/** * The goal here is to have a minimum-viable test case here, in order to * check changes in Validator. * * Changes in Validator should ideally be checked to see if they trigger here. * * test-console reference: https://github.com/jamesshore/test-console */ var assert = require('assert'); var stdout = require('test-console').stdout; var Validator = require("../lib/shared/Validator").default; // Copied from lib/network/options.js let string = 'string'; let bool = 'boolean'; let number = 'number'; let array = 'array'; let object = 'object'; // should only be in a __type__ property let dom = 'dom'; let any = 'any'; let allOptions = { // simple options enabled: { boolean: bool }, inherit: { string: ['from', 'to', 'both'] }, size: { number }, filter: { 'function': 'function' }, chosen: { label: { boolean: bool }, edge: { 'function': 'function' }, __type__: { object } }, chosen2: { label: { string }, __type__: { object } }, // Tests with any. These have been tailored to test all paths in: // - Validator.check() // - Validator.checkFields() __any__: { string }, // Any option name allowed here, but it must be a string // NOTE: you can have as many new options as you want! IS THIS INTENTIONAL? groups: { generic: { any }, __any__: { any }, __type__: { object } }, // TODO: add combined options, e.g. //inherit: { string: ['from', 'to', 'both'], boolean: bool }, //filter: { boolean: bool, string, array, 'function': 'function' }, __type__: { object } }; describe('Validator', function() { function run_validator(options, check_correct, definition = undefined) { let errorFound; let output; if (definition === undefined) { definition = allOptions; } output = stdout.inspectSync(function() { errorFound = Validator.validate(options, definition); }); if (check_correct) { assert(!errorFound); assert(output.length === 0, 'No error expected'); } else { //console.log(output); //sometimes useful here assert(errorFound, 'Validation should have failed'); assert(output.length !== 0, 'must return errors'); } return output; } function testExpected(output, expectedErrors) { for (let i = 0; i < expectedErrors.length; ++i) { assert(expectedErrors[i].test(output[i]), 'Regular expression at index ' + i + ' failed'); } assert(output.length === expectedErrors.length, 'Number of expected errors does not match returned errors'); } it('handles regular options correctly', function(done) { // Empty options should be accepted as well run_validator({}, true); // test values for all options var options = { enabled: true, inherit: 'from', size : 123, filter : function() { return true; }, chosen : { label: false, edge :function() { return true; }, }, chosen2: { label: "I am a string" }, myNameDoesntMatter: "My type does", groups : { generic: "any type is good here", dontCareAboutName: [0,1,2,3] // Type can also be anything } }; run_validator(options, true); done(); }); it('rejects incorrect options', function(done) { // All of the options are wrong, all should generate an error var options = { iDontExist: 42, // name is 'any' but type must be string enabled : 'boolean', inherit : 'abc', size : 'not a number', filter : 42, chosen : 'not an object', chosen2 : { label : 123, // Following test the working of Validator.getSuggestion() iDontExist: 'asdf', generic : "I'm not defined here", labe : 42, // Incomplete name labell : 123, }, }; var output = run_validator(options, false); // Sometimes useful: console.log(output); // Errors are in the order as the options are defined in the object let expectedErrors = [ /Invalid type received for "iDontExist"\. Expected: string\. Received \[number\]/, /Invalid type received for "enabled"\. Expected: boolean\. Received \[string\]/, /Invalid option detected in "inherit"\. Allowed values are:from, to, both not/, /Invalid type received for "size"\. Expected: number\. Received \[string\]/, /Invalid type received for "filter"\. Expected: function\. Received \[number\]/, /Invalid type received for "chosen"\. Expected: object\. Received \[string\]/, /Invalid type received for "label". Expected: string. Received \[number\]/, // Expected results of Validator.getSuggestion() /Unknown option detected: "iDontExist"\. Did you mean one of these:/, /Unknown option detected: "generic"[\s\S]*Perhaps it was misplaced\? Matching option found at:/gm, /Unknown option detected: "labe"[\s\S]*Perhaps it was incomplete\? Did you mean:/gm, /Unknown option detected: "labell"\. Did you mean "label"\?/ ]; testExpected(output, expectedErrors); done(); }); /** * Explicit tests on explicit 'undefined', to be really sure it works as expected. */ it('properly handles explicit `undefined`', function(done) { // Option definitions with 'undefined' let undefinedOptions = { width : { number, 'undefined': 'undefined' }, undefOnly : { 'undefined': 'undefined' }, colorOptions : { fill : { string }, stroke : { string, 'undefined': 'undefined' }, strokeWidth: { number }, __type__ : { string, object, 'undefined': 'undefined' } }, moreOptions : { hello : { string }, world : { string, 'undefined': 'undefined' }, __type__ : { object } } } // // Test good actual option values // let correct1 = { width : 42, colorOptions: 'I am a string', moreOptions : { hello: 'world', world: '!' } } var output = run_validator(correct1, true, undefinedOptions); let correct2 = { width : undefined, colorOptions: { fill : 'I am a string', stroke: 'I am a string' }, moreOptions : { world: undefined } } var output = run_validator(correct2, true, undefinedOptions); let correct3 = { width : undefined, undefOnly : undefined, colorOptions: undefined } var output = run_validator(correct3, true, undefinedOptions); // // Test bad actual option values // let bad1 = { width : 'string', undefOnly : 42, colorOptions: 42, moreOptions : undefined } var output = run_validator(bad1, false, undefinedOptions); let expectedErrors = [ /Invalid type received for "width"\. Expected: number, undefined\. Received \[string\]/, /Invalid type received for "undefOnly"\. Expected: undefined\. Received \[number\]/, /Invalid type received for "colorOptions"\. Expected: string, object, undefined\. Received \[number\]/, /Invalid type received for "moreOptions"\. Expected: object\. Received \[undefined\]/ ]; testExpected(output, expectedErrors); let bad2 = { undefOnly : 'undefined', colorOptions: { fill: undefined } , moreOptions: { hello: undefined, world: 42 } } var output = run_validator(bad2, false, undefinedOptions); let expectedErrors2= [ /Invalid type received for "undefOnly"\. Expected: undefined\. Received \[string\]/, /Invalid type received for "fill"\. Expected: string\. Received \[undefined\]/, /Invalid type received for "hello"\. Expected: string\. Received \[undefined\]/, /Invalid type received for "world"\. Expected: string, undefined\. Received \[number\]/ ]; testExpected(output, expectedErrors2); done(); }); });