check-more-types
Advanced tools
Comparing version 0.7.0 to 0.8.0
{ | ||
"name": "check-more-types", | ||
"main": "check-more-types.js", | ||
"version": "0.7.0", | ||
"version": "0.8.0", | ||
"homepage": "https://github.com/kensho/check-more-types", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
@@ -149,2 +149,20 @@ (function checkMoreTypes(check) { | ||
if (!check.defend) { | ||
check.defend = function defend(fn) { | ||
var predicates = Array.prototype.slice.call(arguments, 1); | ||
return function () { | ||
var n = arguments.length; | ||
while (n--) { | ||
var predicate = predicates[n]; | ||
if (check.fn(predicate)) { | ||
if (!predicate.call(null, arguments[n])) { | ||
throw new Error('Argument ' + (n + 1) + ' ' + arguments[n] + ' does not pass predicate'); | ||
} | ||
} | ||
} | ||
return fn.apply(null, arguments); | ||
}; | ||
}; | ||
} | ||
if (!check.mixin) { | ||
@@ -151,0 +169,0 @@ /** Adds new predicate to all objects |
@@ -1,1 +0,1 @@ | ||
!function(a){"use strict";function b(a){return"undefined"!=typeof a}function c(a){return 0===a||1===a}function d(a){return"boolean"==typeof a}function e(a,b){return Boolean(a&&b&&"string"==typeof b&&"undefined"!=typeof a[b])}function f(b){return a.string(b)&&b.toLowerCase()===b}function g(b){return a.array(b)&&b.length>0}function h(b,c){var d=a.array(b)&&b.every(a.string);return d&&a.bool(c)&&c?b.every(a.lowerCase):d}function i(b,c){return a.array(b)&&b.every(function(b){return a.arrayOfStrings(b,c)})}function j(b,c){return a.verify.object(b,"missing object to check"),a.verify.object(c,"missing predicates object"),Object.keys(c).forEach(function(b){a.verify.fn(c[b],"not a predicate function for "+b)}),a.every(a.map(b,c))}function k(a,b){return j(b,a)}function l(b,c){a.verify.fn(b,"expected function that raises");try{b()}catch(d){return"undefined"==typeof c?!0:"function"==typeof c?c(d):!1}return!1}if(!a)throw new Error("Cannot find check-types library, has it been loaded?");a.mixin||(a.mixin=function(b,c){function d(b,c,d){a.verify.object(b,"missing object"),a.verify.unemptyString(c,"missing name"),a.verify.fn(d,"missing function"),b[c]||(b[c]=d)}function e(b){return function(){return!a.defined(arguments[0])||a.nulled(arguments[0])?!0:b.apply(null,arguments)}}function f(a){return function(){return!a.apply(null,arguments)}}function g(b,c){return function(){var d;if(b.apply(null,arguments)===!1)throw d=arguments[arguments.length-1],new Error(a.unemptyString(d)?d:c)}}a.verify.fn(b,"expected predicate function"),a.unemptyString(c)||(c=b.name),a.verify.unemptyString(c,"predicate function missing name\n"+b.toString()),d(a,c,b),d(a.maybe,c,e(b)),d(a.not,c,f(b)),d(a.verify,c,g(b,c+" failed"))});var m={defined:b,bit:c,bool:d,has:e,lowerCase:f,unemptyArray:g,arrayOfStrings:h,arrayOfArraysOfStrings:i,all:j,schema:k,raises:l};Object.keys(m).forEach(function(b){a.mixin(m[b],b)})}("object"==typeof window?window.check:global.check); | ||
!function(a){"use strict";function b(a){return"undefined"!=typeof a}function c(a){return 0===a||1===a}function d(a){return"boolean"==typeof a}function e(a,b){return Boolean(a&&b&&"string"==typeof b&&"undefined"!=typeof a[b])}function f(b){return a.string(b)&&b.toLowerCase()===b}function g(b){return a.array(b)&&b.length>0}function h(b,c){var d=a.array(b)&&b.every(a.string);return d&&a.bool(c)&&c?b.every(a.lowerCase):d}function i(b,c){return a.array(b)&&b.every(function(b){return a.arrayOfStrings(b,c)})}function j(b,c){return a.verify.object(b,"missing object to check"),a.verify.object(c,"missing predicates object"),Object.keys(c).forEach(function(b){a.verify.fn(c[b],"not a predicate function for "+b)}),a.every(a.map(b,c))}function k(a,b){return j(b,a)}function l(b,c){a.verify.fn(b,"expected function that raises");try{b()}catch(d){return"undefined"==typeof c?!0:"function"==typeof c?c(d):!1}return!1}if(!a)throw new Error("Cannot find check-types library, has it been loaded?");a.defend||(a.defend=function(b){var c=Array.prototype.slice.call(arguments,1);return function(){for(var d=arguments.length;d--;){var e=c[d];if(a.fn(e)&&!e.call(null,arguments[d]))throw new Error("Argument "+(d+1)+" "+arguments[d]+" does not pass predicate")}return b.apply(null,arguments)}}),a.mixin||(a.mixin=function(b,c){function d(b,c,d){a.verify.object(b,"missing object"),a.verify.unemptyString(c,"missing name"),a.verify.fn(d,"missing function"),b[c]||(b[c]=d)}function e(b){return function(){return!a.defined(arguments[0])||a.nulled(arguments[0])?!0:b.apply(null,arguments)}}function f(a){return function(){return!a.apply(null,arguments)}}function g(b,c){return function(){var d;if(b.apply(null,arguments)===!1)throw d=arguments[arguments.length-1],new Error(a.unemptyString(d)?d:c)}}a.verify.fn(b,"expected predicate function"),a.unemptyString(c)||(c=b.name),a.verify.unemptyString(c,"predicate function missing name\n"+b.toString()),d(a,c,b),d(a.maybe,c,e(b)),d(a.not,c,f(b)),d(a.verify,c,g(b,c+" failed"))});var m={defined:b,bit:c,bool:d,has:e,lowerCase:f,unemptyArray:g,arrayOfStrings:h,arrayOfArraysOfStrings:i,all:j,schema:k,raises:l};Object.keys(m).forEach(function(b){a.mixin(m[b],b)})}("object"==typeof window?window.check:global.check); |
@@ -202,26 +202,52 @@ # API | ||
### check.mixin(predicate) | ||
### Defending a function | ||
check.foo; // false | ||
// new predicate to be added. Should have function name | ||
function foo(a) { | ||
return a === 'foo'; | ||
Using *check-more-types* you can separate the inner function logic from checking input | ||
arguments. Instead of this | ||
:::javascript | ||
function add(a, b) { | ||
la(check.number(a), 'first argument should be a number', a); | ||
la(check.number(a), 'second argument should be a number', b); | ||
return a + b; | ||
} | ||
check.mixin(foo); | ||
check.fn(check.foo); // true | ||
check.fn(check.maybe.foo); // true | ||
check.fn(check.not.foo); // true | ||
check.foo('foo'); // true | ||
check.maybe.foo('foo'); // true | ||
check.not.foo('bar'); // true | ||
// you can provide name | ||
function isBar(a) { | ||
return a === 'bar'; | ||
you can use `check.defend` function | ||
### check.defend(fn, predicates) | ||
function add(a, b) { | ||
return a + b; | ||
} | ||
check.mixin(isBar, 'bar'); | ||
check.bar('bar'); // true | ||
check.bar('anything else'); // false | ||
// does NOT overwrite predicate if already exists | ||
check.bar; // isBar | ||
check.mixin(foo, 'bar'); | ||
check.bar; // isBar | ||
var safeAdd = check.defend(add, check.number, check.number); | ||
add('foo', 2); // 'foo2' | ||
check.raises(safeAdd.bind(null, 'foo', 2)); // true | ||
--- | ||
### protects optional arguments | ||
function add(a, b) { | ||
if (typeof b === 'undefined') { | ||
return 'foo'; | ||
} | ||
return a + b; | ||
} | ||
add(2); // 'foo' | ||
var safeAdd = check.defend(add, check.number, check.maybe.number); | ||
safeAdd(2, 3); // 5 | ||
safeAdd(2); // 'foo' | ||
--- | ||
This works great when combined with JavaScript module pattern | ||
:::javascript | ||
var add = (function () { | ||
// inner private function without any argument checks | ||
function add(a, b) { | ||
return a + b; | ||
} | ||
// return defended function | ||
return check.defend(add, check.number, check.number); | ||
}()); |
{ | ||
"name": "check-more-types", | ||
"description": "Additional type checks for https://github.com/philbooth/check-types.js", | ||
"version": "0.7.0", | ||
"version": "0.8.0", | ||
"author": "Gleb Bahmutov <gleb.bahmutov@gmail.com>", | ||
@@ -6,0 +6,0 @@ "bugs": { |
@@ -1,2 +0,2 @@ | ||
# check-more-types v0.7.0 | ||
# check-more-types v0.8.0 | ||
@@ -239,29 +239,55 @@ > Additional type checks for [check-types.js](https://github.com/philbooth/check-types.js) | ||
#### check.mixin(predicate) | ||
#### Defending a function | ||
check.foo; // false | ||
// new predicate to be added. Should have function name | ||
function foo(a) { | ||
return a === 'foo'; | ||
Using *check-more-types* you can separate the inner function logic from checking input | ||
arguments. Instead of this | ||
:::javascript | ||
function add(a, b) { | ||
la(check.number(a), 'first argument should be a number', a); | ||
la(check.number(a), 'second argument should be a number', b); | ||
return a + b; | ||
} | ||
check.mixin(foo); | ||
check.fn(check.foo); // true | ||
check.fn(check.maybe.foo); // true | ||
check.fn(check.not.foo); // true | ||
check.foo('foo'); // true | ||
check.maybe.foo('foo'); // true | ||
check.not.foo('bar'); // true | ||
// you can provide name | ||
function isBar(a) { | ||
return a === 'bar'; | ||
you can use `check.defend` function | ||
#### check.defend(fn, predicates) | ||
function add(a, b) { | ||
return a + b; | ||
} | ||
check.mixin(isBar, 'bar'); | ||
check.bar('bar'); // true | ||
check.bar('anything else'); // false | ||
// does NOT overwrite predicate if already exists | ||
check.bar; // isBar | ||
check.mixin(foo, 'bar'); | ||
check.bar; // isBar | ||
var safeAdd = check.defend(add, check.number, check.number); | ||
add('foo', 2); // 'foo2' | ||
check.raises(safeAdd.bind(null, 'foo', 2)); // true | ||
--- | ||
#### protects optional arguments | ||
function add(a, b) { | ||
if (typeof b === 'undefined') { | ||
return 'foo'; | ||
} | ||
return a + b; | ||
} | ||
add(2); // 'foo' | ||
var safeAdd = check.defend(add, check.number, check.maybe.number); | ||
safeAdd(2, 3); // 5 | ||
safeAdd(2); // 'foo' | ||
--- | ||
This works great when combined with JavaScript module pattern | ||
:::javascript | ||
var add = (function () { | ||
// inner private function without any argument checks | ||
function add(a, b) { | ||
return a + b; | ||
} | ||
// return defended function | ||
return check.defend(add, check.number, check.number); | ||
}()); | ||
### Small print | ||
@@ -268,0 +294,0 @@ |
@@ -624,2 +624,45 @@ describe('check-more-types', function () { | ||
}); | ||
describe('defend', function () { | ||
it('protects a function without predicates', function () { | ||
la(check.fn(check.defend)); | ||
function add(a, b) { return a + b; } | ||
var safeAdd = check.defend(add); | ||
la(check.fn(safeAdd)); | ||
la(safeAdd !== add, 'it is not the same function'); | ||
la(add(2, 3) === 5, 'original function works'); | ||
la(safeAdd(2, 3) === 5, 'protected function works'); | ||
}); | ||
it('protects a function', function () { | ||
function add(a, b) { return a + b; } | ||
var safeAdd = check.defend(add, check.number, check.number); | ||
la(add('foo', 2) === 'foo2', 'adding string to number works just fine'); | ||
la(check.raises(safeAdd.bind(null, 'foo', 2), function (err) { | ||
console.log(err); | ||
return /foo/.test(err.message); | ||
}), 'trying to add string to number breaks'); | ||
}); | ||
it('protects optional arguments', function () { | ||
function add(a, b) { | ||
if (typeof b === 'undefined') { | ||
return 'foo'; | ||
} | ||
return a + b; | ||
} | ||
la(add(2) === 'foo'); | ||
var safeAdd = check.defend(add, check.number, check.maybe.number); | ||
la(safeAdd(2, 3) === 5); | ||
la(safeAdd(2) === 'foo'); | ||
}); | ||
// API doc examples | ||
it('check.defend(fn, predicates)', function () { | ||
function add(a, b) { return a + b; } | ||
var safeAdd = check.defend(add, check.number, check.number); | ||
la(add('foo', 2) === 'foo2', 'adding string to number works just fine'); | ||
la(check.raises(safeAdd.bind(null, 'foo', 2))); | ||
}); | ||
}); | ||
}); |
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
50341
904
329