occamsrazor-match
Advanced tools
Comparing version 2.0.0 to 2.1.0
@@ -8,5 +8,5 @@ var match = require('../lib/match'); | ||
var newfunc = function (o) { | ||
var newfunc = function (o, callback, path) { | ||
for (var i = 0; i < funcs.length; i++) { | ||
if (!funcs[i](o)) { | ||
if (!funcs[i](o, callback, path)) { | ||
return false; | ||
@@ -13,0 +13,0 @@ } |
var setName = require('../lib/setName'); | ||
var logger = require('../lib/logger'); | ||
@@ -6,3 +7,3 @@ module.exports = function isInstanceOf(constructor) { | ||
setName(func, 'isInstanceOf:' + constructor.name); | ||
return func; | ||
return logger(func); | ||
}; |
var setName = require('../lib/setName'); | ||
var logger = require('../lib/logger'); | ||
@@ -6,3 +7,3 @@ module.exports = function isPrototypeOf(proto) { | ||
setName(func, 'isPrototypeOf:' + proto.constructor.name); | ||
return func; | ||
return logger(func); | ||
}; |
var match = require('../lib/match'); | ||
var setName = require('../lib/setName'); | ||
var logger = require('../lib/logger'); | ||
@@ -10,3 +11,3 @@ module.exports = function not(arg) { | ||
setName(newfunc, 'not(' + func.name + ')'); | ||
return newfunc; | ||
return logger(newfunc); | ||
}; |
@@ -8,5 +8,5 @@ var match = require('../lib/match'); | ||
var newfunc = function (o) { | ||
var newfunc = function (o, callback, path) { | ||
for (var i = 0; i < funcs.length; i++) { | ||
if (funcs[i](o)) { | ||
if (funcs[i](o, callback, path)) { | ||
return true; | ||
@@ -13,0 +13,0 @@ } |
var setName = require('./setName'); | ||
var logger = require('./logger'); | ||
@@ -37,4 +38,22 @@ function isAnything() { | ||
function isArray(o) { | ||
var functions = o.map(function (item) { | ||
function getIsArray() { | ||
return logger(function isArray(o) { | ||
return Array.isArray(o); | ||
}); | ||
} | ||
function getIsObject() { | ||
return logger(function isObject(o) { | ||
return typeof o === 'object'; | ||
}); | ||
} | ||
function getHasAttr(attr) { | ||
return logger(function hasAttribute(o) { | ||
return attr in o; | ||
}); | ||
} | ||
function array(o) { | ||
var functions = o.map(function (item, index) { | ||
return match(item); | ||
@@ -45,17 +64,22 @@ }); | ||
var func = function (arr) { | ||
if (!Array.isArray(arr)) return false; | ||
var func = function (arr, callback, path) { | ||
var result = true; | ||
path = path || ''; | ||
if (!getIsArray()(arr, callback, path)) return false; | ||
for (var i = 0; i < functions.length; i++) { | ||
if (!functions[i](arr[i])) { | ||
return false; | ||
if (!functions[i](arr[i], callback, path + '[' + i + ']')) { | ||
if (!callback) { | ||
return false; | ||
} | ||
result = false; // extra check only if callback | ||
} | ||
} | ||
return true; | ||
return result; | ||
}; | ||
setName(func, 'isArray:[' + names + ']'); | ||
setName(func, 'array:[' + names + ']'); | ||
return func; | ||
} | ||
function isObject(o) { | ||
function object(o) { | ||
var functions = Object.keys(o).map(function (k) { | ||
@@ -76,13 +100,18 @@ return { | ||
var func = function (obj) { | ||
if (typeof obj !== 'object') return false; | ||
var func = function (obj, callback, path) { | ||
var result = true; | ||
var currentPath; | ||
if (!getIsObject()(obj, callback, path)) return false; | ||
for (var k in o) { | ||
if (!(k in obj)) return false; | ||
if (!functions[k](obj[k])) { | ||
return false; | ||
currentPath = path ? path + '.' + k : k; | ||
if (!getHasAttr(k)(obj, callback, currentPath) || !functions[k](obj[k], callback, currentPath)) { | ||
if (!callback) { | ||
return false; | ||
} | ||
result = false; // extra check only if callback | ||
} | ||
} | ||
return true; | ||
return result; | ||
}; | ||
setName(func, 'isObject:{' + names + '}'); | ||
setName(func, 'object:{' + names + '}'); | ||
return func; | ||
@@ -94,2 +123,3 @@ } | ||
var func; | ||
if (typeof o === 'undefined') { | ||
@@ -99,24 +129,28 @@ func = isAnything; | ||
else if (typeof o === 'string') { | ||
func = isString(o); | ||
func = logger(isString(o)); | ||
} | ||
else if (typeof o === 'number') { | ||
func = isNumber(o); | ||
func = logger(isNumber(o)); | ||
} | ||
else if (typeof o === 'boolean') { | ||
func = isBoolean(o); | ||
func = logger(isBoolean(o)); | ||
} | ||
else if (o === null) { | ||
func = isNull; | ||
func = logger(isNull); | ||
} | ||
else if (o instanceof RegExp) { | ||
func = isRegExp(o); | ||
func = logger(isRegExp(o)); | ||
} | ||
else if (typeof o === 'function') { | ||
func = o; | ||
if (o.length > 1) { | ||
func = o; | ||
} else { | ||
func = logger(o); | ||
} | ||
} | ||
else if (Array.isArray(o)) { | ||
func = isArray(o); | ||
func = array(o); | ||
} | ||
else if (typeof o === 'object') { | ||
func = isObject(o); | ||
func = object(o); | ||
} | ||
@@ -123,0 +157,0 @@ |
{ | ||
"name": "occamsrazor-match", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "helper library for writing validators", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -169,3 +169,18 @@ occamsrazor-match | ||
Custom validator | ||
================ | ||
A validator is a simple function that given a value returns true or false. You can build your own and use it together with the other functions: | ||
```js | ||
function isEven(n) {return o % 2 === 0;}; | ||
match(isEven); | ||
or([isEven, match(null)]); | ||
match({ | ||
numberOfShoes: isEven | ||
}); | ||
``` | ||
Note: I have used a named function (not an anonymous function expression or an arrow function). It is important as logging and debugging rely entirely on the function name. | ||
Mixing them up! | ||
@@ -191,5 +206,47 @@ =============== | ||
match(2).name === 'isNumber:2' | ||
match([1,'test']).name === 'isArray:[isNumber:1,isString:test]' | ||
has('test1', 'test2').name === 'isObject:{test1:isAnything,test2:isAnything}' | ||
match([1,'test']).name === 'array:[isNumber:1,isString:test]' | ||
has('test1', 'test2').name === 'object:{test1:isAnything,test2:isAnything}' | ||
``` | ||
This can be very helpful for debugging. | ||
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: | ||
```js | ||
var validator = match({ | ||
user: { | ||
name: /[a-zA-Z]+/, | ||
jobtitle: or(['engineer', 'analyst']) | ||
}, | ||
deleted: not(true) | ||
}); | ||
validator({ | ||
user: { | ||
name: 'Maurizio', | ||
jobtitle: 'engineer' | ||
}, | ||
deleted: false | ||
}, function (val) { | ||
// val is an object containing: | ||
{ | ||
path: path, // if this validation step is nested in an object or array | ||
name: name, // name of the function | ||
result: result, // true or false | ||
value: o // the value on which the validator ran | ||
} | ||
}); | ||
``` | ||
Returning: | ||
```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 }]); | ||
``` |
@@ -46,3 +46,3 @@ var assert = require('chai').assert; | ||
}); | ||
assert.isTrue(hasX10({ center: { x:'10', y:'1' } } )); | ||
assert.isTrue(hasX10({ center: { x:'10', y:'1' } })); | ||
assert.isFalse(hasX10( {center: { x:'11', y:'1' } } )); | ||
@@ -49,0 +49,0 @@ }); |
@@ -37,9 +37,9 @@ var assert = require('chai').assert; | ||
it('must return name for array', function () { | ||
assert.equal(match([]).name, 'isArray:[]'); | ||
assert.equal(match([]).name, 'array:[]'); | ||
}); | ||
it('must return name for array (2)', function () { | ||
assert.equal(match([1,'test']).name, 'isArray:[isNumber:1,isString:test]'); | ||
assert.equal(match([1,'test']).name, 'array:[isNumber:1,isString:test]'); | ||
}); | ||
it('must return name for object', function () { | ||
assert.equal(match({}).name, 'isObject:{}'); | ||
assert.equal(match({}).name, 'object:{}'); | ||
}); | ||
@@ -49,3 +49,3 @@ }); | ||
it('must return name', function () { | ||
assert.equal(has(['test1', 'test2']).name, 'isObject:{test1:isAnything,test2:isAnything}'); | ||
assert.equal(has(['test1', 'test2']).name, 'object:{test1:isAnything,test2:isAnything}'); | ||
}); | ||
@@ -52,0 +52,0 @@ }); |
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
33651
21
686
251