isvalid
Version:
Async JSON validation library for node.js.
848 lines (843 loc) • 30.6 kB
JavaScript
//
// validate.js
//
// Created by Kristian Trenskow on 2014-06-06
//
// See license in LICENSE
//
import { expect, assert } from 'chai';
import ValidationError from '../lib/errors/validation.js';
import AggregatedError from '../lib/errors/aggregated.js';
import isvalid from '../index.js';
import { typeName, instanceTypeName, isSameType } from '../lib/utils.js';
class Test {
constructor() {
this.test = 'test';
}
}
const commonTests = {
type: function(type, validData, invalidData) {
describe('type', function() {
it(`should come back with an error if input is not a(n) ${typeName(type)}.`, () => {
return expect(isvalid(invalidData, type))
.to.eventually.be.rejectedWith(`Is not of type ${typeName(type)}.`)
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'type');
});
it(`should come back with no error if input is a(n) ${typeName(type)}.`, () => {
return expect(isvalid(validData, {
type: type
})).to.eventually.satisfy((data) => {
return isSameType(instanceTypeName(data), typeName(type)) || (typeof type !== 'string' && data instanceof type);
});
});
describe('#errors', function() {
it(`should come back with an error of custom message if input is not a(n) ${typeName(type)}.`, () => {
return expect(isvalid(invalidData, {
type: type,
errors: {
type: 'Type custom error message.'
}}))
.to.eventually.be.rejectedWith('Type custom error message.')
.and.to.be.instanceOf(ValidationError)
.and.has.property('validator', 'type');
});
});
});
},
required: function(type, validData) {
describe('required', function() {
it('should come back with an error if required and input is undefined.', () => {
return expect(isvalid(undefined, {
type: type,
required: true}))
.to.eventually.be.rejectedWith('Data is required.')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'required');
});
it('should come back with no error if required and input is present', () => {
return expect(isvalid(validData, {
type: type,
required: true
})).to.eventually.satisfy((data) => {
return isSameType(instanceTypeName(data), typeName(type)) || (typeof type !== 'string' && data instanceof type);
});
});
it('should prioritize concrete over defaults.', () => {
return expect(isvalid(undefined, {
type: type,
required: false
}, { defaults: { required: true }})).to.eventually.equal(undefined);
});
describe('#errors', function() {
it('should come back with an error with custom message if required and input is undefined.', () => {
return expect(isvalid(undefined, {
type: type,
required: true,
errors: {
required: 'Required custom error message.'
}}))
.to.eventually.be.rejectedWith('Required custom error message.')
.and.to.be.instanceOf(ValidationError)
.and.has.property('validator', 'required');
});
});
});
},
null: function(type) {
describe('null', function() {
it('should come back with an error if required and does not allow null and input is null.', () => {
return expect(isvalid(null, {
type: type,
null: 'deny',
required: true}))
.to.eventually.be.rejectedWith('Cannot be null.')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'null');
});
it('should come back with no error if required and null is allowed and input is null.', () => {
return expect(isvalid(null, {
type: type,
required: true,
null: 'allow'
})).to.eventually.be.null;
});
it('should come back with no error if required and null is allowed and input is null.', () => {
return expect(isvalid(null, {
type: type,
required: true,
null: 'allow'
})).to.eventually.be.null;
});
it('should come back with no error and undefined if null is set to undefine input and input is null.', () => {
return expect(isvalid(null, {
type: type,
null: 'undefine'
})).to.eventually.be.undefined;
});
});
},
default: function(type, validData) {
describe('default', function() {
it('should call default if default is function and returns a promise (async function).', () => {
return expect(isvalid(undefined, { type: type, default: async () => {
return validData;
}})).to.eventually.satisfy((data) => {
return isSameType(instanceTypeName(data), typeName(type)) || (typeof type !== 'string' && data instanceof type);
});
});
it('should call default if default is a function.', () => {
return expect(isvalid(undefined, { type: type, default: () => {
return validData;
}})).to.eventually.satisfy((data) => {
return isSameType(instanceTypeName(data), typeName(type)) || (typeof type !== 'string' && data instanceof type);
});
});
it('should call default if default is a value.', () => {
return expect(isvalid(undefined, { type: type, default: validData })).to.eventually.satisfy((data) => {
return isSameType(instanceTypeName(data), typeName(type)) || (typeof type !== 'string' && data instanceof type);
});
});
it('should call default with options if options are provided.', () => {
return expect(isvalid(undefined, { type: type, default: (options) => {
return options.value;
}}, { value: validData })).to.eventually.equal(validData);
});
it('should allow `null` as a valid value.', () => {
return expect(isvalid(undefined, { type: type, default: null})).to.eventually.equal(null);
});
});
},
equal: function(type, validData, invalidData) {
describe('equal', function() {
it('should come back with data if data is equal.', () => {
return expect(isvalid(validData, {
equal: validData
})).to.eventually.equal(validData);
});
it('should come back with error if data does not equal.', () => {
return expect(isvalid(invalidData, {
equal: validData}))
.to.eventually.be.rejectedWith(`Data does not equal ${validData}.`)
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'equal');
});
});
},
post: function() {
describe('post', function() {
it('should call function if post is specified.', () => {
return expect(isvalid('test', {
post: function(data) {
expect(data).to.be.a('String').equals('test');
return 'test2';
}
})).to.eventually.be.a('String').equals('test2');
});
it('should call function if synchronous post is specified.', () => {
return expect(isvalid(undefined, {
post: function() {
return 'test';
}
})).to.eventually.be.a('String').equal('test');
});
it('should convert errors thrown in synchronous post function.', () => {
return expect(isvalid('test', {
post: function() {
throw new Error('an error');
}}))
.to.eventually.be.rejectedWith('an error')
.and.to.be.instanceOf(ValidationError)
.and.has.property('message', 'an error');
});
it('should return original object if synchronous function doesn\'t return.', () => {
return expect(isvalid('test', {
post: function() {}
})).to.eventually.be.a('String').equal('test');
});
it('should accept async functions', () => {
return expect(isvalid('test', {
post: async function() {}
})).to.eventually.be.a('String').equal('test');
});
it('should reformat err if post is specified and returns an error.', () => {
return expect(isvalid({}, {
post: async function() {
throw new Error('an error');
}}))
.to.eventually.be.rejectedWith('an error')
.and.to.be.instanceOf(ValidationError)
.and.has.property('validator', 'post');
});
it('should pass on post schema options if specified.', () => {
return expect(isvalid({}, {
post: function(obj, schema, { options }) {
expect(options).to.have.property('test').to.be.equal(true);
}
}, {
test: true
})).to.not.be.rejected;
});
it('should first validate using pre and then validations,', () => {
let s = isvalid({
'low': 0
}, {
type: Object,
schema: {
low: { type: Number },
high: { type: Number, default: 10 }
},
pre: function(obj) {
expect(obj.high).to.be.undefined;
}
});
return Promise.all([
expect(s).to.eventually.have.property('low').equal(0),
expect(s).to.eventually.have.property('high').equal(10)
]);
});
it('should first validate using validators and then post.', () => {
let s = isvalid({
'low': 0
}, {
type: Object,
schema: {
'low': { type: Number },
'high': { type: Number, default: 10 },
},
post: function(obj) {
expect(obj.high).to.equal(10);
}
});
return Promise.all([
expect(s).to.eventually.have.property('low').equal(0),
expect(s).to.eventually.have.property('high').equal(10)
]);
});
it('should call all post validators in array.', () => {
return expect(isvalid(0, {
post: [
function(data) {
return data + 1;
},
function(data) {
return Promise.resolve(data + 2);
},
function(data) {
return data + 3;
},
function(data) {
return Promise.resolve(data + 4);
}
]
})).to.eventually.equal(10);
});
it('should come back with error if thrown underway.', () => {
return expect(isvalid(0, {
post: [
function(data) {
return data + 1;
},
function() {
throw new Error('Stop here');
},
function(data) {
assert(false, 'This post function should not have been called.');
return data + 3;
}
]}))
.to.eventually.be.rejectedWith('Stop here')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'post');
});
it('should have the full validated data so far as a parameter', () => {
return expect(isvalid({ why: {} }, {
'awesome': { type: Boolean, priority: 1, default: true },
'why': {
'reason': { type: 'string', default: 'It just is!' },
'who': { type: 'string', post: (_, schema, { data }) => {
expect(data.awesome).to.be.true;
return 'isvalid';
} }
}
})).to.eventually.have.property('why').to.have.property('who').to.equal('isvalid');
});
it ('should accept `null` as a valid return value.', () => {
return expect(isvalid('', { type: 'string', post: () => null})).to.eventually.equal(null);
});
});
},
all: function(type, validData, invalidData) { let self = this;
['type', 'required', 'null', 'default', 'equal', 'post'].forEach(function(test) {
self[test](type, validData, invalidData);
});
}
};
describe('validate', function() {
it('should throw an error if schema is not provided.', () => {
return expect(isvalid({})).to.eventually.be.rejectedWith(Error);
});
it('should allow for custom key path in options', () => {
return expect(isvalid({}, { type: 'string' }, { keyPath: 'custom.keyPath' }))
.to.eventually.be.rejectedWith(Error)
.to.have.property('keyPath')
.to.have.property(0)
.to.equal('custom');
});
describe('type conversion', function() {
it('should convert string values into numbers if string contains a number.', () => {
return expect(isvalid('123.987', Number)).to.eventually.equal(123.987);
});
it('should convert string values into numbers if string contains a negative number.', () => {
return expect(isvalid('-123.987', Number)).to.eventually.equal(-123.987);
});
it('should convert string values into numbers if string contains a negative E notation.', () => {
return expect(isvalid('5.8e-7', Number)).to.eventually.equal(5.8e-7);
});
it('should convert string values into numbers if string contains a positive E notation.', () => {
return expect(isvalid('5.8e+7', Number)).to.eventually.equal(5.8e+7);
});
it('should come back with error if string is supplied - but not a number.', () => {
return expect(isvalid('abc', Number))
.to.eventually.be.rejectedWith('Is not of type number.')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'type');
});
it('should come back with error if wrong E notation is supplied - but not a number.', () => {
return expect(isvalid('12e', Number))
.to.eventually.be.rejectedWith('Is not of type number.')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'type');
});
it('should come back with no error and validData set to true if input is string with \'True\'.', () => {
return expect(isvalid('True', Boolean)).to.eventually.equal(true);
});
it('should come back with no error and validData set to false if input is string with \'False\'.', () => {
return expect(isvalid('False', Boolean)).to.eventually.equal(false);
});
it('should come back with error and if string is supplied - but not \'true\' or \'false\'.', () => {
return expect(isvalid('123', Boolean))
.to.eventually.be.rejectedWith('Is not of type boolean.')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'type');
});
it('should come back with no error and validData set to a Date if input is string with an ISO date.', () => {
return expect(
isvalid('2014-10-19T02:24:42.395Z', Date)
.then((date) => {
return date.getTime();
})
).to.eventually.equal(new Date('2014-10-19T02:24:42.395Z').getTime());
});
it('should come back with error and if string is supplied - but not ISO date.', () => {
return expect(isvalid('19/10/14 2:24:42', Date))
.to.eventually.be.rejectedWith('Is not of type date.')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'type');
});
});
describe('object validator', function() {
commonTests.all(Object, {}, 123);
it('should come back with same input if sub-schema is not provided.', () => {
return expect(isvalid({}, {})).to.eventually.eql({});
});
it('should come out with same input as output if keys can validate.', () => {
let s = isvalid({
awesome: true,
why: 'it just is!'
}, {
awesome: Boolean,
why: 'string'
});
return Promise.all([
expect(s).to.eventually.have.property('awesome').equals(true),
expect(s).to.eventually.have.property('why').equals('it just is!')
]);
});
it('should come back with no error and validData if object shortcut is empty.', () => {
return expect(isvalid({}, {})).to.eventually.be.an('Object');
});
describe('priority', function() {
it('should validate higher priority before validating others', () => {
let validated = false;
return expect(isvalid({}, {
awesome: { type: Boolean, post: () => {
expect(validated).to.be.true;
return true;
}, },
why: { type: 'string', priority: 1, default: 'it just is!', post: () => {
validated = true;
} }
})).to.eventually.have.property('why').equals('it just is!');
});
});
describe('unknownKeys', function() {
it('should come back with unknown keys intact if unknownKeys is \'allow\'.', () => {
return expect(isvalid({
awesome: true,
why: 'it just is!'
}, {
type: Object,
unknownKeys: 'allow',
schema: {
awesome: Boolean
}
})).to.eventually.have.property('why').equals('it just is!');
});
it('should come back with unknown keys intact if unknownKeys is provided as \'allow\' in options defaults.', () => {
return expect(isvalid({
awesome: true,
why: 'it just is!'
}, {
awesome: Boolean
}, {
defaults: {
unknownKeys: 'allow'
}
})).to.eventually.have.property('why').equals('it just is!');
});
it('should come back with error if there are unknown keys and unknownKeys is not set.', () => {
return expect(isvalid({
awesome: true,
why: 'it just is!'
}, {
awesome: Boolean}))
.to.eventually.be.rejectedWith('Unknown key.')
.and.to.be.instanceOf(ValidationError)
.and.has.property('validator', 'unknownKeys');
});
it('should come back with error if there are unknown keys and unknownKeys is set to \'deny\'.', () => {
return expect(isvalid({
awesome: true,
why: 'it just is!'
}, {
type: Object,
unknownKeys: 'deny',
schema: {
awesome: Boolean
}}))
.to.eventually.be.rejectedWith('Unknown key.')
.and.to.be.instanceOf(ValidationError)
.and.has.property('validator', 'unknownKeys');
});
it('should come back with keys removed if unknown keys and unknownKeys is set to \'remove\'.', () => {
return expect(isvalid({
awesome: true,
why: 'it just is!'
}, {
type: Object,
unknownKeys: 'remove',
schema: {
awesome: Boolean
}
})).to.eventually.not.have.property('why');
});
describe('required', function() {
it ('should come back with object key path when implicit (aggregated error).', () => {
return expect(isvalid(undefined, {
'myObject': {
'myFirstKey': {
type: String,
required: true
},
'mySecondKey': {
type: String,
required: true
}
}}, { keyPath: ['root'], aggregatedErrors: true }))
.to.eventually.be.rejectedWith('Multiple errors occurred.')
.and.to.be.instanceOf(AggregatedError)
.and.have.property('errors')
.and.have.property(0)
.and.have.property('message', 'Data is required.');
});
});
describe('#errors', function() {
it('should come back with error of post message if there are unknown keys and unknownKeys is set to \'deny\'.', () => {
return expect(isvalid({
awesome: true,
why: 'it just is!'
}, {
type: Object,
unknownKeys: 'deny',
schema: {
awesome: Boolean
},
errors: {
unknownKeys: 'Not allowed.'
}}))
.to.eventually.be.rejectedWith('Not allowed.')
.and.to.be.instanceOf(ValidationError)
.and.have.property('message', 'Not allowed.');
});
});
});
});
describe('array validator', function() {
commonTests.all(Array, [], 123);
it('should come back with same input if no sub-schema is provided.', () => {
return expect(isvalid([], [])).to.eventually.eql([]);
});
it('should come back with same input as output if array can validate.', () => {
let s = isvalid([{
awesome: true,
why: 'it just is!'
}], [{
awesome: Boolean,
why: 'string'
}]);
return Promise.all([
expect(s).to.eventually.be.an('Array').of.length(1),
expect(s).to.eventually.to.have.property(0).and.to.have.property('awesome').equals(true),
expect(s).to.eventually.to.have.property(0).and.to.have.property('why').equals('it just is!')
]);
});
it('should come back with no error and an empty array when supplying empty array.', () => {
return expect(isvalid([], [{}])).to.eventually.have.length(0);
});
describe('#errors', function() {
it ('should come back with error and index of key path properly set.', () => {
return expect(isvalid([1], {
type: Array,
schema: {
type: String,
}}, { keyPath: 'root'}))
.to.eventually.be.rejectedWith('Is not of type string.')
.and.to.be.instanceOf(ValidationError)
.and.have.property('keyPath').eql(['root', '0']);
});
});
describe('len', function() {
it('should come back with same input as output if within ranges of len.', () => {
return expect(isvalid([1,2], {
type: Array,
len: '2-',
schema: Number
})).to.eventually.be.an('Array').of.length(2);
});
it('should come back with error if array length is not within ranges of len.', () => {
return expect(isvalid([], {
type: Array,
len: '2-',
schema: {}}))
.to.eventually.be.rejectedWith('Array length is not within range of \'2-\'.')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'len');
});
describe('#errors', function() {
it('should come back with error of post message if array length is not within ranges of len.', () => {
return expect(isvalid([], {
type: Array,
len: '2-',
schema: {},
errors: {
len: 'Not within range.'
}}))
.to.eventually.be.rejectedWith('Not within range.')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'len');
});
});
});
describe('unique', function() {
it('should come back with error if array of objects is not unique.', () => {
return expect(isvalid([{
awesome: true
},{
awesome: true
}], {
type: Array,
unique: true,
schema: { awesome: Boolean }}))
.to.eventually.be.rejectedWith('Array is not unique.')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'unique');
});
it('should come back with no error if array of strings is unique.', () => {
return expect(isvalid(['This', 'is', 'an', 'array'], {
type: Array,
unique: true,
schema: 'string'
})).to.eventually.have.length(4);
});
describe('#errors', function() {
it('should come back with error of post message if array of objects is not unique.', () => {
return expect(isvalid([{
awesome: true
},{
awesome: true
}], {
type: Array,
unique: true,
schema: { awesome: Boolean },
errors: {
unique: 'Not a set.'
}}))
.to.eventually.be.rejectedWith('Not a set.')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'unique');
});
});
});
describe('autoWrap', function() {
it('should come back with non-array wrapped in array.', () => {
return expect(isvalid({
test: true
}, {
type: Array,
autoWrap: true,
schema: {
test: Boolean
}
})).to.eventually.be.an('array').and.to.have.property(0).and.to.have.property('test', true);
});
it('should come back with type error if autoWrap and not matching sub-schema.', () => {
return expect(isvalid({
test: 'Not a boolean'
}, {
type: Array,
autoWrap: true,
schema: {
test: Boolean
}}))
.to.eventually.be.rejectedWith('Is not of type boolean.')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'type');
});
it('should come back with type error if no autoWrap and matching sub-schema.', () => {
return expect(isvalid({
test: true
}, [{
test: Boolean}]))
.to.eventually.be.rejectedWith('Is not of type array.')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'type');
});
it('should prioritize concrete over defaults.', () => {
return expect(isvalid(true, {
type: Array,
autoWrap: false
}, { defaults: { autoWrap: true }}))
.to.eventually.be.rejectedWith('Is not of type array.')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'type');
});
});
});
describe('string validator', function() {
commonTests.all(String, 'string', 123);
it('should come back with no error and input same as output if string is supplied.', () => {
return expect(isvalid('123', 'string')).to.eventually.be.a('String').equals('123');
});
describe('trim', function() {
it('should come back with trimmed string when trim is set to true.', () => {
return expect(isvalid('\t123abc ', { type: 'string', trim: true }))
.to.eventually.equal('123abc');
});
it('should come back with trimmed string when trim option is true.', () => {
return expect(isvalid('\t123abc ', 'string', { defaults: { trim: true }}))
.to.eventually.equal('123abc');
});
it('should come back with the string untrimmed if trim is not specified', () => {
return expect(isvalid('\t123abc ', 'string'))
.to.eventually.equal('\t123abc ');
});
it('should prioritize concrete over defaults.', () => {
return expect(isvalid(' 123', {
type: 'string',
trim: false
}, { defaults: { trim: true }})).to.eventually.equal(' 123');
});
});
describe('match', function() {
it('should come back with an error if string does not match RegExp.', () => {
return expect(isvalid('123', { type: 'string', match: /^[a-z]+$/ }))
.to.eventually.be.rejectedWith('Does not match expression ^[a-z]+$.')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'match');
});
it('should come back with no error and validData should match input string when match is specified and input matches.', () => {
return expect(isvalid('123', { type: 'string', match: /^[0-9]+$/ }))
.to.eventually.equal('123');
});
describe('#errors', function() {
it('should come back with an error of post message if string does not match RegExp.', () => {
return expect(isvalid('123', {
type: 'string',
match: /^[a-z]+$/,
errors: {
match: 'Must be a string of letters from a to z.'
}}))
.to.eventually.be.rejectedWith('Must be a string of letters from a to z.')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'match');
});
});
});
describe('enum', function() {
it('should come back with an error if string is not in enum.', () => {
return expect(isvalid('123', { type: 'string', enum: ['this','test'] }))
.to.eventually.be.rejectedWith('Possible values are "this" and "test".')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'enum');
});
it('should come back with no error if string is in enum.', () => {
return expect(isvalid('test', { type: 'string', enum: ['this','test'] }))
.to.eventually.be.a('String').equal('test');
});
describe('#errors', function() {
it('should come back with an error of post message if string is not in enum.', () => {
return expect(isvalid('123', {
type: 'string',
enum: ['this','is','a','test'],
errors: {
enum: 'Must be a word from the sentence "this is a test".'
}}))
.to.eventually.be.rejectedWith('Must be a word from the sentence "this is a test".')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'enum');
});
});
});
describe('length', function() {
it('should come back with an error if string is not with range.', () => {
return expect(isvalid('123', { type: 'string', len: '-2'}))
.to.eventually.be.rejectedWith('String length is not within range of -2')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'len');
});
it('should come back with no error if string is within range.', () => {
return expect(isvalid('123', {
type: 'string',
len: '2-'
}));
});
describe('#errors', function() {
it ('should come back with a custom error message', () => {
return expect(isvalid('123', {
type: 'string',
len: ['-2', 'My custom error']}))
.to.eventually.be.rejectedWith('My custom error')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'len');
});
});
});
});
describe('number validator', function() {
commonTests.all(Number, 123, []);
it('should come back with no error and input same as output if number is supplied.', () => {
return expect(isvalid(123, Number))
.to.eventually.equal(123);
});
describe('range', function() {
it('should come back with error if input is not within range.', () => {
return expect(isvalid(1, { type: Number, range: '2-4' }))
.to.eventually.be.rejectedWith('Not within')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'range');
});
it('should come back with no error and output same as input if within range.', () => {
return expect(isvalid(3, { type: Number, range: '2-4' }))
.to.eventually.equal(3);
});
describe('#errors', function() {
it('should come back with error of post message if input is not within range.', () => {
return expect(isvalid(1, {
type: Number,
range: '2-4',
errors: {
range: 'Must be between 2 and 4.'
}}))
.to.eventually.be.rejectedWith('Must be between 2 and 4.')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'range');
});
});
});
describe('float', function() {
it('should throw error if non-integers are not allowed.', () => {
return expect(isvalid(2.2, { type: Number, float: 'deny' }))
.to.eventually.be.rejectedWith('Number must be an integer.')
.and.to.be.instanceOf(ValidationError)
.and.have.property('validator', 'float');
});
it ('should come back with non-integer values if they are allowed.', () => {
return expect(isvalid(2.2, { type: Number })).to.eventually.equal(2.2);
});
it ('should come back with number rounded if `float` is set to `round`.', () => {
return expect(isvalid(2.5, { type: Number, float: 'round' })).to.eventually.equal(3);
});
it ('should come back with number ceiled if `float` is set to `ceil`.', () => {
return expect(isvalid(2.2, { type: Number, float: 'ceil' })).to.eventually.equal(3);
});
it ('should come back with number floored if `float` is set to `floor`.', () => {
return expect(isvalid(2.8, { type: Number, float: 'floor' })).to.eventually.equal(2);
});
});
});
describe('date validator', function() {
commonTests.all(Date, new Date(), 123);
});
describe('other validator', function() {
commonTests.all(Test, new Test(), 123);
});
describe('plugin validators', function() {
it ('should throw error if casing does not match.', function() {
return expect(isvalid('my-string', { type: String, ensureCase: 'camel' }))
.to.eventually.rejectedWith('Is not camel case.')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'ensureCase');
});
it ('should throw error with custom message if casing does not match.', function() {
return expect(isvalid('my-string', { type: String, ensureCase: ['camel', 'Something is not right!'] }))
.to.eventually.rejectedWith('Something is not right!')
.and.to.be.instanceOf(ValidationError)
.and.to.have.property('validator', 'ensureCase');
});
it ('should come back with correct value.', function() {
return expect(isvalid('myString', { type: String, ensureCase: 'camel' }))
.to.eventually.equal('myString');
});
});
});