UNPKG

sound

Version:

Make sure your data is sound! Schema generator, converter and validation library for Node.js.

467 lines (422 loc) 17.4 kB
import _ from 'lodash' import test from 'tape' import sound from '../sound.js' const schemaForStrings = { username1 : sound().isString().isRequired().setName('Username1'), username2 : sound().isString().isRequired().setName('Username2').isMinLen(3), username3 : sound().isString().isRequired().setName('Username3').isMinLen(3), username4 : sound().isString().isRequired().setName('Username4').isMaxLen(8), username5 : sound().isString().isRequired().setName('Username5').isMaxLen(8), username6 : sound().isString().isRequired().setName('Username6').isMinLen(3).isMaxLen(8), username7 : sound().isString().isRequired().setName('Username7').isMinLen(3).isMaxLen(8), username8 : sound().isString().isRequired().setName('Username8').isMaxLen(8).isMinLen(3), username9 : sound().isString().isRequired().setName('Username9').isMaxLen(8).isMinLen(3), usernameA : sound().isString().isRequired().isNotEmpty().setName('UsernameA'), } const schemaForIntegers = { int1 : sound().isInteger().isRequired().setName('Int1'), int2 : sound().isInteger().isRequired().setName('Int2').isMinVal(3), int3 : sound().isInteger().isRequired().setName('Int3').isMinVal(3), int4 : sound().isInteger().isRequired().setName('Int4').isMaxVal(8), int5 : sound().isInteger().isRequired().setName('Int5').isMaxVal(8), int6 : sound().isInteger().isRequired().setName('Int6').isMinVal(3).isMaxVal(8), int7 : sound().isInteger().isRequired().setName('Int7').isMinVal(3).isMaxVal(8), int8 : sound().isInteger().isRequired().setName('Int8').isMaxVal(8).isMinVal(3), int9 : sound().isInteger().isRequired().setName('Int9').isMaxVal(8).isMinVal(3), int10 : sound().isInteger().isRequired().setName('Int10').isGreaterThan(3), int11 : sound().isInteger().isRequired().setName('Int11').isGreaterThan(3), int12 : sound().isInteger().isRequired().setName('Int12').isLessThan(8), int13 : sound().isInteger().isRequired().setName('Int13').isLessThan(8), } const schemaForUrls = { url1 : sound().isString().isRequired().isUrl(), url2 : sound().isString().isRequired().isUrl(), url3 : sound().isString().isRequired().isUrl(), url4 : sound().isString().isRequired().isUrl(), url5 : sound().isString().isRequired().isUrl(), url6 : sound().isString().isRequired().isUrl(), url7 : sound().isString().isRequired().isUrl(), } const schemaForDomains = { domain1 : sound().isString().isRequired().isDomain(), domain2 : sound().isString().isRequired().isDomain(), domain3 : sound().isString().isRequired().isDomain(), domain4 : sound().isString().isRequired().isDomain(), domain5 : sound().isString().isRequired().isDomain(), domain6 : sound().isString().isRequired().isDomain(), domain7 : sound().isString().isRequired().isDomain(), domain8 : sound().isString().isRequired().isDomain(), domain9 : sound().isString().isRequired().isDomain(), domain10 : sound().isString().isRequired().isDomain(), domain11 : sound().isString().isRequired().isDomain(), domain12 : sound().isString().isRequired().isDomain(), domain13 : sound().isString().isRequired().isDomain(), domain14 : sound().isString().isRequired().isDomain(), domain15 : sound().isString().isRequired().isDomain(), domain16 : sound().isString().isRequired().isDomain(), domain17 : sound().isString().isRequired().isDomain(), domain18 : sound().isString().isRequired().isDomain(), domain19 : sound().isString().isRequired().isDomain(), domain20 : sound().isString().isRequired().isDomain(), domain21 : sound().isString().isRequired().isDomain(), domain22 : sound().isString().isRequired().isDomain(), domain23 : sound().isString().isRequired().isDomain(), domain24 : sound().isString().isRequired().isDomain(), } const schemaForEmailAddresses = { email1 : sound().isString().isRequired().isEmailAddress(), email2 : sound().isString().isRequired().isEmailAddress(), email3 : sound().isString().isRequired().isEmailAddress(), email4 : sound().isString().isRequired().isEmailAddress(), email5 : sound().isString().isRequired().isEmailAddress(), email6 : sound().isString().isRequired().isEmailAddress(), email7 : sound().isString().isRequired().isEmailAddress(), email8 : sound().isString().isRequired().isEmailAddress(), } const schemaForTokens = { tok1 : sound().isString().isRequired().isToken(), tok2 : sound().isString().isRequired().isToken(), tok3 : sound().isString().isRequired().isToken(), tok4 : sound().isString().isRequired().isToken(), tok5 : sound().isString().isRequired().isToken(), tok6 : sound().isString().isRequired().isToken(), tok7 : sound().isString().isRequired().isToken(), } const schemaForUrlShortener = { title : sound().isString().isRequired(), url : sound().isString().isRequired().isUrl(), } const schemaForMatches = { username : sound().isString().isRequired(), favColour1 : sound().isString().isMatch(/^(red|green|blue)$/), favColour2 : sound().isString().isMatch(/^(red|green|blue)$/), } const schemaForEnums = { username : sound().isString().isRequired(), favColour1 : sound().isString().isEnum([ 'red', 'green', 'blue' ]), favColour2 : sound().isString().isEnum([ 'red', 'green', 'blue' ]), favColour3 : sound().isString().isEnum([ 'red', 'green', 'blue' ]), favColour4 : sound().isString().isEnum([ 'red', 'green', 'blue' ]), favColour5 : sound().isString().isEnum([ 'red', 'green', 'blue' ]), favColour6 : sound().isString().toLowerCase().toTrim().isRequired().isEnum([ 'red', 'green', 'blue' ]), favColour7 : sound().isString().isRequired().isEnum([ 'red', 'green', 'blue' ]), } const tests = [ { name : 'Validate simple types (isRequired)', schema : { username : sound().isString().setName('Username').isRequired(), password : sound().isString().setName('Password').isRequired(), logins : sound().isInteger().setName('Logins').isRequired(), pi : sound().isFloat().setName('PI').isRequired(), isAdmin : sound().isBoolean().setName('Is Admin').isRequired(), isHuman : sound().isBoolean().setName('Is Human').isRequired(), date : sound().isDate().setName('Date').isRequired(), agree : sound().isEqual(true).setName('Agree'), hasHair : sound().isEqual(false).setName('Have Hair?'), age : sound().isEqual(21).setName('Is 21?'), yes : sound().isEqual('yes'), }, params : { username : 'andy', password : 's3kr1t', logins : 2, pi : 3.14159, isAdmin : false, isHuman : true, date : new Date(), agree : true, hasHair : false, age : 21, yes : 'yes', }, test : function(t, err) { t.ok(_.isPlainObject(err), "is an object") t.end() }, }, { name : 'Min/Max Lengths of strings', schema : schemaForStrings, params : { username1 : 'ok', username2 : 'ok-here', username3 : 'mm', username4 : 'ok-here', username5 : 'too-long-here', username6 : 'ok-here', username7 : 'mm', username8 : 'ok-here', username9 : 'too-long-here', usernameA : '', }, test : function(t, err) { t.ok(_.isPlainObject(err), "is an object") t.ok( _.isUndefined(err.username1), "username1 string passes") t.ok( _.isUndefined(err.username2), "username2 string passes") t.ok(!_.isUndefined(err.username3), "username3 string fails") t.ok( _.isUndefined(err.username4), "username4 string passes") t.ok(!_.isUndefined(err.username5), "username5 string fails") t.ok( _.isUndefined(err.username6), "username6 string passes") t.ok(!_.isUndefined(err.username7), "username7 string fails") t.ok( _.isUndefined(err.username8), "username8 string passes") t.ok(!_.isUndefined(err.username9), "username9 string fails") t.ok(!_.isUndefined(err.usernameA), "usernameA string fails") t.equal(err.username3, "Username3 should be at least 3 characters") t.equal(err.username5, "Username5 should be at most 8 characters") t.equal(err.usernameA, "UsernameA is required") // for these, the first error should be these t.equal(err.username7, "Username7 should be at least 3 characters") t.equal(err.username9, "Username9 should be at most 8 characters") t.end() }, }, { name : 'Min/Max for integers', schema : schemaForIntegers, params : { int1 : 5, int2 : 5, int3 : 2, int4 : 5, int5 : 9, int6 : 5, int7 : 2, int8 : 5, int9 : 9, int10 : 4, int11 : 3, int12 : 7, int13 : 8, }, test : function(t, err) { t.ok(_.isPlainObject(err), "is an object") t.ok( _.isUndefined(err.int1), "integer passes") t.ok( _.isUndefined(err.int2), "integer passes") t.ok(!_.isUndefined(err.int3), "integer passes") t.ok( _.isUndefined(err.int4), "integer passes") t.ok(!_.isUndefined(err.int5), "integer passes") t.ok( _.isUndefined(err.int6), "integer passes") t.ok(!_.isUndefined(err.int7), "integer passes") t.ok( _.isUndefined(err.int8), "integer passes") t.ok(!_.isUndefined(err.int9), "integer passes") t.ok( _.isUndefined(err.int10), "integer passes") t.ok(!_.isUndefined(err.int11), "integer passes") t.ok( _.isUndefined(err.int12), "integer passes") t.ok(!_.isUndefined(err.int13), "integer passes") t.equal(err.int3, "Int3 should be at least 3") t.equal(err.int5, "Int5 should be at most 8") // for these, the first error should be these t.equal(err.int7, "Int7 should be at least 3") t.equal(err.int9, "Int9 should be at most 8") // for these, the first error should be these t.equal(err.int11, "Int11 should be greater than 3") t.equal(err.int13, "Int13 should be less than 8") t.end() }, }, { name : 'URLs', schema : schemaForUrls, params : { url1 : 'http://chilts.org/', url2 : 'http://chilts.org', url3 : 'http://chilts.org/blog/', url4 : 'https://google.com/', url5 : 'ftp://example.net/', url6 : 'http://localhost/', url7 : 'http://localhost.localdomain:8000/', }, test : function(t, err) { t.ok(_.isPlainObject(err), "is an object") t.ok( _.isUndefined(err.url1), "url1 passes") t.ok( _.isUndefined(err.url2), "url2 passes") t.ok( _.isUndefined(err.url3), "url3 passes") t.ok( _.isUndefined(err.url4), "url4 passes") t.ok(!_.isUndefined(err.url5), "url5 fails") t.ok(!_.isUndefined(err.url6), "url6 fails") // 'coz we want domain names t.ok( _.isUndefined(err.url7), "url7 passes") t.equal(err.url5, "url5 should be a URL and start with http:// or https://") t.equal(err.url6, "url6 should be a URL and start with http:// or https://") t.end() }, }, { name : 'Domains', schema : schemaForDomains, params : { domain1 : 'example.org', domain2 : 'my.example.org', domain3 : '1.cc', // doesn't make sure `cc` is a valid tld domain4 : 'hello-world.info', domain5 : 'my.app.development.example.com', domain6 : 'localhost.localdomain', domain7 : 'localhost', domain8 : 'hello_world.info', domain9 : '-.net', domain10 : '', domain11 : ' ', domain12 : '*', domain13 : '*.example.com', domain14 : '!.com', domain15 : '.com', domain16 : 'example.', domain17 : 'example.com.', domain18 : 'http://example.com', domain19 : 'me@example.com', domain20 : '-another.com', domain21 : 'another-.com', domain22 : 'another.c-m', domain23 : 'another.c', domain24 : 'status-2345.example.com', }, test : function(t, err) { t.ok(_.isPlainObject(err), "is an object") t.ok( _.isUndefined(err.domain1), "domain1 passes") t.ok( _.isUndefined(err.domain2), "domain2 passes") t.ok( _.isUndefined(err.domain3), "domain3 passes") t.ok( _.isUndefined(err.domain4), "domain4 passes") t.ok( _.isUndefined(err.domain5), "domain5 passes") t.ok( _.isUndefined(err.domain6), "domain6 passes") // 'coz we want domain names t.ok(!_.isUndefined(err.domain7), "domain7 fails") t.ok(!_.isUndefined(err.domain8), "domain8 fails") t.ok(!_.isUndefined(err.domain9), "domain9 fails") t.ok(!_.isUndefined(err.domain10), "domain10 fails") t.ok(!_.isUndefined(err.domain11), "domain11 fails") t.ok(!_.isUndefined(err.domain12), "domain12 fails") t.ok(!_.isUndefined(err.domain13), "domain13 fails") t.ok(!_.isUndefined(err.domain14), "domain14 fails") t.ok(!_.isUndefined(err.domain15), "domain15 fails") t.ok(!_.isUndefined(err.domain16), "domain16 fails") t.ok(!_.isUndefined(err.domain17), "domain17 fails") t.ok(!_.isUndefined(err.domain18), "domain18 fails") t.ok(!_.isUndefined(err.domain19), "domain19 fails") t.ok(!_.isUndefined(err.domain20), "domain20 fails") t.ok(!_.isUndefined(err.domain21), "domain21 fails") t.ok(!_.isUndefined(err.domain22), "domain22 fails") t.ok(!_.isUndefined(err.domain23), "domain23 fails") t.ok( _.isUndefined(err.domain24), "domain24 passes") t.equal(err.domain7, "domain7 should be a FQDN such as example.com or my.example.org") t.end() }, }, { name : 'Email Addresses', schema : schemaForEmailAddresses, params : { email1 : '', email2 : '@', email3 : 'blah', email4 : '1@2.de', email5 : 'andychilton+tagged@gmail.com', email6 : 'mchu4apc@fs2.ee.umist.ac.uk', email7 : 'me@t.co', email8 : 'me@t.123', }, test : function(t, err) { t.ok(_.isPlainObject(err), "is an object") t.ok(!_.isUndefined(err.email1), "email1 fails") t.ok(!_.isUndefined(err.email2), "email2 fails") t.ok(!_.isUndefined(err.email3), "email3 fails") t.ok( _.isUndefined(err.email4), "email4 passes") t.ok( _.isUndefined(err.email5), "email5 passes") t.ok( _.isUndefined(err.email6), "email6 passes") t.ok( _.isUndefined(err.email7), "email7 passes") t.ok(!_.isUndefined(err.email8), "email8 fails") t.equal(err.email1, "email1 is required") t.equal(err.email8, "email8 should be an Email Address") t.end() }, }, { name : 'Tokens', schema : schemaForTokens, params : { tok1 : 'chilts', tok2 : 'yay-pie', tok3 : '-invalid', tok4 : 'invalid-', tok5 : 'contains spaces', tok6 : 'AndyUppercase', tok7 : '*&%@#&', }, test : function(t, err) { t.ok(_.isPlainObject(err), "is an object") t.ok( _.isUndefined(err.tok1), "tok1 passes") t.ok( _.isUndefined(err.tok2), "tok2 passes") t.ok(!_.isUndefined(err.tok3), "tok3 fails") t.ok(!_.isUndefined(err.tok4), "tok4 fails") t.ok(!_.isUndefined(err.tok5), "tok5 fails") t.ok(!_.isUndefined(err.tok6), "tok6 fails") t.ok(!_.isUndefined(err.tok7), "tok7 fails") t.equal(err.tok3, "tok3 should start and end with letters/numbers and contain only lowercase letters, numbers and dashes") t.end() }, }, { name : 'Url Shortener', schema : schemaForUrlShortener, params : { title : 'chilts.org', url : 'http://chilts.org/', }, test : function(t, err) { t.ok(_.isPlainObject(err), "is an object") t.end() }, }, { name : 'Test for .matches()', schema : schemaForMatches, params : { username : 'chilts', favColour1 : 'red', favColour2 : 'purple', }, test : function(t, err) { t.ok(_.isPlainObject(err), "is an object") t.ok( _.isUndefined(err.username), "username is correct") t.ok( _.isUndefined(err.favColour1), "red is ok") t.ok(!_.isUndefined(err.favColour2), "purple is not ok") t.equal(err.favColour2, "favColour2 is not valid") t.end() }, }, { name : 'Test for .isEnum()', schema : schemaForEnums, params : { username : 'chilts', favColour1 : 'blue', favColour2 : 'pink', favColour3 : ' ', favColour4 : 'Red', favColour5 : true, favColour6 : ' RED ', favColour7 : '', }, test : function(t, err) { t.ok(_.isPlainObject(err), "is an object") t.ok( _.isUndefined(err.username), "username is correct") t.ok( _.isUndefined(err.favColour1), "'red' is ok") t.ok(!_.isUndefined(err.favColour2), "'purple' is not ok") t.ok(!_.isUndefined(err.favColour3), "' ' is not ok") t.ok(!_.isUndefined(err.favColour4), "'Red' is not ok") t.ok(!_.isUndefined(err.favColour5), "true is not ok") t.ok( _.isUndefined(err.favColour6), "' RED ' is ok") t.ok(!_.isUndefined(err.favColour7), "favColour7 is required") t.equal(err.favColour2, "favColour2 is not a valid value") t.equal(err.favColour3, "favColour3 is not a valid value") t.equal(err.favColour4, "favColour4 is not a valid value") t.equal(err.favColour5, "favColour5 should be a string") t.equal(err.favColour7, "favColour7 is required") t.end() }, }, ] tests.forEach(function(v) { test(v.name, function(t) { const res = sound.validate(v.params, v.schema) v.test(t, res.err, res.val) }) })