Not requiring fields to be previously set while loading existing data

This commit is contained in:
Jonathan Putney
2020-07-30 16:54:15 -04:00
parent dcad088b25
commit c341d3f70f
6 changed files with 199 additions and 188 deletions

View File

@@ -848,7 +848,6 @@ export default class BaseAPI {
* @param {string} CMIElement
*/
loadFromFlattenedJSON(json, CMIElement) {
console.clear();
if (!this.isNotInitialized()) {
console.error(
'loadFromFlattenedJSON can only be called before the call to lmsInitialize.');
@@ -866,39 +865,23 @@ export default class BaseAPI {
function testPattern(a, c, a_pattern) {
const a_match = a.match(a_pattern);
if (a_match !== null) {
let c_match = c.match(
new RegExp(a_match[1] + Number(a_match[2]) + '.(.*)'));
if (c_match !== null) {
const a_int = Number(a_match[2]);
if (a_match[3] === 'id') {
return -1;
} else if (a_match[3] === 'type' && c_match[1] !== 'id') {
return -1;
} else {
return 1;
}
} else if ((c_match = c.match(a_pattern)) !== null) {
return Number(a_match[2]) - Number(c_match[2]);
} else {
return testPattern(c, a, a_pattern);
}
let c_match;
if (a_match !== null && (c_match = c.match(a_pattern)) !== null) {
return Number(a_match[2]) - Number(c_match[2]);
}
return null;
}
/**
* Function to sort the array, which we'll call until we're done.
*
* @param {string} a
* @param {string} b
* @param {string} c
* @param {string} d
* @return {number}
*/
function resultSort([a, b], [c, d]) {
const int_pattern = /^(cmi\.interactions\.)(\d+)\.(.*)$/;
const obj_pattern = /^(cmi\.objectives\.)(\d+)\.(.*)$/;
const result = Object.keys(json).map(function(key) {
return [String(key), json[key]];
});
// CMI interactions need to have id and type loaded before any other fields
result.sort(function([a, b], [c, d]) {
let test;
if ((test = testPattern(a, c, int_pattern)) !== null) {
return test;
@@ -914,25 +897,10 @@ export default class BaseAPI {
return 1;
}
return 0;
}
const int_pattern = /^(cmi\.interactions\.)(\d+)\.(.*)$/;
const obj_pattern = /^(cmi\.objectives\.)(\d+)\.(.*)$/;
const result = Object.keys(json).map(function(key) {
return [String(key), json[key]];
});
// CMI interactions need to have id and type loaded before any other fields
// Call the sort until everything is properly sorted.
// I must be missing an edge case in my sort?
let sorted_result = [];
while (sorted_result !== result.sort(resultSort)) {
sorted_result = result;
}
let obj;
sorted_result.forEach((element) => {
result.forEach((element) => {
obj = {};
obj[element[0]] = element[1];
this.loadFromJSON(unflatten(obj), CMIElement);

View File

@@ -194,39 +194,42 @@ export default class Scorm2004API extends BaseAPI {
const parts = CMIElement.split('.');
const index = Number(parts[2]);
const interaction = this.cmi.interactions.childArray[index];
if (!interaction.type) {
this.throwSCORMError(scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
const interaction_type = interaction.type;
const interaction_count = interaction.correct_responses._count;
if (interaction_type === 'choice') {
for (let i = 0; i < interaction_count && this.lastErrorCode ===
0; i++) {
const response = interaction.correct_responses.childArray[i];
if (response.pattern === value) {
this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE);
if (this.isInitialized()) {
if (!interaction.type) {
this.throwSCORMError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
const interaction_type = interaction.type;
const interaction_count = interaction.correct_responses._count;
if (interaction_type === 'choice') {
for (let i = 0; i < interaction_count && this.lastErrorCode ===
0; i++) {
const response = interaction.correct_responses.childArray[i];
if (response.pattern === value) {
this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE);
}
}
}
}
const response_type = correct_responses[interaction_type];
if (response_type) {
let nodes = [];
if (response_type?.delimiter) {
nodes = String(value).split(response_type.delimiter);
const response_type = correct_responses[interaction_type];
if (response_type) {
let nodes = [];
if (response_type?.delimiter) {
nodes = String(value).split(response_type.delimiter);
} else {
nodes[0] = value;
}
if (nodes.length > 0 && nodes.length <= response_type.max) {
this.checkCorrectResponseValue(interaction_type, nodes, value);
} else if (nodes.length > response_type.max) {
this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
'Data Model Element Pattern Too Long');
}
} else {
nodes[0] = value;
}
if (nodes.length > 0 && nodes.length <= response_type.max) {
this.checkCorrectResponseValue(interaction_type, nodes, value);
} else if (nodes.length > response_type.max) {
this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
'Data Model Element Pattern Too Long');
'Incorrect Response Type: ' + interaction_type);
}
} else {
this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE,
'Incorrect Response Type: ' + interaction_type);
}
}
if (this.lastErrorCode === 0) {

View File

@@ -819,7 +819,7 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} type
*/
set type(type) {
if (typeof this.id === 'undefined') {
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
@@ -842,8 +842,13 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} timestamp
*/
set timestamp(timestamp) {
if (check2004ValidFormat(timestamp, scorm2004_regex.CMITime)) {
this.#timestamp = timestamp;
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(timestamp, scorm2004_regex.CMITime)) {
this.#timestamp = timestamp;
}
}
}
@@ -860,8 +865,13 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} weighting
*/
set weighting(weighting) {
if (check2004ValidFormat(weighting, scorm2004_regex.CMIDecimal)) {
this.#weighting = weighting;
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(weighting, scorm2004_regex.CMIDecimal)) {
this.#weighting = weighting;
}
}
}
@@ -879,7 +889,8 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} learner_response
*/
set learner_response(learner_response) {
if (typeof this.type === 'undefined' || typeof this.id === 'undefined') {
if (this.initialized && (typeof this.type === 'undefined' ||
typeof this.id === 'undefined')) {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
@@ -962,8 +973,13 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} latency
*/
set latency(latency) {
if (check2004ValidFormat(latency, scorm2004_regex.CMITimespan)) {
this.#latency = latency;
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(latency, scorm2004_regex.CMITimespan)) {
this.#latency = latency;
}
}
}
@@ -980,9 +996,14 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} description
*/
set description(description) {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250,
true)) {
this.#description = description;
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250,
true)) {
this.#description = description;
}
}
}
@@ -1081,8 +1102,13 @@ export class CMIObjectivesObject extends BaseCMI {
* @param {string} success_status
*/
set success_status(success_status) {
if (check2004ValidFormat(success_status, scorm2004_regex.CMISStatus)) {
this.#success_status = success_status;
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(success_status, scorm2004_regex.CMISStatus)) {
this.#success_status = success_status;
}
}
}
@@ -1099,8 +1125,13 @@ export class CMIObjectivesObject extends BaseCMI {
* @param {string} completion_status
*/
set completion_status(completion_status) {
if (check2004ValidFormat(completion_status, scorm2004_regex.CMICStatus)) {
this.#completion_status = completion_status;
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(completion_status, scorm2004_regex.CMICStatus)) {
this.#completion_status = completion_status;
}
}
}
@@ -1117,9 +1148,15 @@ export class CMIObjectivesObject extends BaseCMI {
* @param {string} progress_measure
*/
set progress_measure(progress_measure) {
if (check2004ValidFormat(progress_measure, scorm2004_regex.CMIDecimal) &&
check2004ValidRange(progress_measure, scorm2004_regex.progress_range)) {
this.#progress_measure = progress_measure;
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(progress_measure, scorm2004_regex.CMIDecimal) &&
check2004ValidRange(progress_measure,
scorm2004_regex.progress_range)) {
this.#progress_measure = progress_measure;
}
}
}
@@ -1136,9 +1173,14 @@ export class CMIObjectivesObject extends BaseCMI {
* @param {string} description
*/
set description(description) {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250,
true)) {
this.#description = description;
if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250,
true)) {
this.#description = description;
}
}
}