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
+89 -91
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+3 -3
View File
File diff suppressed because one or more lines are too long
+13 -45
View File
@@ -848,7 +848,6 @@ export default class BaseAPI {
* @param {string} CMIElement * @param {string} CMIElement
*/ */
loadFromFlattenedJSON(json, CMIElement) { loadFromFlattenedJSON(json, CMIElement) {
console.clear();
if (!this.isNotInitialized()) { if (!this.isNotInitialized()) {
console.error( console.error(
'loadFromFlattenedJSON can only be called before the call to lmsInitialize.'); 'loadFromFlattenedJSON can only be called before the call to lmsInitialize.');
@@ -866,39 +865,23 @@ export default class BaseAPI {
function testPattern(a, c, a_pattern) { function testPattern(a, c, a_pattern) {
const a_match = a.match(a_pattern); const a_match = a.match(a_pattern);
if (a_match !== null) { let c_match;
let c_match = c.match( if (a_match !== null && (c_match = c.match(a_pattern)) !== null) {
new RegExp(a_match[1] + Number(a_match[2]) + '.(.*)')); return Number(a_match[2]) - Number(c_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);
}
} }
return null; return null;
} }
/** const int_pattern = /^(cmi\.interactions\.)(\d+)\.(.*)$/;
* Function to sort the array, which we'll call until we're done. const obj_pattern = /^(cmi\.objectives\.)(\d+)\.(.*)$/;
*
* @param {string} a const result = Object.keys(json).map(function(key) {
* @param {string} b return [String(key), json[key]];
* @param {string} c });
* @param {string} d
* @return {number} // CMI interactions need to have id and type loaded before any other fields
*/ result.sort(function([a, b], [c, d]) {
function resultSort([a, b], [c, d]) {
let test; let test;
if ((test = testPattern(a, c, int_pattern)) !== null) { if ((test = testPattern(a, c, int_pattern)) !== null) {
return test; return test;
@@ -914,25 +897,10 @@ export default class BaseAPI {
return 1; return 1;
} }
return 0; 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; let obj;
sorted_result.forEach((element) => { result.forEach((element) => {
obj = {}; obj = {};
obj[element[0]] = element[1]; obj[element[0]] = element[1];
this.loadFromJSON(unflatten(obj), CMIElement); this.loadFromJSON(unflatten(obj), CMIElement);
+30 -27
View File
@@ -194,39 +194,42 @@ export default class Scorm2004API extends BaseAPI {
const parts = CMIElement.split('.'); const parts = CMIElement.split('.');
const index = Number(parts[2]); const index = Number(parts[2]);
const interaction = this.cmi.interactions.childArray[index]; const interaction = this.cmi.interactions.childArray[index];
if (!interaction.type) { if (this.isInitialized()) {
this.throwSCORMError(scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED); if (!interaction.type) {
} else { this.throwSCORMError(
const interaction_type = interaction.type; scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
const interaction_count = interaction.correct_responses._count; } else {
if (interaction_type === 'choice') { const interaction_type = interaction.type;
for (let i = 0; i < interaction_count && this.lastErrorCode === const interaction_count = interaction.correct_responses._count;
0; i++) { if (interaction_type === 'choice') {
const response = interaction.correct_responses.childArray[i]; for (let i = 0; i < interaction_count && this.lastErrorCode ===
if (response.pattern === value) { 0; i++) {
this.throwSCORMError(scorm2004_error_codes.GENERAL_SET_FAILURE); 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]; const response_type = correct_responses[interaction_type];
if (response_type) { if (response_type) {
let nodes = []; let nodes = [];
if (response_type?.delimiter) { if (response_type?.delimiter) {
nodes = String(value).split(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 { } 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, 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) { if (this.lastErrorCode === 0) {
+63 -21
View File
@@ -819,7 +819,7 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} type * @param {string} type
*/ */
set type(type) { set type(type) {
if (typeof this.id === 'undefined') { if (this.initialized && typeof this.id === 'undefined') {
throw new ValidationError( throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED); scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else { } else {
@@ -842,8 +842,13 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} timestamp * @param {string} timestamp
*/ */
set timestamp(timestamp) { set timestamp(timestamp) {
if (check2004ValidFormat(timestamp, scorm2004_regex.CMITime)) { if (this.initialized && typeof this.id === 'undefined') {
this.#timestamp = timestamp; 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 * @param {string} weighting
*/ */
set weighting(weighting) { set weighting(weighting) {
if (check2004ValidFormat(weighting, scorm2004_regex.CMIDecimal)) { if (this.initialized && typeof this.id === 'undefined') {
this.#weighting = weighting; 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 * @param {string} learner_response
*/ */
set learner_response(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( throw new ValidationError(
scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED); scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else { } else {
@@ -962,8 +973,13 @@ export class CMIInteractionsObject extends BaseCMI {
* @param {string} latency * @param {string} latency
*/ */
set latency(latency) { set latency(latency) {
if (check2004ValidFormat(latency, scorm2004_regex.CMITimespan)) { if (this.initialized && typeof this.id === 'undefined') {
this.#latency = latency; 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 * @param {string} description
*/ */
set description(description) { set description(description) {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250, if (this.initialized && typeof this.id === 'undefined') {
true)) { throw new ValidationError(
this.#description = description; 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 * @param {string} success_status
*/ */
set success_status(success_status) { set success_status(success_status) {
if (check2004ValidFormat(success_status, scorm2004_regex.CMISStatus)) { if (this.initialized && typeof this.id === 'undefined') {
this.#success_status = success_status; 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 * @param {string} completion_status
*/ */
set completion_status(completion_status) { set completion_status(completion_status) {
if (check2004ValidFormat(completion_status, scorm2004_regex.CMICStatus)) { if (this.initialized && typeof this.id === 'undefined') {
this.#completion_status = completion_status; 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 * @param {string} progress_measure
*/ */
set progress_measure(progress_measure) { set progress_measure(progress_measure) {
if (check2004ValidFormat(progress_measure, scorm2004_regex.CMIDecimal) && if (this.initialized && typeof this.id === 'undefined') {
check2004ValidRange(progress_measure, scorm2004_regex.progress_range)) { throw new ValidationError(
this.#progress_measure = progress_measure; 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 * @param {string} description
*/ */
set description(description) { set description(description) {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250, if (this.initialized && typeof this.id === 'undefined') {
true)) { throw new ValidationError(
this.#description = description; scorm2004_error_codes.DEPENDENCY_NOT_ESTABLISHED);
} else {
if (check2004ValidFormat(description, scorm2004_regex.CMILangString250,
true)) {
this.#description = description;
}
} }
} }