occamsrazor-match
Advanced tools
Comparing version 2.2.1 to 3.0.0
@@ -23,6 +23,3 @@ var match = require('../lib/match'); | ||
if (result) { | ||
if (!callback) { | ||
return true; | ||
} | ||
result = true; // extra check only if callback | ||
return true; // if true no needs to go on | ||
} | ||
@@ -29,0 +26,0 @@ } else { |
var match = require('../lib/match'); | ||
var setName = require('../lib/setName'); | ||
function queueCallback(callback) { | ||
var queue = []; | ||
return { | ||
queue: function (obj) { queue.push(obj); }, | ||
execute: function () { | ||
if (!callback) return; | ||
for (var i = 0; i < queue.length; i++) { | ||
callback(queue[i]); | ||
} | ||
} | ||
}; | ||
} | ||
module.exports = function or(args) { | ||
@@ -15,7 +28,9 @@ if (!Array.isArray(args)) throw new Error('"or": requires an array'); | ||
var newfunc = function (o, callback, path) { | ||
callback = queueCallback(callback); | ||
for (var i = 0; i < funcs.length; i++) { | ||
if (funcs[i](o, callback, path)) { | ||
if (funcs[i](o, callback.queue, path)) { | ||
return true; | ||
} | ||
} | ||
callback.execute(); // callback is only relevant if validation is false | ||
return false; | ||
@@ -22,0 +37,0 @@ }; |
@@ -7,7 +7,6 @@ var setName = require('./setName'); | ||
var result = originalValidator(o); | ||
if (callback) { | ||
if (!result && callback) { | ||
callback({ | ||
path: path, | ||
name: originalValidator.name, | ||
result:result, | ||
value: o | ||
@@ -14,0 +13,0 @@ }); |
{ | ||
"name": "occamsrazor-match", | ||
"version": "2.2.1", | ||
"version": "3.0.0", | ||
"description": "helper library for writing validators", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -18,3 +18,6 @@ occamsrazor-match | ||
``` | ||
Writing complex validators may be a bit verbose. This library helps you to write short yet expressive validators. | ||
Writing complex validators may be a bit verbose. This library helps you to write short yet expressive validators. It also takes care of assigning the function a sensible name, this can be very helpful for debugging. For example: | ||
```js | ||
match([1,'test']).name === 'array:[isNumber:1,isString:test]' | ||
``` | ||
@@ -230,6 +233,6 @@ Importing the library | ||
Validation introspection | ||
======================== | ||
This feature can be useful to have some insight about the validation. Like where did it fail, for example. | ||
When validating a value you can pass a function, as a second argument. This function is called whenever a validation step succeed or fail: | ||
Validation errors | ||
================= | ||
This feature can be useful to have some insight about what went wrong in the validation. | ||
When validating a value you can pass a function, as a second argument. This function is called whenever a validation step fail (only if it is relevant to the validation): | ||
```js | ||
@@ -249,3 +252,3 @@ var validator = match({ | ||
}, | ||
deleted: false | ||
deleted: true | ||
}, function (val) { | ||
@@ -256,3 +259,2 @@ // val is an object containing: | ||
name: name, // name of the function | ||
result: result, // true or false | ||
value: o // the value on which the validator ran | ||
@@ -264,11 +266,13 @@ } | ||
```js | ||
{ path: '', name: 'isObject', result: true, value: { user: { name: 'Maurizio', jobtitle: 'engineer' }, deleted: false } }, | ||
{ path: 'user', name: 'hasAttribute', result: true, value: { user: { name: 'Maurizio', jobtitle: 'engineer' }, deleted: false } }, | ||
{ path: 'user', name: 'isObject', result: true, value: { name: 'Maurizio', jobtitle: 'engineer' } }, | ||
{ path: 'user.name', name: 'hasAttribute', result: true, value: { name: 'Maurizio', jobtitle: 'engineer' } }, | ||
{ path: 'user.name', name: 'isRegExp:/[a-zA-Z]+/', result: true, value: 'Maurizio' }, | ||
{ path: 'user.jobtitle', name: 'hasAttribute', result: true, value: { name: 'Maurizio', jobtitle: 'engineer' } }, | ||
{ path: 'user.jobtitle', name: 'isString:engineer', result: true, value: 'engineer' }, | ||
{ path: 'deleted', name: 'hasAttribute', result: true, value: { user: { name: 'Maurizio', jobtitle: 'engineer' }, deleted: false } }, | ||
{ path: 'deleted', name: 'not(isTrue)', result: true, value: false }]); | ||
{ path: 'deleted', name: 'not(isTrue)', result: true, value: true }]); | ||
``` | ||
If you want to collect all this informations in an array you can use the validationErrors helper: | ||
```js | ||
var validationErrors = require('occamsrazor-match/extra/validationErrors'); | ||
... | ||
var errors = validationErrors(); | ||
var validator = arrayOf(5); | ||
validator([5, 5], errors); | ||
console.log(errors()); // returns a list of all errors | ||
``` |
@@ -11,3 +11,3 @@ var assert = require('chai').assert; | ||
var isInstanceOf = require('../extra/isInstanceOf'); | ||
var validationResult = require('../extra/validationResult'); | ||
var validationErrors = require('../extra/validationErrors'); | ||
@@ -17,90 +17,66 @@ describe('logger', function () { | ||
it('must log simple object', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = match(1); | ||
validator(1, result); | ||
assert.deepEqual(result(), [ { path: '', name: 'isNumber:1', result: true, value: 1 } ]); | ||
validator(1, errors); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
it('must log simple object - false', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = match(1); | ||
validator(2, result); | ||
assert.deepEqual(result(), [ { path: '', name: 'isNumber:1', result: false, value: 2 } ]); | ||
validator(2, errors); | ||
assert.deepEqual(errors(), [ { path: '', name: 'isNumber:1', value: 2 } ]); | ||
}); | ||
it('must log a custom function', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = match(function isCool(o) { return o === 'cool'; }); | ||
validator('cool', result); | ||
assert.deepEqual(result(), [ { path: '', name: 'isCool', result: true, value: 'cool' } ]); | ||
validator('cool', errors); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
it('must log an array', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = match([1, 2]); | ||
validator([1, 2], result); | ||
validator([1, 2], errors); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isArray', result: true, value: [ 1, 2 ] }, | ||
{ path: '[0]', name: 'isNumber:1', result: true, value: 1 }, | ||
{ path: '[1]', name: 'isNumber:2', result: true, value: 2 } ]); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
it('must log an array (valid false)', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = match([1, 2]); | ||
validator([3, 2], result); | ||
validator([3, 2], errors); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isArray', result: true, value: [ 3, 2 ] }, | ||
{ path: '[0]', name: 'isNumber:1', result: false, value: 3 }, | ||
{ path: '[1]', name: 'isNumber:2', result: true, value: 2 } ]); | ||
assert.deepEqual(errors(), [ | ||
{ path: '[0]', name: 'isNumber:1', value: 3 } | ||
]); | ||
}); | ||
it('must log an object', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = match({ key1: 1, key2: 2 }); | ||
validator({ key1: 1, key2: 2 }, result); | ||
validator({ key1: 1, key2: 2 }, errors); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isObject', result: true, value: { key1: 1, key2: 2 } }, | ||
{ path: 'key1', name: 'hasAttribute', result: true, value: { key1: 1, key2: 2 } }, | ||
{ path: 'key1', name: 'isNumber:1', result: true, value: 1 }, | ||
{ path: 'key2', name: 'hasAttribute', result: true, value: { key1: 1, key2: 2 } }, | ||
{ path: 'key2', name: 'isNumber:2', result: true, value: 2 } ]); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
it('must log an object, validate false', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = match({ key1: 1, key2: 2 }); | ||
validator({ key1: 1 }, result); | ||
validator({ key1: 1 }, errors); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isObject', result: true, value: { key1: 1 } }, | ||
{ path: 'key1', name: 'hasAttribute', result: true, value: { key1: 1 } }, | ||
{ path: 'key1', name: 'isNumber:1', result: true, value: 1 }, | ||
{ path: 'key2', name: 'hasAttribute', result: false, value: { key1: 1 } }]); | ||
assert.deepEqual(errors(), [ | ||
{ path: 'key2', name: 'hasAttribute', value: { key1: 1 } }]); | ||
}); | ||
it('must log an object, validate false', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = match({ key1: 1, key2: 2 }); | ||
validator({ key1: 3, key2: 2 }, result); | ||
validator({ key1: 3, key2: 2 }, errors); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isObject', result: true, value: { key1: 3, key2: 2 } }, | ||
{ path: 'key1', name: 'hasAttribute', result: true, value: { key1: 3, key2: 2 } }, | ||
{ path: 'key1', name: 'isNumber:1', result: false, value: 3 }, | ||
{ path: 'key2', name: 'hasAttribute', result: true, value: { key1: 3, key2: 2 } }, | ||
{ path: 'key2', name: 'isNumber:2', result: true, value: 2 } ]); | ||
assert.deepEqual(errors(), [ | ||
{ path: 'key1', name: 'isNumber:1', value: 3 }, | ||
]); | ||
}); | ||
it('must log an object, validate false, show only false', function () { | ||
var result = validationResult(false); | ||
var validator = match({ key1: 1, key2: 2 }); | ||
validator({ key1: 1 }, result); | ||
assert.deepEqual(result(), [ | ||
{ path: 'key2', name: 'hasAttribute', result: false, value: { key1: 1 } }]); | ||
}); | ||
}); | ||
@@ -110,10 +86,6 @@ | ||
it('must log simple object', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = has(['test1', 'test2']); | ||
validator({test1: 1, test2: 2}, result); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isObject', result: true, value: {test1: 1, test2: 2} }, | ||
{ path: 'test1', name: 'hasAttribute', result: true, value: {test1: 1, test2: 2} }, | ||
{ path: 'test2', name: 'hasAttribute', result: true, value: {test1: 1, test2: 2} } | ||
]); | ||
validator({test1: 1, test2: 2}, errors); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
@@ -124,17 +96,13 @@ }); | ||
it('must log isPropotypeOf', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = isPrototypeOf(Array.prototype); | ||
validator([], result); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isPrototypeOf:Array', result: true, value: [] }, | ||
]); | ||
validator([], errors); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
it('must log isInstanceOf', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = isInstanceOf(Array); | ||
validator([], result); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isInstanceOf:Array', result: true, value: [] }, | ||
]); | ||
validator([], errors); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
@@ -145,7 +113,7 @@ }); | ||
it('must log not', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = not(1); | ||
validator(1, result); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'not(isNumber:1)', result: false, value: 1 }, | ||
validator(1, errors); | ||
assert.deepEqual(errors(), [ | ||
{ path: '', name: 'not(isNumber:1)', value: 1 }, | ||
]); | ||
@@ -157,21 +125,18 @@ }); | ||
it('must log and', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = and([ | ||
function sum3(o) { return o[0] + o[1] === 3; }, | ||
function are2Items(o) { return o.length === 2; }]); | ||
validator([1, 2], result); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'sum3', result: true, value: [1, 2] }, | ||
{ path: '', name: 'are2Items', result: true, value: [1, 2] }, | ||
]); | ||
validator([1, 2], errors); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
it('must log and, one fails', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = and([ | ||
function sum3(o) { return o[0] + o[1] === 3; }, | ||
function are2Items(o) { return o.length === 2; }]); | ||
validator([1, 3], result); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'sum3', result: false, value: [1, 3] }, | ||
validator([1, 3], errors); | ||
assert.deepEqual(errors(), [ | ||
{ path: '', name: 'sum3', value: [1, 3] }, | ||
]); | ||
@@ -183,23 +148,27 @@ }); | ||
it('must log or', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = or([ | ||
function sum3(o) { return o[0] + o[1] === 3; }, | ||
function are2Items(o) { return o.length === 2; }]); | ||
validator([1, 2], result); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'sum3', result: true, value: [1, 2] }, | ||
]); | ||
validator([1, 2], errors); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
it('must log or, one fails', function () { | ||
var result = validationResult(true); | ||
it('must log or, all fail', function () { | ||
var errors = validationErrors(); | ||
var validator = or([ | ||
function sum3(o) { return o[0] + o[1] === 3; }, | ||
function are2Items(o) { return o.length === 2; }]); | ||
validator([1, 3], result); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'sum3', result: false, value: [1, 3] }, | ||
{ path: '', name: 'are2Items', result: true, value: [1, 3] }, | ||
]); | ||
validator([1, 1, 4], errors); | ||
assert.deepEqual(errors(), [ | ||
{ path: '', name: 'sum3', value: [ 1, 1, 4 ] }, | ||
{ path: '', name: 'are2Items', value: [ 1, 1, 4 ] } ]); | ||
}); | ||
it('must log or, only if relevant)', function () { | ||
var errors = validationErrors(); | ||
var validator = or([false, true]); | ||
validator(true, errors); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
}); | ||
@@ -209,22 +178,23 @@ | ||
it('must log arrayOf', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = arrayOf(5); | ||
validator([5, 5], result); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isArray', result: true, value: [5, 5] }, | ||
{ path: '[0]', name: 'isNumber:5', result: true, value: 5 }, | ||
{ path: '[1]', name: 'isNumber:5', result: true, value: 5 }, | ||
]); | ||
validator([5, 5], errors); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
it('must log arrayOf, one fails', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = arrayOf(5); | ||
validator([2, 5], result); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isArray', result: true, value: [2, 5] }, | ||
{ path: '[0]', name: 'isNumber:5', result: false, value: 2 }, | ||
{ path: '[1]', name: 'isNumber:5', result: true, value: 5 }, | ||
validator([2, 5], errors); | ||
assert.deepEqual(errors(), [ | ||
{ path: '[0]', name: 'isNumber:5', value: 2 }, | ||
]); | ||
}); | ||
it('must stop logging is validation is true (some)', function () { | ||
var errors = validationErrors(); | ||
var validator = arrayOf(5, 'some'); | ||
validator([5, 2, 3], errors); | ||
assert.deepEqual(errors(), []); | ||
}); | ||
}); | ||
@@ -234,3 +204,3 @@ | ||
it('must log composed object', function () { | ||
var result = validationResult(true); | ||
var errors = validationErrors(); | ||
var validator = match({ | ||
@@ -248,17 +218,10 @@ user: { | ||
}, | ||
deleted: false | ||
}, result); | ||
deleted: true | ||
}, errors); | ||
assert.deepEqual(result(), [ | ||
{ path: '', name: 'isObject', result: true, value: { user: { name: 'Maurizio', jobtitle: 'engineer' }, deleted: false } }, | ||
{ path: 'user', name: 'hasAttribute', result: true, value: { user: { name: 'Maurizio', jobtitle: 'engineer' }, deleted: false } }, | ||
{ path: 'user', name: 'isObject', result: true, value: { name: 'Maurizio', jobtitle: 'engineer' } }, | ||
{ path: 'user.name', name: 'hasAttribute', result: true, value: { name: 'Maurizio', jobtitle: 'engineer' } }, | ||
{ path: 'user.name', name: 'isRegExp:/[a-zA-Z]+/', result: true, value: 'Maurizio' }, | ||
{ path: 'user.jobtitle', name: 'hasAttribute', result: true, value: { name: 'Maurizio', jobtitle: 'engineer' } }, | ||
{ path: 'user.jobtitle', name: 'isString:engineer', result: true, value: 'engineer' }, | ||
{ path: 'deleted', name: 'hasAttribute', result: true, value: { user: { name: 'Maurizio', jobtitle: 'engineer' }, deleted: false } }, | ||
{ path: 'deleted', name: 'not(isTrue)', result: true, value: false }]); | ||
assert.deepEqual(errors(), [ | ||
{ path: 'deleted', name: 'not(isTrue)', value: true } | ||
]); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
274
35092
808