occamsrazor-validator
This is a validator library with a very specific goal. Identifying if a value matches some criteria using (duck typing)[https://en.wikipedia.org/wiki/Duck_typing] and assigning a score to the match.
It is a part of occamsrazor (https://github.com/sithmel/occamsrazor.js) that uses this library for picking the right function for a specific set of arguments.
Importing the library
var validator = ;
What is a validators
Ultimately a validator is a function. When it runs against an object, it returns null or a score (wrapped in a validationResult for convenience). Null means that an object doesn't fit in the validator's constraints. The score represent how well the object fits (its specificity). For example:
var isAnything = ;
"validator()" creates the simplest validator. It matches everything with score 0:
value; // 0value; // 0
You can chain a function to create a more strict validation:
var hasWheels = isAnything;
So for example, the score of this new validator will be 1:
value; // 1; // returns null
You can go on having a more specific validator:
var hasWheelsAndWings = hasWheels;
Every validator has a function "score" that returns its specificity:
isAnything // 0hasWheels // 1hasWheelsAndWings // 2
In order to write validators you can use duck typing, type checking or whatever check you want to use:
// duck typingvar has_wings = ; //type checkingvar is_a_car = ; //othervar is_year = ;
The "match" method allows to extend a validator using a terse syntax. You have already seen that it can take a function as argument. You can also pass a string or a regular expression for matching a string:
var is_hello = ;var contains_nuts = ; ;;
Or numbers:
var is_ten = ;;
It works for booleans and null in the same way. If you pass an array it will match with any element of an input array with its content:
var has_1_2 = ;
Finally you can perform deep property checking using an object and combining the previous checks:
// match with width and height equal to 10var has_width_and_height_10 = ; // match with a center attribute with x and y subattributesvar isNumber = ; // you can find many helpers in this libraryvar has_center = ; // match if obj.recipe.ingredients is a string and match with /nuts/var recipe_has_nuts = ; // match if obj.weight is a number bigger than 100var is_heavy = ;
You can find a lot of documentation and more "ready to use" validators in the occamsrazor-match
Combine validators
You might want to match a group of values. You can do it combining as many validators you want:
var isNumber = ;var is5 = isNumber;var is8 = isNumber;var v = ;
and then test if it matches:
value; // it will return [1, 2, 2]
If all values match, the validator will return a validationResult with value [1, 2, 2]. The elements of the array are the values of the respective validators. If one of them doesn't match the result will be null:
; // it will return null
When the value returned is an array it is compared in this way (alphabetically):
2 3 4 > 2 2 51 < 1 22 > 1 9 5
Sort and compare results
The resulting validator object has an useful property. It can be sorted and compared (greater than, lesser than) just like a basic js value. You can use the output of the toString attribute to compare for equality:
r0 > r1var results = r0 r1 r2 r3;r;r0 === r1
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:
var has_width_and_height_10 = ;;
var v = ;;
Syntax
Validator function
Syntax:
;
Returns a generic validator. It will validate every object with score 0.
validator().score
Syntax:
a_validator;
Returns the score returned by this validator. It can be useful for debugging or introspection.
validator().important
Syntax:
a_validator;
It bumps the score by n (default to 64).
validator().match
Add a check to the validator, using an expressive syntax.
Syntax:
// execute a function against the value: returns true or falsevar validator = ;
The last two forms allow to perform the validation check recursively, walking the properties of the object/array. If a property is undefined the value will match any value.
For example:
var hasCenterX = ;// will match { center: {x: "10"} } var hasCenterX10 = ;// will match {center: { x: "10" } } but not {center: { x: "11" } } var hasCenter5or10 = ;// will match {center: {x: "5"}} or {center: {x: "10"}}