occamsrazor-validator
Advanced tools
Comparing version 7.0.0 to 8.0.0
57
index.js
@@ -0,52 +1,39 @@ | ||
var match = require('occamsrazor-match'); | ||
var and = require('occamsrazor-match/extra/and'); | ||
var combineValidators = require('./lib/combine-validators'); | ||
var ValidationResult = require('./lib/validation-result'); | ||
var match = require('occamsrazor-match'); | ||
var setName = require('./lib/setName'); | ||
var _validator = function (baseScore, funcs) { | ||
var k; | ||
function buildValidator(baseScore, funcs) { | ||
baseScore = baseScore || 0; | ||
funcs = funcs || []; | ||
var v = function validator(obj) { | ||
var i, score, total = 0; | ||
for (i = 0; i < funcs.length; i++) { | ||
score = funcs[i](obj); | ||
if (!score) { | ||
return null; | ||
} | ||
total += score; // 1 + true === 2 | ||
var innerValidator = and(funcs); | ||
function validator(obj, callback) { | ||
if (innerValidator(obj, callback)) { | ||
return new ValidationResult(funcs.length + baseScore, obj); | ||
} | ||
return new ValidationResult(total + baseScore, obj); | ||
return null; | ||
}; | ||
v.match = function (func) { | ||
return _validator(baseScore, funcs.concat(match(func))); | ||
validator.score = function () { | ||
return funcs.length + baseScore; | ||
}; | ||
v.score = function () { | ||
return funcs.length + baseScore; | ||
validator.match = function (func) { | ||
return buildValidator(baseScore, funcs.concat(match(func))); | ||
}; | ||
v.important = function (bump) { | ||
validator.important = function (bump) { | ||
bump = bump || 64; | ||
return _validator(baseScore + bump, funcs); | ||
return buildValidator(baseScore + bump, funcs); | ||
}; | ||
v.functions = function () { | ||
return funcs; | ||
}; | ||
setName(validator, innerValidator.name + ' (score: ' + validator.score() + ')'); | ||
v.functionNames = function () { | ||
return funcs.map(function (func) { return func.name; }); | ||
}; | ||
return validator; | ||
} | ||
return v; | ||
}; | ||
buildValidator.combine = combineValidators; | ||
// returns a validator (function that returns a score) | ||
var validator = function () { | ||
return _validator(0); | ||
}; | ||
// validator.shortcut_validators = shortcut_validators; | ||
validator.combine = combineValidators; | ||
module.exports = validator; | ||
module.exports = buildValidator; |
@@ -1,13 +0,26 @@ | ||
var ValidationResult = require('../lib/validation-result'); | ||
var ValidationResult = require('./validation-result'); | ||
var setName = require('./setName'); | ||
module.exports = function combineValidators() { | ||
var validators = Array.prototype.slice.call(arguments); | ||
return function getScore() { | ||
var args = Array.prototype.slice.call(arguments); | ||
var i, l, current_score, score = []; | ||
function addValidatorName(validatorName, callback) { | ||
if (!callback) return; | ||
return function (obj) { | ||
obj.validatorName = validatorName; | ||
callback(obj); | ||
}; | ||
} | ||
module.exports = function combineValidators(validators) { | ||
var validatorName = validators.map(function (v) { return v.name; }).join(', '); | ||
var validatorWrapper = function validatorWrapper(args, callback) { | ||
var i, l, current_score, score = [], validator, decoratedCallback; | ||
decoratedCallback = addValidatorName(validatorName, callback); | ||
if (args.length < validators.length) { | ||
decoratedCallback && decoratedCallback({ path: '', name: 'minArguments:' + args.length, result: false, value: args }); | ||
return null; | ||
} | ||
decoratedCallback && decoratedCallback({ path: '', name: 'minArguments:' + args.length, result: true, value: args }); | ||
for (i = 0, l = validators.length; i < l; i++) { | ||
current_score = validators[i](args[i]); | ||
validator = validators[i]; | ||
decoratedCallback = addValidatorName(validators[i].name, callback); | ||
current_score = validator(args[i], decoratedCallback); | ||
if (!current_score) { | ||
@@ -20,2 +33,6 @@ return null; | ||
}; | ||
validatorWrapper.validators = validators; | ||
setName(validatorWrapper, validatorName); | ||
return validatorWrapper; | ||
}; |
{ | ||
"name": "occamsrazor-validator", | ||
"version": "7.0.0", | ||
"version": "8.0.0", | ||
"description": "A duck-typing library", | ||
@@ -34,4 +34,4 @@ "main": "index.js", | ||
"dependencies": { | ||
"occamsrazor-match": "^1.0.0" | ||
"occamsrazor-match": "^2.1.1" | ||
} | ||
} |
@@ -115,7 +115,7 @@ occamsrazor-validator | ||
var is8 = isNumber.match(8); | ||
var v = combineValidators(isNumber, is5, is8); | ||
var v = combineValidators([isNumber, is5, is8]); | ||
``` | ||
and then test if it matches: | ||
```js | ||
v(1, 5, 8).value(); // it will return [1, 2, 2] | ||
v([1, 5, 8]).value(); // it will return [1, 2, 2] | ||
``` | ||
@@ -126,3 +126,3 @@ If all values match, the validator will return a validationResult with value [1, 2, 2]. | ||
```js | ||
v(1, 5, 5); // it will return null | ||
v([1, 5, 5]); // it will return null | ||
``` | ||
@@ -146,2 +146,27 @@ When the value returned is an array it is compared in this way (alphabetically): | ||
Adding a callback for debugging | ||
=============================== | ||
If you need to inspect the state of the validation, you can add a callback to a validator or combined validator: | ||
```js | ||
var has_width_and_height_10 = validator().match({width: 10, height: 10}); | ||
has_width_and_height_10({width: 10, height: 10}, function debug (o) { | ||
// "o" contains: | ||
// name: 'the validator name', | ||
// path: if the validation is applied to an object, the path of the current validation | ||
// result: true or false, | ||
// value: the value used for the validation, | ||
}); | ||
``` | ||
```js | ||
var v = combineValidators([isNumber, is5, is8]); | ||
v([1, 8], function debug (o) { | ||
// "o" contains: | ||
// validatorName: the name of the combination of these validators | ||
// name: 'the validator name', | ||
// path: if the validation is applied to an object, the path of the current validation | ||
// result: true or false, | ||
// value: the value used for the validation, | ||
}); | ||
``` | ||
Syntax | ||
@@ -148,0 +173,0 @@ ====== |
@@ -11,20 +11,64 @@ var assert = require('chai').assert; | ||
var c = validator().match(Array.isArray).match({length: 2}); | ||
v = combineValidators(a, b, c); | ||
v = combineValidators([a, b, c]); | ||
}); | ||
it('must succeed', function () { | ||
assert.deepEqual(v(1, 5, [3, 4]).value(), [0, 1, 2]); | ||
assert.deepEqual(v([1, 5, [3, 4]]).value(), [0, 1, 2]); | ||
}); | ||
it('must log everything', function () { | ||
var out = []; | ||
v([1, 5, [3]], function (o) { | ||
out.push(o); | ||
}); | ||
assert.deepEqual(out, [ | ||
{ path: '', | ||
name: 'minArguments:3', | ||
result: true, | ||
value: [ 1, 5, [ 3 ] ], | ||
validatorName: 'isAnything (score: 0), isNumber:5 (score: 1), and(isArray object:{length:isNumber:2}) (score: 2)' }, | ||
{ path: '', | ||
name: 'isNumber:5', | ||
result: true, | ||
value: 5, | ||
validatorName: 'isNumber:5 (score: 1)' }, | ||
{ path: '', | ||
name: 'isArray', | ||
result: true, | ||
value: [ 3 ], | ||
validatorName: 'and(isArray object:{length:isNumber:2}) (score: 2)' }, | ||
{ path: '', | ||
name: 'isObject', | ||
result: true, | ||
value: [ 3 ], | ||
validatorName: 'and(isArray object:{length:isNumber:2}) (score: 2)' }, | ||
{ path: 'length', | ||
name: 'hasAttribute', | ||
result: true, | ||
value: [ 3 ], | ||
validatorName: 'and(isArray object:{length:isNumber:2}) (score: 2)' }, | ||
{ path: 'length', | ||
name: 'isNumber:2', | ||
result: false, | ||
value: 1, | ||
validatorName: 'and(isArray object:{length:isNumber:2}) (score: 2)' }, | ||
]); | ||
}); | ||
it('must fail if too short', function () { | ||
assert.isNull(v(1, 5)); | ||
assert.isNull(v([1, 5])); | ||
}); | ||
it('must not fail if too long', function () { | ||
assert.deepEqual(v(1, 5, [3, 4], 33).value(), [0, 1, 2]); | ||
assert.deepEqual(v([1, 5, [3, 4], 33]).value(), [0, 1, 2]); | ||
}); | ||
it('must fail if one fails', function () { | ||
assert.isNull(v(1, 3, [3, 4])); | ||
assert.isNull(v([1, 3, [3, 4]])); | ||
}); | ||
it('must return names', function () { | ||
assert.equal(v.name, 'isAnything (score: 0), isNumber:5 (score: 1), and(isArray object:{length:isNumber:2}) (score: 2)'); | ||
}); | ||
}); |
@@ -15,9 +15,20 @@ var assert = require('chai').assert; | ||
it('must have the right name', function () { | ||
assert.equal(is_hello.name, 'validator'); | ||
it('must store function names', function () { | ||
assert.deepEqual(validator().name, 'isAnything (score: 0)'); | ||
assert.deepEqual(is_hello.name, 'isString:hello (score: 1)'); | ||
}); | ||
it('must store function names', function () { | ||
assert.deepEqual(validator().functionNames(), []); | ||
assert.deepEqual(is_hello.functionNames(), ['isString:hello']); | ||
it('must log', function () { | ||
var out = []; | ||
is_hello('hi', function (o) { | ||
out.push(o); | ||
}); | ||
assert.deepEqual(out, [ | ||
{ | ||
name: 'isString:hello', | ||
path: '', | ||
result: false, | ||
value: 'hi', | ||
} | ||
]); | ||
}); | ||
@@ -24,0 +35,0 @@ |
28012
17
504
248
+ Addedoccamsrazor-match@2.2.1(transitive)
- Removedoccamsrazor-match@1.0.0(transitive)
Updatedoccamsrazor-match@^2.1.1