Skip to content
This repository has been archived by the owner on Jul 29, 2019. It is now read-only.

Refactoring and unit testing of Validator module #3106

Merged
merged 11 commits into from
Jul 20, 2017
94 changes: 56 additions & 38 deletions lib/shared/Validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,53 +53,62 @@ class Validator {
static check(option, options, referenceOptions, path) {
if (referenceOptions[option] === undefined && referenceOptions.__any__ === undefined) {
Validator.getSuggestion(option, referenceOptions, path);
return;
}
else if (referenceOptions[option] === undefined && referenceOptions.__any__ !== undefined) {

let referenceOption = option;
let is_object = true;

if (referenceOptions[option] === undefined && referenceOptions.__any__ !== undefined) {
// NOTE: This only triggers if the __any__ is in the top level of the options object.
// THAT'S A REALLY BAD PLACE TO ALLOW IT!!!!
// TODO: Examine if needed, remove if possible

// __any__ is a wildcard. Any value is accepted and will be further analysed by reference.
if (Validator.getType(options[option]) === 'object' && referenceOptions['__any__'].__type__ !== undefined) {
// if the any subgroup is not a predefined object int he configurator we do not look deeper into the object.
Validator.checkFields(option, options, referenceOptions, '__any__', referenceOptions['__any__'].__type__, path);
}
else {
Validator.checkFields(option, options, referenceOptions, '__any__', referenceOptions['__any__'], path);
}
referenceOption = '__any__';

// if the any-subgroup is not a predefined object in the configurator,
// we do not look deeper into the object.
is_object = (Validator.getType(options[option]) === 'object');
}
else {
// Since all options in the reference are objects, we can check whether they are supposed to be object to look for the __type__ field.
if (referenceOptions[option].__type__ !== undefined) {
// if this should be an object, we check if the correct type has been supplied to account for shorthand options.
Validator.checkFields(option, options, referenceOptions, option, referenceOptions[option].__type__, path);
}
else {
Validator.checkFields(option, options, referenceOptions, option, referenceOptions[option], path);
}
// Since all options in the reference are objects, we can check whether
// they are supposed to be the object to look for the __type__ field.
// if this is an object, we check if the correct type has been supplied to account for shorthand options.
}

let refOptionObj = referenceOptions[referenceOption];
if (is_object && refOptionObj.__type__ !== undefined) {
refOptionObj = refOptionObj.__type__;
}

Validator.checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path);
}

/**
*
* @param {String} option | the option property
* @param {Object} options | The supplied options object
* @param {Object} referenceOptions | The reference options containing all options and their allowed formats
* @param {String} referenceOption | Usually this is the same as option, except when handling an __any__ tag.
* @param {String} refOptionType | This is the type object from the reference options
* @param {Array} path | where in the object is the option
* @param {String} option | the option property
* @param {Object} options | The supplied options object
* @param {Object} referenceOptions | The reference options containing all options and their allowed formats
* @param {String} referenceOption | Usually this is the same as option, except when handling an __any__ tag.
* @param {String} refOptionType | This is the type object from the reference options
* @param {Array} path | where in the object is the option
*/
static checkFields(option, options, referenceOptions, referenceOption, refOptionObj, path) {
let log = function(message) {
console.log('%c' + message + Validator.printLocation(path, option), printStyle);
};

let optionType = Validator.getType(options[option]);
let refOptionType = refOptionObj[optionType];

if (refOptionType !== undefined) {
// if the type is correct, we check if it is supposed to be one of a few select values
if (Validator.getType(refOptionType) === 'array') {
if (refOptionType.indexOf(options[option]) === -1) {
console.log('%cInvalid option detected in "' + option + '".' +
' Allowed values are:' + Validator.print(refOptionType) + ' not "' + options[option] + '". ' + Validator.printLocation(path, option), printStyle);
errorFound = true;
}
else if (optionType === 'object' && referenceOption !== "__any__") {
path = util.copyAndExtendArray(path, option);
Validator.parse(options[option], referenceOptions[referenceOption], path);
}
if (Validator.getType(refOptionType) === 'array' && refOptionType.indexOf(options[option]) === -1) {
log('Invalid option detected in "' + option + '".' +
' Allowed values are:' + Validator.print(refOptionType) +
' not "' + options[option] + '". ');
errorFound = true;
}
else if (optionType === 'object' && referenceOption !== "__any__") {
path = util.copyAndExtendArray(path, option);
Expand All @@ -108,7 +117,9 @@ class Validator {
}
else if (refOptionObj['any'] === undefined) {
// type of the field is incorrect and the field cannot be any
console.log('%cInvalid type received for "' + option + '". Expected: ' + Validator.print(Object.keys(refOptionObj)) + '. Received [' + optionType + '] "' + options[option] + '"' + Validator.printLocation(path, option), printStyle);
log('Invalid type received for "' + option +
'". Expected: ' + Validator.print(Object.keys(refOptionObj)) +
'. Received [' + optionType + '] "' + options[option] + '"');
errorFound = true;
}
}
Expand Down Expand Up @@ -166,19 +177,26 @@ class Validator {
let localSearchThreshold = 8;
let globalSearchThreshold = 4;

let msg;
if (localSearch.indexMatch !== undefined) {
console.log('%cUnknown option detected: "' + option + '" in ' + Validator.printLocation(localSearch.path, option,'') + 'Perhaps it was incomplete? Did you mean: "' + localSearch.indexMatch + '"?\n\n', printStyle);
msg = ' in ' + Validator.printLocation(localSearch.path, option,'') +
'Perhaps it was incomplete? Did you mean: "' + localSearch.indexMatch + '"?\n\n';
}
else if (globalSearch.distance <= globalSearchThreshold && localSearch.distance > globalSearch.distance) {
console.log('%cUnknown option detected: "' + option + '" in ' + Validator.printLocation(localSearch.path, option,'') + 'Perhaps it was misplaced? Matching option found at: ' + Validator.printLocation(globalSearch.path, globalSearch.closestMatch,''), printStyle);
msg = ' in ' + Validator.printLocation(localSearch.path, option,'') +
'Perhaps it was misplaced? Matching option found at: ' +
Validator.printLocation(globalSearch.path, globalSearch.closestMatch,'');
}
else if (localSearch.distance <= localSearchThreshold) {
console.log('%cUnknown option detected: "' + option + '". Did you mean "' + localSearch.closestMatch + '"?' + Validator.printLocation(localSearch.path, option), printStyle);
msg = '. Did you mean "' + localSearch.closestMatch + '"?' +
Validator.printLocation(localSearch.path, option);
}
else {
console.log('%cUnknown option detected: "' + option + '". Did you mean one of these: ' + Validator.print(Object.keys(options)) + Validator.printLocation(path, option), printStyle);
msg = '. Did you mean one of these: ' + Validator.print(Object.keys(options)) +
Validator.printLocation(path, option);
}

console.log('%cUnknown option detected: "' + option + '"' + msg, printStyle);
errorFound = true;
}

Expand Down Expand Up @@ -298,4 +316,4 @@ class Validator {


export default Validator;
export {printStyle}
export {printStyle}
Loading