underscore-contrib
Advanced tools
Comparing version 0.1.4 to 0.2.1
@@ -5,3 +5,3 @@ ## How to contribute to Underscore-contrib | ||
* Before sending a pull request for a feature, be sure to have [tests like found in Underscore](http://underscorejs.org/test/). | ||
* Before sending a pull request for a feature, be sure to have [tests like found in Underscore](http://underscorejs.org/test/). Tests may be run in a browser by opening `test/index.html`. Tests and linting can be run in the terminal by using the `grunt test` command, or `grunt watch:test` to automatically rerun after file save. | ||
@@ -8,0 +8,0 @@ * Use the same coding [style as Underscore](https://github.com/documentcloud/underscore/blob/master/underscore.js). |
@@ -1,2 +0,2 @@ | ||
// underscore-contrib v0.1.1 | ||
// underscore-contrib v0.1.4 | ||
// ========================= | ||
@@ -420,11 +420,15 @@ | ||
function enforcesUnary (fn) { | ||
return function mustBeUnary () { | ||
if (arguments.length === 1) { | ||
return fn.apply(this, arguments); | ||
} | ||
else throw new RangeError('Only a single argument may be accepted.'); | ||
} | ||
} | ||
// Curry | ||
// ------- | ||
var curry = (function () { | ||
function checkArguments (argsCount) { | ||
if (argsCount !== 1) { | ||
throw new RangeError('Only a single argument may be accepted.'); | ||
} | ||
} | ||
function collectArgs(func, that, argCount, args, newArg, reverse) { | ||
@@ -439,6 +443,5 @@ if (reverse == true) { | ||
} else { | ||
return function () { | ||
checkArguments(arguments.length); | ||
return enforcesUnary(function () { | ||
return collectArgs(func, that, argCount, args.slice(0), arguments[0], reverse); | ||
}; | ||
}); | ||
} | ||
@@ -448,9 +451,31 @@ } | ||
var that = this; | ||
return function () { | ||
checkArguments(arguments.length); | ||
return enforcesUnary(function () { | ||
return collectArgs(func, that, func.length, [], arguments[0], reverse); | ||
}; | ||
}); | ||
}; | ||
}()); | ||
// Enforce Arity | ||
// -------------------- | ||
var enforce = (function () { | ||
var CACHE = []; | ||
return function enforce (func) { | ||
if (typeof func !== 'function') { | ||
throw new Error('Argument 1 must be a function.'); | ||
} | ||
var funcLength = func.length; | ||
if (CACHE[funcLength] === undefined) { | ||
CACHE[funcLength] = function (enforceFunc) { | ||
return function () { | ||
if (arguments.length !== funcLength) { | ||
throw new RangeError(funcLength + ' arguments must be applied.'); | ||
} | ||
return enforceFunc.apply(this, arguments); | ||
}; | ||
}; | ||
} | ||
return CACHE[funcLength](func); | ||
}; | ||
}()); | ||
// Mixing in the arity functions | ||
@@ -507,3 +532,3 @@ // ----------------------------- | ||
}, | ||
// Flexible curry function with strict arity. | ||
@@ -517,3 +542,43 @@ // Argument application left to right. | ||
return curry.call(this, func, true); | ||
} | ||
}, | ||
curry2: function (fun) { | ||
return enforcesUnary(function curried (first) { | ||
return enforcesUnary(function (last) { | ||
return fun.call(this, first, last); | ||
}); | ||
}) | ||
}, | ||
curry3: function (fun) { | ||
return enforcesUnary(function (first) { | ||
return enforcesUnary(function (second) { | ||
return enforcesUnary(function (last) { | ||
return fun.call(this, first, second, last); | ||
}) | ||
}) | ||
}) | ||
}, | ||
// reverse currying for functions taking two arguments. | ||
rcurry2: function (fun) { | ||
return enforcesUnary(function (last) { | ||
return enforcesUnary(function (first) { | ||
return fun.call(this, first, last); | ||
}) | ||
}) | ||
}, | ||
rcurry3: function (fun) { | ||
return enforcesUnary(function (last) { | ||
return enforcesUnary(function (second) { | ||
return enforcesUnary(function (first) { | ||
return fun.call(this, first, second, last); | ||
}) | ||
}) | ||
}) | ||
}, | ||
// Dynamic decorator to enforce function arity and defeat varargs. | ||
enforce: enforce | ||
}); | ||
@@ -782,3 +847,9 @@ | ||
// Returns function property of object by name, bound to object | ||
_.bound = function(obj, fname) { | ||
var fn = obj[fname]; | ||
if (!_.isFunction(fn)) | ||
throw new TypeError("Expected property to be a function"); | ||
return _.bind(fn, obj); | ||
}; | ||
@@ -1372,3 +1443,3 @@ })(this); | ||
return getPath(obj[[].shift.call(ks)], ks); | ||
return getPath(obj[_.first(ks)], _.rest(ks)); | ||
}, | ||
@@ -1387,3 +1458,3 @@ | ||
return hasPath(obj[[].shift.call(ks)], ks); | ||
return hasPath(obj[_.first(ks)], _.rest(ks)); | ||
} | ||
@@ -1422,2 +1493,93 @@ }); | ||
// Underscore-contrib (underscore.function.arity.js 0.0.1) | ||
// (c) 2013 Michael Fogus, DocumentCloud and Investigative Reporters & Editors | ||
// Underscore-contrib may be freely distributed under the MIT license. | ||
(function(root) { | ||
// Baseline setup | ||
// -------------- | ||
// Establish the root object, `window` in the browser, or `global` on the server. | ||
var _ = root._ || require('underscore'); | ||
// Mixing in the operator functions | ||
// ----------------------------- | ||
_.mixin({ | ||
add: function(x, y) { | ||
return x + y; | ||
}, | ||
sub: function(x, y) { | ||
return x - y; | ||
}, | ||
mul: function(x, y) { | ||
return x * y; | ||
}, | ||
div: function(x, y) { | ||
return x / y; | ||
}, | ||
mod: function(x, y) { | ||
return x % y; | ||
}, | ||
inc: function(x) { | ||
return ++x; | ||
}, | ||
dec: function(x) { | ||
return --x; | ||
}, | ||
neg: function(x) { | ||
return -x; | ||
}, | ||
eq: function(x, y) { | ||
return x == y; | ||
}, | ||
seq: function(x, y) { | ||
return x === y; | ||
}, | ||
neq: function(x, y) { | ||
return x != y; | ||
}, | ||
sneq: function(x, y) { | ||
return x !== y; | ||
}, | ||
not: function(x) { | ||
return !x; | ||
}, | ||
gt: function(x, y) { | ||
return x > y; | ||
}, | ||
lt: function(x, y) { | ||
return x < y; | ||
}, | ||
gte: function(x, y) { | ||
return x >= y; | ||
}, | ||
lte: function(x, y) { | ||
return x <= y; | ||
}, | ||
bitwiseAnd: function(x, y) { | ||
return x & y; | ||
}, | ||
bitwiseOr: function(x, y) { | ||
return x | y; | ||
}, | ||
bitwiseXor: function(x, y) { | ||
return x ^ y; | ||
}, | ||
bitwiseNot: function(x) { | ||
return ~x; | ||
}, | ||
bitwiseLeft: function(x, y) { | ||
return x << y; | ||
}, | ||
bitwiseRight: function(x, y) { | ||
return x >> y; | ||
}, | ||
bitwiseZ: function(x, y) { | ||
return x >>> y; | ||
} | ||
}); | ||
})(this); | ||
// Underscore-contrib (underscore.util.strings.js 0.0.1) | ||
@@ -1424,0 +1586,0 @@ // (c) 2013 Michael Fogus, DocumentCloud and Investigative Reporters & Editors |
@@ -1,2 +0,2 @@ | ||
// underscore-contrib v0.1.1 | ||
// underscore-contrib v0.1.4 | ||
// ========================= | ||
@@ -8,2 +8,2 @@ | ||
(function(n){var r=n._||require("underscore"),t=Array.prototype.slice,e=Array.prototype.concat,u=function(n){return null!=n};r.mixin({cat:function(){return r.reduce(arguments,function(n,u){return r.isArguments(u)?e.call(n,t.call(u)):e.call(n,u)},[])},cons:function(n,t){return r.cat([n],t)},partition:function(n,t,e){var u=function(n){if(null==n)return[];var i=r.take(n,t);return t===r.size(i)?r.cons(i,u(r.drop(n,t))):e?[r.take(r.cat(i,e),t)]:[]};return u(n)},partitionAll:function(n,t,e){e=null!=e?e:t;var u=function(n,t,e){return r.isEmpty(n)?[]:r.cons(r.take(n,t),u(r.drop(n,e),t,e))};return u(n,t,e)},mapcat:function(n,t){return r.cat.apply(null,r.map(n,t))},interpose:function(n,e){if(!r.isArray(n))throw new TypeError;var u=r.size(n);return 0===u?n:1===u?n:t.call(r.mapcat(n,function(n){return r.cons(n,[e])}),0,-1)},weave:function(){return r.some(arguments)?r.filter(r.flatten(r.zip.apply(null,arguments),!0),function(n){return null!=n}):[]},interleave:r.weave,repeat:function(n,t){return r.times(n,function(){return t})},cycle:function(n,t){return r.flatten(r.times(n,function(){return t}),!0)},splitAt:function(n,t){return[r.take(n,t),r.drop(n,t)]},iterateUntil:function(n,r,t){for(var e=[],u=n(t);r(u);)e.push(u),u=n(u);return e},takeSkipping:function(n,t){var e=[],u=r.size(n);if(0>=t)return[];if(1===t)return n;for(var i=0;u>i;i+=t)e.push(n[i]);return e},reductions:function(n,t,e){var u=[],i=e;return r.each(n,function(r,e){i=t(i,n[e]),u.push(i)}),u},keepIndexed:function(n,t){return r.filter(r.map(r.range(r.size(n)),function(r){return t(r,n[r])}),u)}})})(this),function(n){var r=n._||require("underscore"),t=Array.prototype.slice,e=Array.prototype.concat,u=function(n){return null!=n},i=function(n){return n!==!1&&u(n)},o=function(n){return r.isArray(n)||r.isArguments(n)};r.mixin({second:function(n,r,e){return null==n?void 0:null==r||e?n[1]:t.call(n,1,r)},nth:function(n,r){if(0>r||r>n.length-1)throw Error("Attempting to index outside the bounds of the array.");return n[r]},takeWhile:function(n,t){if(!o(n))throw new TypeError;for(var e=r.size(n),u=0;e>u&&i(t(n[u]));u++);return r.take(n,u)},dropWhile:function(n,t){if(!o(n))throw new TypeError;for(var e=r.size(n),u=0;e>u&&i(t(n[u]));u++);return r.drop(n,u)},splitWith:function(n,t){return[r.takeWhile(t,n),r.dropWhile(t,n)]},partitionBy:function(n,t){if(r.isEmpty(n)||!u(n))return[];var i=r.first(n),o=t(i),a=e.call([i],r.takeWhile(r.rest(n),function(n){return r.isEqual(o,t(n))}));return e.call([a],r.partitionBy(r.drop(n,r.size(a)),t))},best:function(n,t){return r.reduce(n,function(n,r){return t(n,r)?n:r})},keep:function(n,t){if(!o(n))throw new TypeError("expected an array as the first argument");return r.filter(r.map(n,function(n){return t(n)}),u)}})}(this),function(n){function r(n,r,t,o){var a=[];(function c(n,l,f){if(!r||r.call(o,n,l,f)!==u){if(e.isObject(n)||e.isArray(n)){if(a.indexOf(n)>=0)throw new TypeError(i);a.push(n),e.each(e.isElement(n)?n.children:n,c,o)}t&&t.call(o,n,l,f)}})(n)}function t(n,r,t){var i=[];return e.walk.preorder(n,function(n,e){return e!==r||(i[i.length]=n,t)?void 0:u}),i}var e=n._||require("underscore"),u={},i="Not a tree: same object found in two different branches";e.walk=r,e.extend(r,{postorder:function(n,t,e){r(n,null,t,e)},preorder:function(n,t,e){r(n,t,null,e)},map:function(n,r,t,e){var u=[];return r.call(null,n,function(n,r,i){u[u.length]=t.call(e,n,r,i)}),u},pluck:function(n,r){return t(n,r,!1)},pluckRec:function(n,r){return t(n,r,!0)}}),e.walk.collect=e.walk.map}(this),function(n){var r=n._||require("underscore"),t=function(){function n(n){if(1!==n)throw new RangeError("Only a single argument may be accepted.")}function r(t,e,u,i,o,a){return 1==a?i.unshift(o):i.push(o),i.length==u?t.apply(e,i):function(){return n(arguments.length),r(t,e,u,i.slice(0),arguments[0],a)}}return function(t,e){var u=this;return function(){return n(arguments.length),r(t,u,t.length,[],arguments[0],e)}}}();r.mixin({fix:function(n){var t=r.rest(arguments),e=function(){for(var e=0,u=0;t.length>u&&arguments.length>e;u++)t[u]===r&&(t[u]=arguments[e++]);return n.apply(null,t)};return e._original=n,e},unary:function(n){return function(r){return n.call(this,r)}},binary:function(n){return function(r,t){return n.call(this,r,t)}},ternary:function(n){return function(r,t,e){return n.call(this,r,t,e)}},quaternary:function(n){return function(r,t,e,u){return n.call(this,r,t,e,u)}},curry:t,rCurry:function(n){return t.call(this,n,!0)}}),r.arity=function(){var n={};return function r(t,e){if(null==n[t]){for(var u=Array(t),i=0;t>i;++i)u[i]="__"+i;var o=u.join(),a="return function ("+o+") { return fun.apply(this, arguments); };";n[t]=Function(["fun"],a)}return null==e?function(n){return r(t,n)}:n[t](e)}}()}(this),function(n){function r(n,r){return t.arity(n.length,function(){return n.apply(this,a.call(arguments,r))})}var t=n._||require("underscore"),e=function(n){return null!=n},u=function(n){return n!==!1&&e(n)},i=[].reverse,o=[].slice,a=[].map,c=function(n){return function(r,t){return 1===arguments.length?function(t){return n(r,t)}:n(r,t)}};t.mixin({always:function(n){return function(){return n}},pipeline:function(){var n=t.isArray(arguments[0])?arguments[0]:arguments;return function(r){return t.reduce(n,function(n,r){return r(n)},r)}},conjoin:function(){var n=arguments;return function(r){return t.every(r,function(r){return t.every(n,function(n){return n(r)})})}},disjoin:function(){var n=arguments;return function(r){return t.some(r,function(r){return t.some(n,function(n){return n(r)})})}},comparator:function(n){return function(r,t){return u(n(r,t))?-1:u(n(t,r))?1:0}},complement:function(n){return function(){return!n.apply(null,arguments)}},splat:function(n){return function(r){return n.apply(null,r)}},unsplat:function(n){var r=n.length;return 1>r?n:1===r?function(){return n.call(this,o.call(arguments,0))}:function(){var t=arguments.length,e=o.call(arguments,0,r-1),u=Math.max(r-t-1,0),i=Array(u),a=o.call(arguments,n.length-1);return n.apply(this,e.concat(i).concat([a]))}},unsplatl:function(n){var r=n.length;return 1>r?n:1===r?function(){return n.call(this,o.call(arguments,0))}:function(){var t=arguments.length,e=o.call(arguments,Math.max(t-r+1,0)),u=o.call(arguments,0,Math.max(t-r+1,0));return n.apply(this,[u].concat(e))}},mapArgs:c(r),juxt:function(){var n=arguments;return function(){var r=arguments;return t.map(n,function(n){return n.apply(null,r)})}},fnull:function(n){var r=t.rest(arguments);return function(){for(var u=t.toArray(arguments),i=t.size(r),o=0;i>o;o++)e(u[o])||(u[o]=r[o]);return n.apply(null,u)}},flip2:function(n){return function(){var r=arguments[0];return arguments[0]=arguments[1],arguments[1]=r,n.apply(null,arguments)}},flip:function(n){return function(){var r=i.call(arguments);return n.apply(null,r)}},k:t.always,t:t.pipeline}),t.unsplatr=t.unsplat,t.mapArgsWith=c(t.flip(r))}(this),function(n){function r(n){return function(r){return n.call(this,r)}}function t(n,r,t){var e,u;for(e=t!==void 0?t:n(),u=n();null!=u;)e=r.call(u,e,u),u=n();return e}function e(n,r){var t=x;return function(){return t===x?t=n:null!=t?t=r.call(t,t):t}}function u(n,r){var t,e,u=n;return function(){return null!=u?(t=r.call(u,u),e=t[1],u=null!=e?t[0]:void 0,e):void 0}}function i(n,r,t){var e=t;return function(){return element=n(),null==element?element:e=e===void 0?element:r.call(element,e,element)}}function o(n,r,t){var e,u=t;return function(){return element=n(),null==element?element:u===void 0?u=element:(e=r.call(element,u,element),u=e[0],e[1])}}function a(n,r){return function(){var t;return t=n(),null!=t?r.call(t,t):void 0}}function c(n,r){return function(){var t;for(t=n();null!=t;){if(r.call(t,t))return t;t=n()}return void 0}}function l(n,r){return c(n,function(n){return!r(n)})}function f(n,r){return c(n,r)()}function s(n,r,t){for(var e=0;r-->0;)n();return null!=t?function(){return t>=++e?n():void 0}:n}function p(n,r){return s(n,null==r?1:r)}function m(n,r){return s(n,0,null==r?1:r)}function v(n){var r=0;return function(){return n[r++]}}function h(n){var r,t,e;return r=0,e=[],t=function(){var u,i;return u=n[r++],u instanceof Array?(e.push({array:n,index:r}),n=u,r=0,t()):u===void 0?e.length>0?(i=e.pop(),n=i.array,r=i.index,t()):void 0:u}}function g(n){return function(){return n}}function y(n,r,t){return function(){var e;return n>r?void 0:(e=n,n+=t,e)}}function d(n,r,t){return function(){var e;return r>n?void 0:(e=n,n-=t,e)}}function A(n,r,t){return null==n?y(1,1/0,1):null==r?y(n,1/0,1):null==t?r>=n?y(n,r,1):d(n,r,1):t>0?y(n,r,t):0>t?d(n,r,Math.abs(t)):k(n)}var w=n._||require("underscore"),x={},q=r(A);w.iterators={accumulate:i,accumulateWithReturn:o,foldl:t,reduce:t,unfold:e,unfoldWithReturn:u,map:a,select:c,reject:l,filter:c,find:f,slice:s,drop:p,take:m,List:v,Tree:h,constant:g,K:g,numbers:q,range:A}}(this),function(n){var r=n._||require("underscore");r.mixin({isInstanceOf:function(n,r){return n instanceof r},isAssociative:function(n){return r.isArray(n)||r.isObject(n)||r.isArguments(n)},isIndexed:function(n){return r.isArray(n)||r.isString(n)||r.isArguments(n)},isSequential:function(n){return r.isArray(n)||r.isArguments(n)},isZero:function(n){return 0===n},isEven:function(n){return r.isFinite(n)&&0===(1&n)},isOdd:function(n){return r.isFinite(n)&&!r.isEven(n)},isPositive:function(n){return n>0},isNegative:function(n){return 0>n},isValidDate:function(n){return r.isDate(n)&&!r.isNaN(n.getTime())},isNumeric:function(n){return!isNaN(parseFloat(n))&&isFinite(n)},isInteger:function(n){return r.isNumeric(n)&&0===n%1},isFloat:function(n){return r.isNumeric(n)&&!r.isInteger(n)},isIncreasing:function(){var n=r.size(arguments);if(1===n)return!0;if(2===n)return arguments[0]<arguments[1];for(var t=1;n>t;t++)if(arguments[t-1]>=arguments[t])return!1;return!0},isDecreasing:function(){var n=r.size(arguments);if(1===n)return!0;if(2===n)return arguments[0]>arguments[1];for(var t=1;n>t;t++)if(arguments[t-1]<=arguments[t])return!1;return!0}})}(this),function(n){var r=n._||require("underscore"),t=(Array.prototype.slice,Array.prototype.concat),e=function(n){return null!=n},u=function(n){return n!==!1&&e(n)},i=function(n){return r.isArray(n)||r.isObject(n)},o=function(n){return function(r){return function(t){return n(t,r)}}};r.mixin({merge:function(){var n=r.some(arguments)?{}:null;return u(n)&&r.extend.apply(null,t.call([n],r.toArray(arguments))),n},renameKeys:function(n,u){return r.reduce(u,function(r,t,u){return e(n[u])?(r[t]=n[u],r):r},r.omit.apply(null,t.call([n],r.keys(u))))},snapshot:function(n){if(null==n||"object"!=typeof n)return n;var t=new n.constructor;for(var e in n)t[e]=r.snapshot(n[e]);return t},updatePath:function(n,t,u){if(!i(n))throw new TypeError("Attempted to update a non-associative object.");if(!e(u))return t(n);var o=r.isArray(u),a=o?u:[u],c=o?r.snapshot(n):r.clone(n),l=r.last(a),f=c;return r.each(r.initial(a),function(n){f=f[n]}),f[l]=t(f[l]),c},setPath:function(n,t,u){if(!e(u))throw new TypeError("Attempted to set a property at a null path.");return r.updatePath(n,function(){return t},u)},frequencies:o(r.countBy)(r.identity)})}(this),function(n){var r=n._||require("underscore"),t=Array.prototype.concat;r.mixin({accessor:function(n){return function(r){return r&&r[n]}},dictionary:function(n){return function(r){return n&&r&&n[r]}},selectKeys:function(n,e){return r.pick.apply(null,t.call([n],e))},kv:function(n,t){return r.has(n,t)?[t,n[t]]:void 0},getPath:function e(n,r){return void 0===n?void 0:0===r.length?n:null===n?void 0:e(n[[].shift.call(r)],r)},hasPath:function u(n,r){var t=r.length;return null==n&&t>0?!1:r[0]in n?1===t?!0:u(n[[].shift.call(r)],r):!1}})}(this),function(n){var r=n._||require("underscore");r.mixin({exists:function(n){return null!=n},truthy:function(n){return n!==!1&&r.exists(n)},falsey:function(n){return!r.truthy(n)},not:function(n){return!n}})}(this),function(n){var r=n._||require("underscore");r.mixin({explode:function(n){return n.split("")},implode:function(n){return n.join("")}})}(this),function(n){var r=n._||require("underscore");r.mixin({done:function(n){var t=r(n);return t.stopTrampoline=!0,t},trampoline:function(n){for(var t=n.apply(n,r.rest(arguments));r.isFunction(t)&&(t=t(),!(t instanceof r&&t.stopTrampoline)););return t.value()}})}(this); | ||
(function(n){var r=n._||require("underscore"),t=Array.prototype.slice,e=Array.prototype.concat,u=function(n){return null!=n};r.mixin({cat:function(){return r.reduce(arguments,function(n,u){return r.isArguments(u)?e.call(n,t.call(u)):e.call(n,u)},[])},cons:function(n,t){return r.cat([n],t)},partition:function(n,t,e){var u=function(n){if(null==n)return[];var i=r.take(n,t);return t===r.size(i)?r.cons(i,u(r.drop(n,t))):e?[r.take(r.cat(i,e),t)]:[]};return u(n)},partitionAll:function(n,t,e){e=null!=e?e:t;var u=function(n,t,e){return r.isEmpty(n)?[]:r.cons(r.take(n,t),u(r.drop(n,e),t,e))};return u(n,t,e)},mapcat:function(n,t){return r.cat.apply(null,r.map(n,t))},interpose:function(n,e){if(!r.isArray(n))throw new TypeError;var u=r.size(n);return 0===u?n:1===u?n:t.call(r.mapcat(n,function(n){return r.cons(n,[e])}),0,-1)},weave:function(){return r.some(arguments)?r.filter(r.flatten(r.zip.apply(null,arguments),!0),function(n){return null!=n}):[]},interleave:r.weave,repeat:function(n,t){return r.times(n,function(){return t})},cycle:function(n,t){return r.flatten(r.times(n,function(){return t}),!0)},splitAt:function(n,t){return[r.take(n,t),r.drop(n,t)]},iterateUntil:function(n,r,t){for(var e=[],u=n(t);r(u);)e.push(u),u=n(u);return e},takeSkipping:function(n,t){var e=[],u=r.size(n);if(0>=t)return[];if(1===t)return n;for(var i=0;u>i;i+=t)e.push(n[i]);return e},reductions:function(n,t,e){var u=[],i=e;return r.each(n,function(r,e){i=t(i,n[e]),u.push(i)}),u},keepIndexed:function(n,t){return r.filter(r.map(r.range(r.size(n)),function(r){return t(r,n[r])}),u)}})})(this),function(n){var r=n._||require("underscore"),t=Array.prototype.slice,e=Array.prototype.concat,u=function(n){return null!=n},i=function(n){return n!==!1&&u(n)},o=function(n){return r.isArray(n)||r.isArguments(n)};r.mixin({second:function(n,r,e){return null==n?void 0:null==r||e?n[1]:t.call(n,1,r)},nth:function(n,r){if(0>r||r>n.length-1)throw Error("Attempting to index outside the bounds of the array.");return n[r]},takeWhile:function(n,t){if(!o(n))throw new TypeError;for(var e=r.size(n),u=0;e>u&&i(t(n[u]));u++);return r.take(n,u)},dropWhile:function(n,t){if(!o(n))throw new TypeError;for(var e=r.size(n),u=0;e>u&&i(t(n[u]));u++);return r.drop(n,u)},splitWith:function(n,t){return[r.takeWhile(t,n),r.dropWhile(t,n)]},partitionBy:function(n,t){if(r.isEmpty(n)||!u(n))return[];var i=r.first(n),o=t(i),c=e.call([i],r.takeWhile(r.rest(n),function(n){return r.isEqual(o,t(n))}));return e.call([c],r.partitionBy(r.drop(n,r.size(c)),t))},best:function(n,t){return r.reduce(n,function(n,r){return t(n,r)?n:r})},keep:function(n,t){if(!o(n))throw new TypeError("expected an array as the first argument");return r.filter(r.map(n,function(n){return t(n)}),u)}})}(this),function(n){function r(n,r,t,o){var c=[];(function a(n,f,l){if(!r||r.call(o,n,f,l)!==u){if(e.isObject(n)||e.isArray(n)){if(c.indexOf(n)>=0)throw new TypeError(i);c.push(n),e.each(e.isElement(n)?n.children:n,a,o)}t&&t.call(o,n,f,l)}})(n)}function t(n,r,t){var i=[];return e.walk.preorder(n,function(n,e){return e!==r||(i[i.length]=n,t)?void 0:u}),i}var e=n._||require("underscore"),u={},i="Not a tree: same object found in two different branches";e.walk=r,e.extend(r,{postorder:function(n,t,e){r(n,null,t,e)},preorder:function(n,t,e){r(n,t,null,e)},map:function(n,r,t,e){var u=[];return r.call(null,n,function(n,r,i){u[u.length]=t.call(e,n,r,i)}),u},pluck:function(n,r){return t(n,r,!1)},pluckRec:function(n,r){return t(n,r,!0)}}),e.walk.collect=e.walk.map}(this),function(n){function r(n){return function(){if(1===arguments.length)return n.apply(this,arguments);throw new RangeError("Only a single argument may be accepted.")}}var t=n._||require("underscore"),e=function(){function n(t,e,u,i,o,c){return 1==c?i.unshift(o):i.push(o),i.length==u?t.apply(e,i):r(function(){return n(t,e,u,i.slice(0),arguments[0],c)})}return function(t,e){var u=this;return r(function(){return n(t,u,t.length,[],arguments[0],e)})}}(),u=function(){var n=[];return function(r){if("function"!=typeof r)throw Error("Argument 1 must be a function.");var t=r.length;return void 0===n[t]&&(n[t]=function(n){return function(){if(arguments.length!==t)throw new RangeError(t+" arguments must be applied.");return n.apply(this,arguments)}}),n[t](r)}}();t.mixin({fix:function(n){var r=t.rest(arguments),e=function(){for(var e=0,u=0;r.length>u&&arguments.length>e;u++)r[u]===t&&(r[u]=arguments[e++]);return n.apply(null,r)};return e._original=n,e},unary:function(n){return function(r){return n.call(this,r)}},binary:function(n){return function(r,t){return n.call(this,r,t)}},ternary:function(n){return function(r,t,e){return n.call(this,r,t,e)}},quaternary:function(n){return function(r,t,e,u){return n.call(this,r,t,e,u)}},curry:e,rCurry:function(n){return e.call(this,n,!0)},curry2:function(n){return r(function(t){return r(function(r){return n.call(this,t,r)})})},curry3:function(n){return r(function(t){return r(function(e){return r(function(r){return n.call(this,t,e,r)})})})},rcurry2:function(n){return r(function(t){return r(function(r){return n.call(this,r,t)})})},rcurry3:function(n){return r(function(t){return r(function(e){return r(function(r){return n.call(this,r,e,t)})})})},enforce:u}),t.arity=function(){var n={};return function r(t,e){if(null==n[t]){for(var u=Array(t),i=0;t>i;++i)u[i]="__"+i;var o=u.join(),c="return function ("+o+") { return fun.apply(this, arguments); };";n[t]=Function(["fun"],c)}return null==e?function(n){return r(t,n)}:n[t](e)}}()}(this),function(n){function r(n,r){return t.arity(n.length,function(){return n.apply(this,c.call(arguments,r))})}var t=n._||require("underscore"),e=function(n){return null!=n},u=function(n){return n!==!1&&e(n)},i=[].reverse,o=[].slice,c=[].map,a=function(n){return function(r,t){return 1===arguments.length?function(t){return n(r,t)}:n(r,t)}};t.mixin({always:function(n){return function(){return n}},pipeline:function(){var n=t.isArray(arguments[0])?arguments[0]:arguments;return function(r){return t.reduce(n,function(n,r){return r(n)},r)}},conjoin:function(){var n=arguments;return function(r){return t.every(r,function(r){return t.every(n,function(n){return n(r)})})}},disjoin:function(){var n=arguments;return function(r){return t.some(r,function(r){return t.some(n,function(n){return n(r)})})}},comparator:function(n){return function(r,t){return u(n(r,t))?-1:u(n(t,r))?1:0}},complement:function(n){return function(){return!n.apply(null,arguments)}},splat:function(n){return function(r){return n.apply(null,r)}},unsplat:function(n){var r=n.length;return 1>r?n:1===r?function(){return n.call(this,o.call(arguments,0))}:function(){var t=arguments.length,e=o.call(arguments,0,r-1),u=Math.max(r-t-1,0),i=Array(u),c=o.call(arguments,n.length-1);return n.apply(this,e.concat(i).concat([c]))}},unsplatl:function(n){var r=n.length;return 1>r?n:1===r?function(){return n.call(this,o.call(arguments,0))}:function(){var t=arguments.length,e=o.call(arguments,Math.max(t-r+1,0)),u=o.call(arguments,0,Math.max(t-r+1,0));return n.apply(this,[u].concat(e))}},mapArgs:a(r),juxt:function(){var n=arguments;return function(){var r=arguments;return t.map(n,function(n){return n.apply(null,r)})}},fnull:function(n){var r=t.rest(arguments);return function(){for(var u=t.toArray(arguments),i=t.size(r),o=0;i>o;o++)e(u[o])||(u[o]=r[o]);return n.apply(null,u)}},flip2:function(n){return function(){var r=arguments[0];return arguments[0]=arguments[1],arguments[1]=r,n.apply(null,arguments)}},flip:function(n){return function(){var r=i.call(arguments);return n.apply(null,r)}},k:t.always,t:t.pipeline}),t.unsplatr=t.unsplat,t.mapArgsWith=a(t.flip(r)),t.bound=function(n,r){var e=n[r];if(!t.isFunction(e))throw new TypeError("Expected property to be a function");return t.bind(e,n)}}(this),function(n){function r(n){return function(r){return n.call(this,r)}}function t(n,r,t){var e,u;for(e=t!==void 0?t:n(),u=n();null!=u;)e=r.call(u,e,u),u=n();return e}function e(n,r){var t=x;return function(){return t===x?t=n:null!=t?t=r.call(t,t):t}}function u(n,r){var t,e,u=n;return function(){return null!=u?(t=r.call(u,u),e=t[1],u=null!=e?t[0]:void 0,e):void 0}}function i(n,r,t){var e=t;return function(){return element=n(),null==element?element:e=e===void 0?element:r.call(element,e,element)}}function o(n,r,t){var e,u=t;return function(){return element=n(),null==element?element:u===void 0?u=element:(e=r.call(element,u,element),u=e[0],e[1])}}function c(n,r){return function(){var t;return t=n(),null!=t?r.call(t,t):void 0}}function a(n,r){return function(){var t;for(t=n();null!=t;){if(r.call(t,t))return t;t=n()}return void 0}}function f(n,r){return a(n,function(n){return!r(n)})}function l(n,r){return a(n,r)()}function s(n,r,t){for(var e=0;r-->0;)n();return null!=t?function(){return t>=++e?n():void 0}:n}function p(n,r){return s(n,null==r?1:r)}function m(n,r){return s(n,0,null==r?1:r)}function h(n){var r=0;return function(){return n[r++]}}function v(n){var r,t,e;return r=0,e=[],t=function(){var u,i;return u=n[r++],u instanceof Array?(e.push({array:n,index:r}),n=u,r=0,t()):u===void 0?e.length>0?(i=e.pop(),n=i.array,r=i.index,t()):void 0:u}}function g(n){return function(){return n}}function y(n,r,t){return function(){var e;return n>r?void 0:(e=n,n+=t,e)}}function d(n,r,t){return function(){var e;return r>n?void 0:(e=n,n-=t,e)}}function w(n,r,t){return null==n?y(1,1/0,1):null==r?y(n,1/0,1):null==t?r>=n?y(n,r,1):d(n,r,1):t>0?y(n,r,t):0>t?d(n,r,Math.abs(t)):k(n)}var A=n._||require("underscore"),x={},b=r(w);A.iterators={accumulate:i,accumulateWithReturn:o,foldl:t,reduce:t,unfold:e,unfoldWithReturn:u,map:c,select:a,reject:f,filter:a,find:l,slice:s,drop:p,take:m,List:h,Tree:v,constant:g,K:g,numbers:b,range:w}}(this),function(n){var r=n._||require("underscore");r.mixin({isInstanceOf:function(n,r){return n instanceof r},isAssociative:function(n){return r.isArray(n)||r.isObject(n)||r.isArguments(n)},isIndexed:function(n){return r.isArray(n)||r.isString(n)||r.isArguments(n)},isSequential:function(n){return r.isArray(n)||r.isArguments(n)},isZero:function(n){return 0===n},isEven:function(n){return r.isFinite(n)&&0===(1&n)},isOdd:function(n){return r.isFinite(n)&&!r.isEven(n)},isPositive:function(n){return n>0},isNegative:function(n){return 0>n},isValidDate:function(n){return r.isDate(n)&&!r.isNaN(n.getTime())},isNumeric:function(n){return!isNaN(parseFloat(n))&&isFinite(n)},isInteger:function(n){return r.isNumeric(n)&&0===n%1},isFloat:function(n){return r.isNumeric(n)&&!r.isInteger(n)},isIncreasing:function(){var n=r.size(arguments);if(1===n)return!0;if(2===n)return arguments[0]<arguments[1];for(var t=1;n>t;t++)if(arguments[t-1]>=arguments[t])return!1;return!0},isDecreasing:function(){var n=r.size(arguments);if(1===n)return!0;if(2===n)return arguments[0]>arguments[1];for(var t=1;n>t;t++)if(arguments[t-1]<=arguments[t])return!1;return!0}})}(this),function(n){var r=n._||require("underscore"),t=(Array.prototype.slice,Array.prototype.concat),e=function(n){return null!=n},u=function(n){return n!==!1&&e(n)},i=function(n){return r.isArray(n)||r.isObject(n)},o=function(n){return function(r){return function(t){return n(t,r)}}};r.mixin({merge:function(){var n=r.some(arguments)?{}:null;return u(n)&&r.extend.apply(null,t.call([n],r.toArray(arguments))),n},renameKeys:function(n,u){return r.reduce(u,function(r,t,u){return e(n[u])?(r[t]=n[u],r):r},r.omit.apply(null,t.call([n],r.keys(u))))},snapshot:function(n){if(null==n||"object"!=typeof n)return n;var t=new n.constructor;for(var e in n)t[e]=r.snapshot(n[e]);return t},updatePath:function(n,t,u){if(!i(n))throw new TypeError("Attempted to update a non-associative object.");if(!e(u))return t(n);var o=r.isArray(u),c=o?u:[u],a=o?r.snapshot(n):r.clone(n),f=r.last(c),l=a;return r.each(r.initial(c),function(n){l=l[n]}),l[f]=t(l[f]),a},setPath:function(n,t,u){if(!e(u))throw new TypeError("Attempted to set a property at a null path.");return r.updatePath(n,function(){return t},u)},frequencies:o(r.countBy)(r.identity)})}(this),function(n){var r=n._||require("underscore"),t=Array.prototype.concat;r.mixin({accessor:function(n){return function(r){return r&&r[n]}},dictionary:function(n){return function(r){return n&&r&&n[r]}},selectKeys:function(n,e){return r.pick.apply(null,t.call([n],e))},kv:function(n,t){return r.has(n,t)?[t,n[t]]:void 0},getPath:function e(n,t){return void 0===n?void 0:0===t.length?n:null===n?void 0:e(n[r.first(t)],r.rest(t))},hasPath:function u(n,t){var e=t.length;return null==n&&e>0?!1:t[0]in n?1===e?!0:u(n[r.first(t)],r.rest(t)):!1}})}(this),function(n){var r=n._||require("underscore");r.mixin({exists:function(n){return null!=n},truthy:function(n){return n!==!1&&r.exists(n)},falsey:function(n){return!r.truthy(n)},not:function(n){return!n}})}(this),function(n){var r=n._||require("underscore");r.mixin({add:function(n,r){return n+r},sub:function(n,r){return n-r},mul:function(n,r){return n*r},div:function(n,r){return n/r},mod:function(n,r){return n%r},inc:function(n){return++n},dec:function(n){return--n},neg:function(n){return-n},eq:function(n,r){return n==r},seq:function(n,r){return n===r},neq:function(n,r){return n!=r},sneq:function(n,r){return n!==r},not:function(n){return!n},gt:function(n,r){return n>r},lt:function(n,r){return r>n},gte:function(n,r){return n>=r},lte:function(n,r){return r>=n},bitwiseAnd:function(n,r){return n&r},bitwiseOr:function(n,r){return n|r},bitwiseXor:function(n,r){return n^r},bitwiseNot:function(n){return~n},bitwiseLeft:function(n,r){return n<<r},bitwiseRight:function(n,r){return n>>r},bitwiseZ:function(n,r){return n>>>r}})}(this),function(n){var r=n._||require("underscore");r.mixin({explode:function(n){return n.split("")},implode:function(n){return n.join("")}})}(this),function(n){var r=n._||require("underscore");r.mixin({done:function(n){var t=r(n);return t.stopTrampoline=!0,t},trampoline:function(n){for(var t=n.apply(n,r.rest(arguments));r.isFunction(t)&&(t=t(),!(t instanceof r&&t.stopTrampoline)););return t.value()}})}(this); |
module.exports = function(grunt) { | ||
grunt.loadNpmTasks("grunt-contrib-concat"); | ||
grunt.loadNpmTasks("grunt-contrib-uglify"); | ||
grunt.loadNpmTasks('grunt-contrib-qunit'); | ||
grunt.loadNpmTasks('grunt-contrib-watch'); | ||
grunt.loadNpmTasks('grunt-contrib-jshint'); | ||
grunt.loadNpmTasks("grunt-docco"); | ||
grunt.loadNpmTasks("grunt-tocdoc"); | ||
@@ -28,6 +33,64 @@ grunt.initConfig({ | ||
} | ||
}, | ||
qunit: { | ||
main: ['test/index.html'], | ||
concat: ['test/dist-concat.html'], | ||
min: ['test/dist-min.html'] | ||
}, | ||
jshint: { | ||
all: [ | ||
"*.js", | ||
"test/*.js" | ||
], | ||
options: { | ||
es3: true, // Enforce ES3 compatibility | ||
indent: 2, // Indent by 2 spaces | ||
camelcase: true, // All vars must be camelCase or UPPER_WITH_UNDERSCORES | ||
eqnull: true, // Allow 'x == null' convention | ||
forin: true, // Require `for x in y` to filter with `hasOwnProperty` | ||
newcap: true, // Require constructor names to be capitalized | ||
"-W058": false // Allow 'new Constructor' without parens | ||
} | ||
}, | ||
watch: { | ||
test: { | ||
files: [ | ||
"underscore.*.js", | ||
"test/*.js" | ||
], | ||
tasks: ["test"] | ||
} | ||
}, | ||
tocdoc: { | ||
api: { | ||
files: { | ||
'index.html': 'docs/*.md' | ||
} | ||
} | ||
}, | ||
docco: { | ||
docs: { | ||
src: ['docs/*.md'], | ||
options: { | ||
output: 'docs/' | ||
} | ||
}, | ||
examples: { | ||
src: ['examples/*.md'], | ||
options: { | ||
output: 'examples/' | ||
} | ||
} | ||
} | ||
}); | ||
grunt.registerTask("default", ["concat", "uglify"]); | ||
grunt.registerTask("test", ["jshint", "qunit:main"]); | ||
grunt.registerTask("dist", ["concat", "uglify"]); | ||
grunt.registerTask('default', ['test']); | ||
grunt.registerTask('dist', ['test', 'concat', 'qunit:concat', 'uglify', 'qunit:min']); | ||
}; |
@@ -6,2 +6,3 @@ require('./underscore.array.builders'); | ||
require('./underscore.function.combinators'); | ||
require('./underscore.function.dispatch'); | ||
require('./underscore.function.iterators'); | ||
@@ -8,0 +9,0 @@ require('./underscore.function.predicates'); |
{ | ||
"name": "underscore-contrib", | ||
"version": "0.1.4", | ||
"version": "0.2.1", | ||
"main": "index.js", | ||
@@ -9,5 +9,10 @@ "dependencies": { | ||
"devDependencies": { | ||
"grunt": "~0.4.0", | ||
"grunt": "~0.4.1", | ||
"grunt-contrib-concat": "0.3.0", | ||
"grunt-contrib-uglify": "0.2.0" | ||
"grunt-contrib-uglify": "0.2.0", | ||
"grunt-contrib-qunit": "~0.2.2", | ||
"grunt-contrib-watch": "~0.5.3", | ||
"grunt-contrib-jshint": "~0.6.4", | ||
"grunt-docco": "~0.3.0", | ||
"grunt-tocdoc": "~0.1.0" | ||
}, | ||
@@ -19,6 +24,8 @@ "repository": { | ||
"license": "MIT", | ||
"author": {"name": "Fogus", | ||
"email": "me@fogus.me", | ||
"url": "http://www.fogus.me"}, | ||
"author": { | ||
"name": "Fogus", | ||
"email": "me@fogus.me", | ||
"url": "http://www.fogus.me" | ||
}, | ||
"homepage": "https://github.com/documentcloud/underscore-contrib" | ||
} |
underscore-contrib | ||
================== | ||
The brass buckles on Underscore's utility belt - a contributor library for Underscore. | ||
The brass buckles on Underscore's utility belt -- a contributors' library for [Underscore](http://underscorejs.org/). | ||
Links | ||
----- | ||
* [Documentation](http://documentcloud.github.io/underscore-contrib/) | ||
* [Source repository](https://github.com/documentcloud/underscore-contrib) | ||
* [Tickets and bug reports](https://github.com/documentcloud/underscore-contrib/issues?state=open) | ||
* [Maintainer's website](http://www.fogus.me) | ||
Why underscore-contrib? | ||
----------------------- | ||
While Underscore provides a bevy of useful tools to support functional programming in JavaScript, it can't | ||
(and shouldn't) be everything to everyone. Underscore-contrib is intended as a home for functions that, for | ||
various reasons, don't belong in Underscore proper. In particular, it aims to be: | ||
* a home for functions that are limited in scope, but solve certain point problems, and | ||
* a proving ground for features that belong in Underscore proper, but need some advocacy and/or evolution | ||
(or devolution) to get them there. | ||
Use | ||
--- | ||
First, you’ll need Underscore. Then you can grab the relevant underscore-contrib libraries and simply add | ||
something | ||
like the following to your pages: | ||
<script type="text/javascript" src="underscore.js"></script> | ||
<script type="text/javascript" src="underscore.object.builders.js"></script> | ||
At the moment there are no cross-contrib dependencies (i.e. each library can stand by itself), but that may | ||
change in the future. | ||
Contributing | ||
------------ | ||
There is still a lot of work to do around perf, documentation, examples, testing and distribution so any help | ||
in those areas is welcomed. Pull requests are accepted, but please search the [issues](https://github.com/documentcloud/underscore-contrib/issues) | ||
before proposing a new sub-contrib or addition. Additionally, all patches and proposals should have strong | ||
documentation, motivating cases and tests. It would be nice if we could not only provide useful tools built on | ||
Underscore, but also provide an educational experience for why and how one might use them. | ||
Other (potentially) useful sub-contribs include the following: | ||
* String utilities | ||
* Date/time utilities | ||
* Validators | ||
* Iterators | ||
* Generators | ||
* Promises | ||
* Monads | ||
* Currying | ||
* Laziness | ||
* Multimethods | ||
What do these mean? Well, that’s up for discussion. :-) |
@@ -187,2 +187,15 @@ $(document).ready(function() { | ||
}); | ||
test('reverseOrder', function() { | ||
var arr = [1, 2, 3]; | ||
deepEqual(_.reverseOrder(arr), [3, 2, 1], 'returns an array whose elements are in the opposite order of the argument'); | ||
deepEqual(arr, [1, 2, 3], 'should not mutate the argument'); | ||
var throwingFn = function() { _.reverseOrder('string'); }; | ||
throws(throwingFn, TypeError, 'throws a TypeError when given a string'); | ||
var argObj = (function() { return arguments; })(1, 2, 3); | ||
deepEqual(_.reverseOrder(argObj), [3, 2, 1], 'works with other array-like objects'); | ||
}); | ||
}); |
@@ -9,4 +9,14 @@ $(document).ready(function() { | ||
equal(_.second(a), 2, 'should retrieve the 2nd element in an array'); | ||
deepEqual(_.second(a, 5), [2,3,4,5], 'should retrieve all but the first element in an array'); | ||
deepEqual(_.map([a,_.rest(a)], _.second), [2,3], 'should be usable in _.map'); | ||
}); | ||
test("third", function() { | ||
var a = [1,2,3,4,5]; | ||
equal(_.third(a), 3, 'should retrieve the 3rd element in an array'); | ||
deepEqual(_.third(a, 5), [3,4,5], 'should retrieve all but the first and second element in an array'); | ||
deepEqual(_.map([a,_.rest(a)], _.third), [3,4], 'should be usable in _.map'); | ||
}); | ||
test("takeWhile", function() { | ||
@@ -34,5 +44,5 @@ var isNeg = function(n) { return n < 0; }; | ||
deepEqual(_.splitWith(lessEq3p, a), [[1,2,3], [4,5]], 'should split an array when a function goes false'); | ||
deepEqual(_.splitWith(lessEq3p$, a), [[1,2,3], [4,5]], 'should split an array when a function goes false'); | ||
deepEqual(_.splitWith(lessEq3p$, []), [[],[]], 'should split an empty array into two empty arrays'); | ||
deepEqual(_.splitWith(a, lessEq3p), [[1,2,3], [4,5]], 'should split an array when a function goes false'); | ||
deepEqual(_.splitWith(a, lessEq3p$), [[1,2,3], [4,5]], 'should split an array when a function goes false'); | ||
deepEqual(_.splitWith([], lessEq3p$), [[],[]], 'should split an empty array into two empty arrays'); | ||
}); | ||
@@ -62,6 +72,9 @@ | ||
var a = ['a','b','c']; | ||
var b = [['a'],['b'],[]]; | ||
equal(_.nth(a,0), 'a', 'should return the element at a given index into an array'); | ||
equal(_.nth(a,100), undefined, 'should return undefined if out of bounds'); | ||
deepEqual(_.map(b,function(e) { return _.nth(e,0); }), ['a','b',undefined], 'should be usable in _.map'); | ||
}); | ||
}); | ||
@@ -9,3 +9,3 @@ $(document).ready(function() { | ||
l: { val: 1, l: { val: 2 }, r: { val: 3 } }, | ||
r: { val: 4, l: { val: 5 }, r: { val: 6 } }, | ||
r: { val: 4, l: { val: 5 }, r: { val: 6 } } | ||
}; | ||
@@ -20,3 +20,3 @@ }; | ||
{ city: 'San Francisco', aliases: ['SF', 'San Fran'], population: 812826 }, | ||
{ city: 'Toronto', aliases: ['TO', 'T-dot'], population: 2615000 }, | ||
{ city: 'Toronto', aliases: ['TO', 'T-dot'], population: 2615000 } | ||
] | ||
@@ -46,8 +46,8 @@ }; | ||
tree.l.l.r = tree; | ||
throws(function() { _.walk.preorder(tree, _.identity) }, TypeError, 'preorder throws an exception'); | ||
throws(function() { _.walk.postrder(tree, _.identity) }, TypeError, 'postorder throws an exception'); | ||
throws(function() { _.walk.preorder(tree, _.identity); }, TypeError, 'preorder throws an exception'); | ||
throws(function() { _.walk.postrder(tree, _.identity); }, TypeError, 'postorder throws an exception'); | ||
tree = getSimpleTestTree(); | ||
tree.r.l = tree.r; | ||
throws(function() { _.walk.preorder(tree, _.identity) }, TypeError, 'exception for a self-referencing node'); | ||
throws(function() { _.walk.preorder(tree, _.identity); }, TypeError, 'exception for a self-referencing node'); | ||
}); | ||
@@ -58,3 +58,3 @@ | ||
if (_.has(node, 'val')) return node.val; | ||
if (key !== 'val') throw Error('Leaf node with incorrect key'); | ||
if (key !== 'val') throw new Error('Leaf node with incorrect key'); | ||
return this.leafChar || '-'; | ||
@@ -125,2 +125,97 @@ }; | ||
}); | ||
test("reduce", function() { | ||
var add = function(a, b) { return a + b; }; | ||
var leafMemo = []; | ||
var sum = function(memo, node) { | ||
if (_.isObject(node)) | ||
return _.reduce(memo, add, 0); | ||
strictEqual(memo, leafMemo); | ||
return node; | ||
}; | ||
var tree = getSimpleTestTree(); | ||
equal(_.walk.reduce(tree, sum, leafMemo), 21); | ||
// A more useful example: transforming a tree. | ||
// Returns a new node where the left and right subtrees are swapped. | ||
var mirror = function(memo, node) { | ||
if (!_.has(node, 'r')) return node; | ||
return _.extend(_.clone(node), { l: memo.r, r: memo.l }); | ||
}; | ||
// Returns the '-' for internal nodes, and the value itself for leaves. | ||
var toString = function(node) { return _.has(node, 'val') ? '-' : node; }; | ||
tree = _.walk.reduce(getSimpleTestTree(), mirror); | ||
equal(_.walk.reduce(tree, sum, leafMemo), 21); | ||
equal(_.walk.map(tree, _.walk.preorder, toString).join(''), '-0-4-6-5-1-3-2', 'pre-order map'); | ||
}); | ||
test("find", function() { | ||
var tree = getSimpleTestTree(); | ||
// Returns a visitor function that will succeed when a node with the given | ||
// value is found, and then raise an exception the next time it's called. | ||
var findValue = function(value) { | ||
var found = false; | ||
return function(node) { | ||
if (found) throw 'already found!'; | ||
found = (node.val === value); | ||
return found; | ||
}; | ||
}; | ||
equal(_.walk.find(tree, findValue(0)).val, 0); | ||
equal(_.walk.find(tree, findValue(6)).val, 6); | ||
deepEqual(_.walk.find(tree, findValue(99)), undefined); | ||
}); | ||
test("filter", function() { | ||
var tree = getSimpleTestTree(); | ||
tree.r.val = '.oOo.'; // Remove one of the numbers. | ||
var isEvenNumber = function(x) { | ||
return _.isNumber(x) && x % 2 === 0; | ||
}; | ||
equal(_.walk.filter(tree, _.walk.preorder, _.isObject).length, 7, 'filter objects'); | ||
equal(_.walk.filter(tree, _.walk.preorder, _.isNumber).length, 6, 'filter numbers'); | ||
equal(_.walk.filter(tree, _.walk.postorder, _.isNumber).length, 6, 'postorder filter numbers'); | ||
equal(_.walk.filter(tree, _.walk.preorder, isEvenNumber).length, 3, 'filter even numbers'); | ||
// With the identity function, only the value '0' should be omitted. | ||
equal(_.walk.filter(tree, _.walk.preorder, _.identity).length, 13, 'filter on identity function'); | ||
}); | ||
test("reject", function() { | ||
var tree = getSimpleTestTree(); | ||
tree.r.val = '.oOo.'; // Remove one of the numbers. | ||
equal(_.walk.reject(tree, _.walk.preorder, _.isObject).length, 7, 'reject objects'); | ||
equal(_.walk.reject(tree, _.walk.preorder, _.isNumber).length, 8, 'reject numbers'); | ||
equal(_.walk.reject(tree, _.walk.postorder, _.isNumber).length, 8, 'postorder reject numbers'); | ||
// With the identity function, only the value '0' should be kept. | ||
equal(_.walk.reject(tree, _.walk.preorder, _.identity).length, 1, 'reject with identity function'); | ||
}); | ||
test("customTraversal", function() { | ||
var tree = getSimpleTestTree(); | ||
// Set up a walker that will not traverse the 'val' properties. | ||
var walker = _.walk(function(node) { | ||
return _.omit(node, 'val'); | ||
}); | ||
var visitor = function(node) { | ||
if (!_.isObject(node)) throw new Error("Leaf value visited when it shouldn't be"); | ||
}; | ||
equal(walker.pluck(tree, 'val').length, 7, 'pluck with custom traversal'); | ||
equal(walker.pluckRec(tree, 'val').length, 7, 'pluckRec with custom traversal'); | ||
equal(walker.map(tree, _.walk.postorder, _.identity).length, 7, 'traversal strategy is dynamically scoped'); | ||
// Check that the default walker is unaffected. | ||
equal(_.walk.map(tree, _.walk.postorder, _.identity).length, 14, 'default map still works'); | ||
equal(_.walk.pluckRec(tree, 'val').join(''), '0123456', 'default pluckRec still works'); | ||
}); | ||
}); |
@@ -8,8 +8,15 @@ $(document).ready(function() { | ||
var t = _.fix(over, 10, _, _); | ||
var m = _.fix(over, _, 5, _); | ||
var b = _.fix(over, _, _, 2); | ||
equal(t(5, 2), 1, 'should return a function partially applied for some number of arbitrary args marked by _'); | ||
equal(t(10, 2), 0.5, 'should return a function partially applied for some number of arbitrary args marked by _'); | ||
equal(t(10, 5), 0.2, 'should return a function partially applied for some number of arbitrary args marked by _'); | ||
equal(t(5,2), 1, 'should return a function partially applied for some number of arbitrary args marked by _'); | ||
equal(t(10,2), 1, 'should return a function partially applied for some number of arbitrary args marked by _'); | ||
equal(t(10,5), 1, 'should return a function partially applied for some number of arbitrary args marked by _'); | ||
var f = function () { | ||
return _.map(arguments, function (arg) { | ||
return typeof arg; | ||
}).join(', '); | ||
}; | ||
var g = _.fix(f, _, _, 3); | ||
equal(g(1), 'number, undefined, number', 'should fill "undefined" if argument not given'); | ||
g(1, 2); | ||
equal(g(1), 'number, undefined, number', 'should not remember arguments between calls'); | ||
@@ -39,3 +46,3 @@ equal(_.fix(parseInt, _, 10)('11'), 11, 'should "fix" common js foibles'); | ||
return fun.apply(this, reverse(arguments)); | ||
} | ||
}; | ||
} | ||
@@ -42,0 +49,0 @@ |
@@ -51,4 +51,3 @@ $(document).ready(function() { | ||
echo2 = _.unsplat(function (first, rest) { return [first, rest]; }), | ||
echo3 = _.unsplat(function (first, second, rest) { return [first, second, rest]; }), | ||
undefined = void 0; | ||
echo3 = _.unsplat(function (first, second, rest) { return [first, second, rest]; }); | ||
@@ -60,3 +59,3 @@ deepEqual(echo(), [], 'should return no arguments'); | ||
deepEqual(echo2(), [undefined, []], 'should return no arguments'); | ||
deepEqual(echo2(), [void 0, []], 'should return no arguments'); | ||
deepEqual(echo2(1), [1, []], 'should return the arguments provded'); | ||
@@ -67,4 +66,4 @@ deepEqual(echo2(1,2), [1,[2]], 'should return the arguments provded'); | ||
deepEqual(echo3(), [undefined, undefined, []], 'should return no arguments'); | ||
deepEqual(echo3(1), [1, undefined, []], 'should return the arguments provded'); | ||
deepEqual(echo3(), [void 0, void 0, []], 'should return no arguments'); | ||
deepEqual(echo3(1), [1, void 0, []], 'should return the arguments provded'); | ||
deepEqual(echo3(1,2), [1,2,[]], 'should return the arguments provded'); | ||
@@ -78,4 +77,3 @@ deepEqual(echo3(1,2,3), [1,2,[3]], 'should return the arguments provded'); | ||
echo2 = _.unsplatl(function (rest, ultimate) { return [rest, ultimate]; }), | ||
echo3 = _.unsplatl(function (rest, penultimate, ultimate) { return [rest, penultimate, ultimate]; }), | ||
undefined = void 0; | ||
echo3 = _.unsplatl(function (rest, penultimate, ultimate) { return [rest, penultimate, ultimate]; }); | ||
@@ -87,3 +85,3 @@ deepEqual(echo(), [], 'should return no arguments'); | ||
deepEqual(echo2(), [[], undefined], 'should return no arguments'); | ||
deepEqual(echo2(), [[], void 0], 'should return no arguments'); | ||
deepEqual(echo2(1), [[], 1], 'should return the arguments provded'); | ||
@@ -94,4 +92,4 @@ deepEqual(echo2(1,2), [[1], 2], 'should return the arguments provded'); | ||
deepEqual(echo3(), [[], undefined, undefined], 'should return no arguments'); | ||
deepEqual(echo3(1), [[], 1, undefined], 'should return the arguments provded'); | ||
deepEqual(echo3(), [[], void 0, void 0], 'should return no arguments'); | ||
deepEqual(echo3(1), [[], 1, void 0], 'should return the arguments provded'); | ||
deepEqual(echo3(1,2), [[], 1, 2], 'should return the arguments provded'); | ||
@@ -104,12 +102,12 @@ deepEqual(echo3(1,2,3), [[1], 2, 3], 'should return the arguments provded'); | ||
var echo = _.unsplatl(function (args) { return args; }); | ||
function double (n) { return n * 2; } | ||
function timesTwo (n) { return n * 2; } | ||
function plusOne (n) { return n + 1; } | ||
deepEqual(_.mapArgsWith(double, echo)(), [], "should handle the empty case") | ||
deepEqual(_.mapArgsWith(double, echo)(42), [84], "should handle one arg") | ||
deepEqual(_.mapArgsWith(plusOne, echo)(1, 2, 3), [2, 3, 4], "should handle many args") | ||
deepEqual(_.mapArgsWith(timesTwo, echo)(), [], "should handle the empty case"); | ||
deepEqual(_.mapArgsWith(timesTwo, echo)(42), [84], "should handle one arg"); | ||
deepEqual(_.mapArgsWith(plusOne, echo)(1, 2, 3), [2, 3, 4], "should handle many args"); | ||
deepEqual(_.mapArgsWith(double)(echo)(), [], "should handle the empty case") | ||
deepEqual(_.mapArgsWith(double)(echo)(42), [84], "should handle one arg") | ||
deepEqual(_.mapArgsWith(plusOne)(echo)(1, 2, 3), [2, 3, 4], "should handle many args") | ||
deepEqual(_.mapArgsWith(timesTwo)(echo)(), [], "should handle the empty case"); | ||
deepEqual(_.mapArgsWith(timesTwo)(echo)(42), [84], "should handle one arg"); | ||
deepEqual(_.mapArgsWith(plusOne)(echo)(1, 2, 3), [2, 3, 4], "should handle many args"); | ||
}); | ||
@@ -166,3 +164,2 @@ | ||
equal(f('there'), 'hello there', 'should return concatenation of obj.a and string argument'); | ||
equal(f.length, 1, 'f should have arity of 1'); | ||
throws(function() { | ||
@@ -172,2 +169,28 @@ _.bound(obj, 'nofun'); | ||
}); | ||
test("functionalize", function() { | ||
var rect = { | ||
x: 2, | ||
y: 3, | ||
area: function() {return this.x * this.y;}, | ||
extrude: function(z) {return _.merge(this, {z: z});} | ||
}; | ||
var areaFunc = _.functionalize(rect.area), | ||
extrudeFunc = _.functionalize(rect.extrude); | ||
equal(areaFunc(rect), 6, "returned function's first arg becomes original method's `this`"); | ||
equal(extrudeFunc(rect, 4).z, 4, "all arguments are passed along"); | ||
}); | ||
test("methodize", function() { | ||
function area(rect) {return rect.x * rect.y;} | ||
function extrude(rect, z) {return _.merge(rect, {z: z});} | ||
var rect = { | ||
x: 2, | ||
y: 3, | ||
area: _.methodize(area), | ||
extrude: _.methodize(extrude) | ||
}; | ||
equal(rect.area(), 6, "returned method passes its receiver (`this`) as first arg to original function"); | ||
equal(rect.extrude(4).z, 4, "all arguments are passed along"); | ||
}); | ||
}); |
$(document).ready(function() { | ||
var undefined = void 0; | ||
function sum (x, y) { return x + y; } | ||
function square (x) { return x * x; } | ||
function odd (x) { return x % 2 === 1; } | ||
function naturalSmallerThan (x) { return _.iterators.List(_.range(0, x)); } | ||
module("underscore.function.iterators"); | ||
@@ -18,15 +18,15 @@ | ||
equal(i(), 5, "should return the next element of the underlying array"); | ||
equal(i(), undefined, "should return undefined when out of elements"); | ||
equal(i(), void 0, "should return undefined when out of elements"); | ||
i = _.iterators.List([1, [2, 3, [4]], 5]) | ||
i = _.iterators.List([1, [2, 3, [4]], 5]); | ||
equal(i(), 1, "should return the first element of the underlying array"); | ||
notEqual(i(), 2, "should not do a deep traverse"); | ||
equal(i(), 5, "should return the next element of the underlying array"); | ||
equal(i(), undefined, "should return undefined when out of elements"); | ||
equal(i(), void 0, "should return undefined when out of elements"); | ||
i = _.iterators.List([]) | ||
equal(i(), undefined, "should return undefined when there are no elements"); | ||
i = _.iterators.List([]); | ||
equal(i(), void 0, "should return undefined when there are no elements"); | ||
i = _.iterators.List([[], [[]]]) | ||
notEqual(i(), undefined, "should have a values given an empty tree"); | ||
i = _.iterators.List([[], [[]]]); | ||
notEqual(i(), void 0, "should have a values given an empty tree"); | ||
}); | ||
@@ -36,6 +36,6 @@ | ||
var i = _.iterators.Tree([]); | ||
equal(i(), undefined, "should return undefined for an empty array"); | ||
equal(i(), void 0, "should return undefined for an empty array"); | ||
i = _.iterators.Tree([[], [[]]]); | ||
equal(i(), undefined, "should return undefined for an empty tree"); | ||
equal(i(), void 0, "should return undefined for an empty tree"); | ||
@@ -48,3 +48,3 @@ i = _.iterators.Tree([1, 2, 3, 4, 5]); | ||
equal(i(), 5, "should return the next element of the underlying array"); | ||
equal(i(), undefined, "should return undefined when out of elements"); | ||
equal(i(), void 0, "should return undefined when out of elements"); | ||
@@ -57,3 +57,3 @@ i = _.iterators.Tree([1, [2, 3, [4]], 5]); | ||
equal(i(), 5, "should return the next element of the underlying array"); | ||
equal(i(), undefined, "should return undefined when out of elements"); | ||
equal(i(), void 0, "should return undefined when out of elements"); | ||
}); | ||
@@ -71,9 +71,9 @@ | ||
equal( _.iterators.reduce(_.iterators.Tree([[[4], []]]), sum), 4, "should fold an array with one element");; | ||
equal( _.iterators.reduce(_.iterators.Tree([[[4], []]]), sum), 4, "should fold an array with one element"); | ||
equal( _.iterators.reduce(_.iterators.Tree([[[], []]]), sum), undefined, "should fold an array with no elements"); | ||
equal( _.iterators.reduce(_.iterators.Tree([[[], []]]), sum), void 0, "should fold an array with no elements"); | ||
}); | ||
test("Accumulate", function () { | ||
var i = _.iterators.accumulate(_.iterators.Tree([1, [2, 3, [4]], 5]), sum, 0) | ||
var i = _.iterators.accumulate(_.iterators.Tree([1, [2, 3, [4]], 5]), sum, 0); | ||
equal(i(), 1, "should map an iterator with many elements"); | ||
@@ -84,10 +84,10 @@ equal(i(), 3, "should map an iterator with many elements"); | ||
equal(i(), 15, "should map an iterator with many elements"); | ||
equal(i(), undefined); | ||
equal(i(), void 0); | ||
i = _.iterators.accumulate(_.iterators.Tree([[[4], []]]), sum, 42); | ||
equal(i(), 46, "should map an iterator with one element"); | ||
equal(i(), undefined) | ||
equal(i(), void 0); | ||
i = _.iterators.accumulate(_.iterators.Tree([[[], []]]), sum, 42); | ||
equal(i(), undefined, "should map an empty iterator"); | ||
equal(i(), void 0, "should map an empty iterator"); | ||
@@ -100,10 +100,10 @@ i = _.iterators.accumulate(_.iterators.Tree([1, [2, 3, [4]], 5]), sum); | ||
equal(i(), 15, "should map an iterator with many elements"); | ||
equal(i(), undefined); | ||
equal(i(), void 0); | ||
i = _.iterators.accumulate(_.iterators.Tree([[[4], []]]), sum); | ||
equal(i(), 4, "should map an iterator with one element"); | ||
equal(i(), undefined); | ||
equal(i(), void 0); | ||
i = _.iterators.accumulate(_.iterators.Tree([[[], []]]), sum); | ||
equal(i(), undefined); | ||
equal(i(), void 0); | ||
@@ -115,16 +115,31 @@ }); | ||
equal(i(), 1, "should map an iterator with many elements"); | ||
equal(i(), 4), "should map an iterator with many elements"; | ||
equal(i(), 4, "should map an iterator with many elements"); | ||
equal(i(), 9, "should map an iterator with many elements"); | ||
equal(i(), 16, "should map an iterator with many elements"); | ||
equal(i(), 25, "should map an iterator with many elements"); | ||
equal(i(), undefined); | ||
equal(i(), void 0); | ||
i = _.iterators.map(_.iterators.Tree([[[4], []]]), square); | ||
equal(i(), 16, "should map an iterator with one element"); | ||
equal(i(), undefined); | ||
equal(i(), void 0); | ||
i = _.iterators.map(_.iterators.Tree([[[], []]]), square); | ||
equal(i(), undefined, "should map an empty iterator"); | ||
equal(i(), void 0, "should map an empty iterator"); | ||
}); | ||
test("mapcat", function () { | ||
var i = _.iterators.mapcat(_.iterators.Tree([1, [2]]), naturalSmallerThan); | ||
equal(i(), 0, "should mapcat an iterator with many elements"); | ||
equal(i(), 0, "should mapcat an iterator with many elements"); | ||
equal(i(), 1, "should mapcat an iterator with many elements"); | ||
equal(i(), void 0); | ||
i = _.iterators.mapcat(_.iterators.Tree([[[1], []]]), naturalSmallerThan); | ||
equal(i(), 0, "should mapcat an iterator with one element"); | ||
equal(i(), void 0); | ||
i = _.iterators.mapcat(_.iterators.Tree([[[], []]]), naturalSmallerThan); | ||
equal(i(), void 0, "should mapcat an empty iterator"); | ||
}); | ||
test("filter", function() { | ||
@@ -135,12 +150,12 @@ var i = _.iterators.filter(_.iterators.Tree([1, [2, 3, [4]], 5]), odd); | ||
equal(i(),5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
i = _.iterators.filter(_.iterators.Tree([[[4], []]]), odd); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
i = _.iterators.filter(_.iterators.Tree([[[], []]]), odd); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
i = _.iterators.filter(_.iterators.List([2, 4, 6, 8, 10]), odd); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -159,3 +174,3 @@ | ||
equal(i(),5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -168,7 +183,7 @@ test("should return a trailing iterator", function() { | ||
equal(i(),5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
test("should return an empty iterator when out of range", function() { | ||
var i = _.iterators.slice(_.iterators.List([1, 2, 3, 4, 5]), 5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -185,3 +200,3 @@ }); | ||
equal(i(),5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
i = _.iterators.slice(_.iterators.List([1, 2, 3, 4, 5]), 0, 99); | ||
@@ -193,3 +208,3 @@ equal(i(),1); | ||
equal(i(),5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -202,3 +217,3 @@ test("should return a leading iterator", function() { | ||
equal(i(),4); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -211,3 +226,3 @@ test("should return a trailing iterator", function() { | ||
equal(i(),5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
i = _.iterators.slice(_.iterators.List([1, 2, 3, 4, 5]), 1, 99); | ||
@@ -218,3 +233,3 @@ equal(i(),2); | ||
equal(i(),5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -226,11 +241,11 @@ test("should return an inner iterator", function() { | ||
equal(i(),4); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
test("should return an empty iterator when given a zero length", function() { | ||
var i = _.iterators.slice(_.iterators.List([1, 2, 3, 4, 5]), 1, 0); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
test("should return an empty iterator when out of range", function() { | ||
var i = _.iterators.slice(_.iterators.List([1, 2, 3, 4, 5]), 5, 1); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -247,7 +262,7 @@ }); | ||
equal(i(),5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
test("should handle overdropping", function() { | ||
var i = _.iterators.drop(_.iterators.List([1, 2, 3, 4, 5]), 99); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -261,3 +276,3 @@ test("should handle underdropping", function() { | ||
equal(i(),5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -270,3 +285,3 @@ test("should default to one", function() { | ||
equal(i(),5); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -300,9 +315,9 @@ }); | ||
test("should not unfold without a seed", function() { | ||
var i = _.iterators.unfold(undefined, function(n) { | ||
var i = _.iterators.unfold(void 0, function(n) { | ||
return n + 1; | ||
}); | ||
equal(i(),undefined); | ||
equal(i(),undefined); | ||
equal(i(),undefined); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
equal(i(),void 0); | ||
equal(i(),void 0); | ||
equal(i(),void 0); | ||
}); | ||
@@ -324,12 +339,12 @@ }); | ||
var i = _.iterators.unfoldWithReturn(1, function(n) { | ||
return [n + 1, n === 1 ? undefined : n * n]; | ||
return [n + 1, n === 1 ? void 0 : n * n]; | ||
}); | ||
equal(i(),undefined); | ||
equal(i(),undefined); | ||
equal(i(),undefined); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
equal(i(),void 0); | ||
equal(i(),void 0); | ||
equal(i(),void 0); | ||
}); | ||
test("should halt if the state becomes undefined", function() { | ||
var i = _.iterators.unfoldWithReturn(1, function(n) { | ||
return [(n === 3 ? undefined : n + 1), (n === undefined ? 100 : n * n)]; | ||
return [(n === 3 ? void 0 : n + 1), (n === void 0 ? 100 : n * n)]; | ||
}); | ||
@@ -339,3 +354,3 @@ equal(i(),1); | ||
equal(i(),9); | ||
equal(i(),undefined); | ||
equal(i(),void 0); | ||
}); | ||
@@ -342,0 +357,0 @@ }); |
@@ -64,2 +64,24 @@ $(document).ready(function() { | ||
test("isPlainObject", function() { | ||
function SomeConstructor() {} | ||
equal(_.isPlainObject({}), true, 'should identify empty objects'); | ||
equal(_.isPlainObject({a: 1, b: 2}), true, 'should identify objects'); | ||
equal(_.isPlainObject(Object.create(null)), false, 'should reject objects with no prototype'); | ||
equal(_.isPlainObject(new SomeConstructor), false, 'should reject instances constructed by something other than Object'); | ||
equal(_.isPlainObject([]), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject(function(){}), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject(null), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject(1), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject(0), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject(-1), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject(3.14), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject('undefined'), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject(''), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject(NaN), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject(Infinity), false, 'should identify when something is not a plain object'); | ||
equal(_.isPlainObject(true), false, 'should identify when something is not a plain object'); | ||
}); | ||
test("isEven", function() { | ||
@@ -147,3 +169,3 @@ equal(_.isEven(0), true, 'should identify even numbers'); | ||
equal(_.isNumeric(new Date(2009,1,1)), false, "should identify Date object"); | ||
equal(_.isNumeric(new Object()), false, "should identify Empty object"); | ||
equal(_.isNumeric({}), false, "should identify Empty object"); | ||
equal(_.isNumeric(function(){}), false, "should identify Instance of a function"); | ||
@@ -153,3 +175,3 @@ }); | ||
test("isInteger and isFloat", function() { | ||
var integer_checks = [ | ||
var integerChecks = [ | ||
{value: "-10", message: "should identify Negative integer string"}, | ||
@@ -169,3 +191,3 @@ {value: "0", message: "should identify Zero string"}, | ||
var float_checks = [ | ||
var floatChecks = [ | ||
{value: "-1.6", message: "should identify Negative floating point string"}, | ||
@@ -179,3 +201,3 @@ {value: "4.536", message: "should identify Positive floating point string"}, | ||
var negative_checks = [ | ||
var negativeChecks = [ | ||
{value: "abc", message: "should identify non-numeric strings"}, | ||
@@ -188,3 +210,3 @@ {value: undefined, message: "should identify undefined"}, | ||
var test_multiple = function(cases, fn, result){ | ||
var testMultiple = function(cases, fn, result){ | ||
for (var i = 0; i < cases.length; i++) { | ||
@@ -195,9 +217,9 @@ equal(fn(cases[i].value), result, cases[i].message); | ||
test_multiple(integer_checks, _.isInteger, true); | ||
test_multiple(float_checks, _.isInteger, false); | ||
test_multiple(negative_checks, _.isInteger, false); | ||
testMultiple(integerChecks, _.isInteger, true); | ||
testMultiple(floatChecks, _.isInteger, false); | ||
testMultiple(negativeChecks, _.isInteger, false); | ||
test_multiple(integer_checks, _.isFloat, false); | ||
test_multiple(float_checks, _.isFloat, true); | ||
test_multiple(negative_checks, _.isFloat, false); | ||
testMultiple(integerChecks, _.isFloat, false); | ||
testMultiple(floatChecks, _.isFloat, true); | ||
testMultiple(negativeChecks, _.isFloat, false); | ||
}); | ||
@@ -204,0 +226,0 @@ |
@@ -0,0 +0,0 @@ $(document).ready(function() { |
@@ -44,2 +44,4 @@ $(document).ready(function() { | ||
strictEqual(_.getPath(deepObject, ["nullVal", "notHere", "notHereEither"]), undefined, "should return undefined for non-existent descendents of null properties"); | ||
strictEqual(_.getPath(deepObject, "a.b.c"), "c", "should work with keys written in dot notation"); | ||
}); | ||
@@ -63,4 +65,17 @@ | ||
strictEqual(_.hasPath(deepObject, ["undefinedVal", "notHere"]), false, "should return false for descendants of undefined properties"); | ||
strictEqual(_.hasPath(deepObject, "a.b.c"), true, "should work with keys written in dot notation."); | ||
}); | ||
test("pickWhen", function() { | ||
var a = {foo: true, bar: false, baz: 42}; | ||
deepEqual(_.pickWhen(a, _.truthy), {foo: true, baz: 42}, "should return an object with kvs that return a truthy value for the given predicate"); | ||
}); | ||
test("omitWhen", function() { | ||
var a = {foo: [], bar: "", baz: "something", quux: ['a']}; | ||
deepEqual(_.omitWhen(a, _.isEmpty), {baz: "something", quux: ['a']}, "should return an object with kvs that return a falsey value for the given predicate"); | ||
}); | ||
}); |
@@ -56,2 +56,9 @@ $(document).ready(function() { | ||
test('firstExisting', function() { | ||
equal(_.firstExisting('first', 'second'), 'first', 'should return the first existing value'); | ||
equal(_.firstExisting(null, 'second'), 'second', 'should ignore null'); | ||
equal(_.firstExisting(void 0, 'second'), 'second', 'should ignore undefined'); | ||
equal(_.firstExisting(null, void 0, 'third'), 'third', 'should work with more arguments'); | ||
}); | ||
}); |
$(document).ready(function() { | ||
module("underscore.util.existential"); | ||
module("underscore.util.operators"); | ||
@@ -8,2 +8,3 @@ test("add", function() { | ||
equal(_.add(3, 5), 8, '3 + 5 = 8'); | ||
equal(_.add(1, 2, 3, 4), 10, 'adds multiple operands'); | ||
}); | ||
@@ -14,2 +15,3 @@ | ||
equal(_.sub(5, 3), 2, '5 - 3 = 2'); | ||
equal(_.sub(10, 9, 8, 7), -14, 'subtracts multiple operands'); | ||
}); | ||
@@ -20,2 +22,3 @@ | ||
equal(_.mul(5, 3), 15, '5 * 3 = 15'); | ||
equal(_.mul(1, 2, 3, 4), 24, 'multiplies multiple operands'); | ||
}); | ||
@@ -27,2 +30,3 @@ | ||
equal(_.div(15, 0), Infinity, '15 / 0 = Infinity'); | ||
equal(_.div(24, 2, 2, 2), 3, 'divides multiple operands'); | ||
}); | ||
@@ -62,14 +66,24 @@ | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.eq(0, 0, 1), false, 'compares a list of arguments'); | ||
}); | ||
test("seq", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.seq(1, 1), true, '1 === 1'); | ||
equal(_.seq(1, '1'), false, '1 !== "1"'); | ||
equal(_.seq(0, 0, 1), false, 'compares a list of arguments'); | ||
}); | ||
test("neq", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.neq('a', 'b'), true, '"a" != "b"'); | ||
equal(_.neq(1, '1'), false, '1 == "1"'); | ||
equal(_.neq(0, 0, 1), true, 'compares a list of arguments'); | ||
}); | ||
test("sneq", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.sneq('a', 'b'), true, '"a" !== "b"'); | ||
equal(_.sneq(1, '1'), true, '1 !== "1"'); | ||
equal(_.sneq(0, 0, 1), true, 'compares a list of arguments'); | ||
}); | ||
test("not", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.not(true), false, 'converts true to false'); | ||
equal(_.not(false), true, 'converts false to true'); | ||
equal(_.not('truthy'), false, 'converts truthy values to false'); | ||
equal(_.not(null), true, 'converts falsy values to true'); | ||
}); | ||
@@ -79,2 +93,3 @@ test("gt", function() { | ||
equal(_.gt(1, 3), false, '1 > 3'); | ||
equal(_.gt(1, 2, 1), false, 'compares a list of arguments'); | ||
}); | ||
@@ -84,2 +99,3 @@ test("lt", function() { | ||
equal(_.lt(1, 3), true, '1 < 3'); | ||
equal(_.lt(1, 2, 1), false, 'compares a list of arguments'); | ||
}); | ||
@@ -90,2 +106,3 @@ test("gte", function() { | ||
equal(_.gte(3, 3), true, '3 >= 3'); | ||
equal(_.gte(2, 3, 1), false, 'compares a list of arguments'); | ||
}); | ||
@@ -96,25 +113,38 @@ test("lte", function() { | ||
equal(_.lte(3, 3), true, '3 <= 3'); | ||
equal(_.lte(2, 2, 1), false, 'compares a list of arguments'); | ||
}); | ||
test("bitwiseAnd", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.bitwiseAnd(1, 1), 1, '1 & 1'); | ||
equal(_.bitwiseAnd(1, 0), 0, '1 & 0'); | ||
equal(_.bitwiseAnd(1, 1, 0), 0, 'operates on multiple arguments'); | ||
}); | ||
test("bitwiseOr", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.bitwiseOr(1, 1), 1, '1 | 1'); | ||
equal(_.bitwiseOr(1, 0), 1, '1 | 0'); | ||
equal(_.bitwiseOr(1, 1, 2), 3, 'operates on multiple arguments'); | ||
}); | ||
test("bitwiseXor", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.bitwiseXor(1, 1), 0, '1 ^ 1'); | ||
equal(_.bitwiseXor(1, 2), 3, '1 ^ 2'); | ||
equal(_.bitwiseXor(1, 2, 3), 0, 'operates on multiple arguments'); | ||
}); | ||
test("bitwiseNot", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.bitwiseNot(1), -2, '~1'); | ||
equal(_.bitwiseNot(2), -3, '~2'); | ||
}); | ||
test("bitwiseLeft", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.bitwiseLeft(1, 1), 2, '1 << 1'); | ||
equal(_.bitwiseLeft(1, 0), 1, '1 << 0'); | ||
equal(_.bitwiseLeft(1, 1, 1), 4, 'operates on multiple arguments'); | ||
}); | ||
test("bitwiseRight", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.bitwiseRight(1, 1), 0, '1 >> 1'); | ||
equal(_.bitwiseRight(2, 1), 1, '2 >> 1'); | ||
equal(_.bitwiseRight(3, 1, 1), 0, 'operates on multiple arguments'); | ||
}); | ||
test("bitwiseZ", function() { | ||
equal(false, false, 'failing placeholder'); | ||
equal(_.bitwiseZ(-1, 1), 2147483647, '-1 >>> 1'); | ||
equal(_.bitwiseZ(-1, 1, 1), 1073741823, 'operates on multiple arguments'); | ||
}); | ||
}); |
@@ -7,13 +7,13 @@ $(document).ready(function() { | ||
var oddOline = function(n) { | ||
if (n === 0) | ||
return _.done(false); | ||
else | ||
return _.partial(evenOline, Math.abs(n) - 1); | ||
if (n === 0) | ||
return _.done(false); | ||
else | ||
return _.partial(evenOline, Math.abs(n) - 1); | ||
}; | ||
var evenOline = function(n) { | ||
if (n === 0) | ||
return _.done(true); | ||
else | ||
return _.partial(oddOline, Math.abs(n) - 1); | ||
if (n === 0) | ||
return _.done(true); | ||
else | ||
return _.partial(oddOline, Math.abs(n) - 1); | ||
}; | ||
@@ -20,0 +20,0 @@ |
@@ -0,0 +0,0 @@ // JSLitmus.js |
@@ -0,0 +0,0 @@ /** |
@@ -0,0 +0,0 @@ /* |
@@ -0,0 +0,0 @@ // Underscore.js 1.4.4 |
@@ -105,2 +105,3 @@ // Underscore-contrib (underscore.array.builders.js 0.0.1) | ||
if (!_.some(arguments)) return []; | ||
if (arguments.length == 1) return arguments[0]; | ||
@@ -182,2 +183,14 @@ return _.filter(_.flatten(_.zip.apply(null, arguments), true), function(elem) { | ||
existy); | ||
}, | ||
// Accepts an array-like object (other than strings) as an argument and | ||
// returns an array whose elements are in the reverse order. Unlike the | ||
// built-in `Array.prototype.reverse` method, this does not mutate the | ||
// original object. Note: attempting to use this method on a string will | ||
// result in a `TypeError`, as it cannot properly reverse unicode strings. | ||
reverseOrder: function(obj) { | ||
if (typeof obj == 'string') | ||
throw new TypeError('Strings cannot be reversed by _.reverseOrder'); | ||
return slice.call(obj).reverse(); | ||
} | ||
@@ -184,0 +197,0 @@ }); |
@@ -36,7 +36,13 @@ // Underscore-contrib (underscore.array.selectors.js 0.0.1) | ||
// Returns the third element of an array. Passing **n** will return all but | ||
// the first two of the head N values in the array. The **guard** check allows it | ||
// to work with `_.map`. | ||
third: function(array, n, guard) { | ||
if (array == null) return void 0; | ||
return (n != null) && !guard ? slice.call(array, 2, n) : array[2]; | ||
}, | ||
// A function to get at an index into an array | ||
nth: function(array, index) { | ||
if ((index < 0) || (index > array.length - 1)) throw Error("Attempting to index outside the bounds of the array."); | ||
return array[index]; | ||
nth: function(array, index, guard) { | ||
if ((index != null) && !guard) return array[index]; | ||
}, | ||
@@ -77,3 +83,3 @@ | ||
splitWith: function(array, pred) { | ||
return [_.takeWhile(pred, array), _.dropWhile(pred, array)]; | ||
return [_.takeWhile(array, pred), _.dropWhile(array, pred)]; | ||
}, | ||
@@ -80,0 +86,0 @@ |
@@ -18,36 +18,62 @@ // Underscore-contrib (underscore.collections.walk.js 0.0.1) | ||
// prevent a top-down walk from walking subtrees of a node. | ||
var breaker = {}; | ||
var stopRecursion = {}; | ||
// An internal object that can be returned from a visitor function to | ||
// cause the walk to immediately stop. | ||
var stopWalk = {}; | ||
var notTreeError = 'Not a tree: same object found in two different branches'; | ||
// Implements the default traversal strategy: if `obj` is a DOM node, walk | ||
// its DOM children; otherwise, walk all the objects it references. | ||
function defaultTraversal(obj) { | ||
return _.isElement(obj) ? obj.children : obj; | ||
} | ||
// Walk the tree recursively beginning with `root`, calling `beforeFunc` | ||
// before visiting an objects descendents, and `afterFunc` afterwards. | ||
function walk(root, beforeFunc, afterFunc, context) { | ||
// If `collectResults` is true, the last argument to `afterFunc` will be a | ||
// collection of the results of walking the node's subtrees. | ||
function walkImpl(root, traversalStrategy, beforeFunc, afterFunc, context, collectResults) { | ||
var visited = []; | ||
(function _walk(value, key, parent) { | ||
if (beforeFunc && beforeFunc.call(context, value, key, parent) === breaker) | ||
return; | ||
if (_.isObject(value) || _.isArray(value)) { | ||
// Keep track of objects that have been visited, and throw an exception | ||
// when trying to visit the same object twice. | ||
return (function _walk(value, key, parent) { | ||
// Keep track of objects that have been visited, and throw an exception | ||
// when trying to visit the same object twice. | ||
if (_.isObject(value)) { | ||
if (visited.indexOf(value) >= 0) throw new TypeError(notTreeError); | ||
visited.push(value); | ||
} | ||
// Recursively walk this object's descendents. If it's a DOM node, walk | ||
// its DOM children. | ||
_.each(_.isElement(value) ? value.children : value, _walk, context); | ||
if (beforeFunc) { | ||
var result = beforeFunc.call(context, value, key, parent); | ||
if (result === stopWalk) return stopWalk; | ||
if (result === stopRecursion) return; | ||
} | ||
if (afterFunc) afterFunc.call(context, value, key, parent); | ||
var subResults; | ||
var target = traversalStrategy(value); | ||
if (_.isObject(target) && !_.isEmpty(target)) { | ||
// If collecting results from subtrees, collect them in the same shape | ||
// as the parent node. | ||
if (collectResults) subResults = _.isArray(value) ? [] : {}; | ||
var stop = _.any(target, function(obj, key) { | ||
var result = _walk(obj, key, value); | ||
if (result === stopWalk) return true; | ||
if (subResults) subResults[key] = result; | ||
}); | ||
if (stop) return stopWalk; | ||
} | ||
if (afterFunc) return afterFunc.call(context, value, key, parent, subResults); | ||
})(root); | ||
} | ||
// Internal helper providing the implementation for `pluck` and `pluckRec`. | ||
function pluck(obj, propertyName, recursive) { | ||
var results = []; | ||
_.walk.preorder(obj, function(value, key) { | ||
if (key === propertyName) { | ||
results[results.length] = value; | ||
if (!recursive) return breaker; | ||
} | ||
this.preorder(obj, function(value, key) { | ||
if (!recursive && key == propertyName) | ||
return stopRecursion; | ||
if (_.has(value, propertyName)) | ||
results[results.length] = value[propertyName]; | ||
}); | ||
@@ -57,17 +83,34 @@ return results; | ||
// Add the `walk` namespace | ||
// ------------------------ | ||
var exports = { | ||
// Performs a preorder traversal of `obj` and returns the first value | ||
// which passes a truth test. | ||
find: function(obj, visitor, context) { | ||
var result; | ||
this.preorder(obj, function(value, key, parent) { | ||
if (visitor.call(context, value, key, parent)) { | ||
result = value; | ||
return stopWalk; | ||
} | ||
}, context); | ||
return result; | ||
}, | ||
_.walk = walk; | ||
_.extend(walk, { | ||
// Recursively traverses `obj` in a depth-first fashion, invoking the | ||
// `visitor` function for each object only after traversing its children. | ||
postorder: function(obj, visitor, context) { | ||
walk(obj, null, visitor, context); | ||
// Recursively traverses `obj` and returns all the elements that pass a | ||
// truth test. `strategy` is the traversal function to use, e.g. `preorder` | ||
// or `postorder`. | ||
filter: function(obj, strategy, visitor, context) { | ||
var results = []; | ||
if (obj == null) return results; | ||
strategy(obj, function(value, key, parent) { | ||
if (visitor.call(context, value, key, parent)) results.push(value); | ||
}, null, this._traversalStrategy); | ||
return results; | ||
}, | ||
// Recursively traverses `obj` in a depth-first fashion, invoking the | ||
// `visitor` function for each object before traversing its children. | ||
preorder: function(obj, visitor, context) { | ||
walk(obj, visitor, null, context) | ||
// Recursively traverses `obj` and returns all the elements for which a | ||
// truth test fails. | ||
reject: function(obj, strategy, visitor, context) { | ||
return this.filter(obj, strategy, function(value, key, parent) { | ||
return !visitor.call(context, value, key, parent); | ||
}); | ||
}, | ||
@@ -81,5 +124,5 @@ | ||
var results = []; | ||
strategy.call(null, obj, function(value, key, parent) { | ||
strategy(obj, function(value, key, parent) { | ||
results[results.length] = visitor.call(context, value, key, parent); | ||
}); | ||
}, null, this._traversalStrategy); | ||
return results; | ||
@@ -92,3 +135,3 @@ }, | ||
pluck: function(obj, propertyName) { | ||
return pluck(obj, propertyName, false); | ||
return pluck.call(this, obj, propertyName, false); | ||
}, | ||
@@ -99,6 +142,60 @@ | ||
pluckRec: function(obj, propertyName) { | ||
return pluck(obj, propertyName, true); | ||
return pluck.call(this, obj, propertyName, true); | ||
}, | ||
// Recursively traverses `obj` in a depth-first fashion, invoking the | ||
// `visitor` function for each object only after traversing its children. | ||
// `traversalStrategy` is intended for internal callers, and is not part | ||
// of the public API. | ||
postorder: function(obj, visitor, context, traversalStrategy) { | ||
traversalStrategy = traversalStrategy || this._traversalStrategy; | ||
walkImpl(obj, traversalStrategy, null, visitor, context); | ||
}, | ||
// Recursively traverses `obj` in a depth-first fashion, invoking the | ||
// `visitor` function for each object before traversing its children. | ||
// `traversalStrategy` is intended for internal callers, and is not part | ||
// of the public API. | ||
preorder: function(obj, visitor, context, traversalStrategy) { | ||
traversalStrategy = traversalStrategy || this._traversalStrategy; | ||
walkImpl(obj, traversalStrategy, visitor, null, context); | ||
}, | ||
// Builds up a single value by doing a post-order traversal of `obj` and | ||
// calling the `visitor` function on each object in the tree. For leaf | ||
// objects, the `memo` argument to `visitor` is the value of the `leafMemo` | ||
// argument to `reduce`. For non-leaf objects, `memo` is a collection of | ||
// the results of calling `reduce` on the object's children. | ||
reduce: function(obj, visitor, leafMemo, context) { | ||
var reducer = function(value, key, parent, subResults) { | ||
return visitor(subResults || leafMemo, value, key, parent); | ||
}; | ||
return walkImpl(obj, this._traversalStrategy, null, reducer, context, true); | ||
} | ||
}); | ||
_.walk.collect = _.walk.map; // Alias `map` as `collect`. | ||
}; | ||
// Set up aliases to match those in underscore.js. | ||
exports.collect = exports.map; | ||
exports.detect = exports.find; | ||
exports.select = exports.filter; | ||
// Returns an object containing the walk functions. If `traversalStrategy` | ||
// is specified, it is a function determining how objects should be | ||
// traversed. Given an object, it returns the object to be recursively | ||
// walked. The default strategy is equivalent to `_.identity` for regular | ||
// objects, and for DOM nodes it returns the node's DOM children. | ||
_.walk = function(traversalStrategy) { | ||
var walker = _.clone(exports); | ||
// Bind all of the public functions in the walker to itself. This allows | ||
// the traversal strategy to be dynamically scoped. | ||
_.bindAll.apply(null, [walker].concat(_.keys(walker))); | ||
walker._traversalStrategy = traversalStrategy || defaultTraversal; | ||
return walker; | ||
}; | ||
// Use `_.walk` as a namespace to hold versions of the walk functions which | ||
// use the default traversal strategy. | ||
_.extend(_.walk, _.walk()); | ||
})(this); |
@@ -23,3 +23,3 @@ // Underscore-contrib (underscore.function.arity.js 0.0.1) | ||
} | ||
}; | ||
} | ||
@@ -31,6 +31,6 @@ | ||
function collectArgs(func, that, argCount, args, newArg, reverse) { | ||
if (reverse == true) { | ||
args.unshift(newArg); | ||
if (reverse === true) { | ||
args.unshift(newArg); | ||
} else { | ||
args.push(newArg); | ||
args.push(newArg); | ||
} | ||
@@ -85,8 +85,9 @@ if (args.length == argCount) { | ||
fix: function(fun) { | ||
var args = _.rest(arguments); | ||
var fixArgs = _.rest(arguments); | ||
var f = function() { | ||
var args = fixArgs.slice(); | ||
var arg = 0; | ||
for ( var i = 0; i < args.length && arg < arguments.length; i++ ) { | ||
for ( var i = 0; i < args.length || arg < arguments.length; i++ ) { | ||
if ( args[i] === _ ) { | ||
@@ -136,3 +137,3 @@ args[i] = arguments[arg++]; | ||
rCurry: function (func) { | ||
return curry.call(this, func, true); | ||
return curry.call(this, func, true); | ||
}, | ||
@@ -146,3 +147,3 @@ | ||
}); | ||
}) | ||
}); | ||
}, | ||
@@ -155,5 +156,5 @@ | ||
return fun.call(this, first, second, last); | ||
}) | ||
}) | ||
}) | ||
}); | ||
}); | ||
}); | ||
}, | ||
@@ -166,4 +167,4 @@ | ||
return fun.call(this, first, last); | ||
}) | ||
}) | ||
}); | ||
}); | ||
}, | ||
@@ -176,5 +177,5 @@ | ||
return fun.call(this, first, second, last); | ||
}) | ||
}) | ||
}) | ||
}); | ||
}); | ||
}); | ||
}, | ||
@@ -186,2 +187,5 @@ // Dynamic decorator to enforce function arity and defeat varargs. | ||
_.arity = (function () { | ||
// Allow 'new Function', as that is currently the only reliable way | ||
// to manipulate function.length | ||
/* jshint -W054 */ | ||
var FUNCTIONS = {}; | ||
@@ -188,0 +192,0 @@ return function arity (numberOfArgs, fun) { |
@@ -40,3 +40,3 @@ // Underscore-contrib (underscore.function.combinators.js 0.0.1) | ||
}); | ||
}; | ||
} | ||
@@ -162,3 +162,3 @@ // Mixing in the combinator functions | ||
return function () { | ||
return fun.call(this, __slice.call(arguments, 0)) | ||
return fun.call(this, __slice.call(arguments, 0)); | ||
}; | ||
@@ -216,7 +216,7 @@ } | ||
return function(/* args */) { | ||
var tmp = arguments[0]; | ||
arguments[0] = arguments[1]; | ||
arguments[1] = tmp; | ||
var flipped = __slice.call(arguments); | ||
flipped[0] = arguments[1]; | ||
flipped[1] = arguments[0]; | ||
return fun.apply(null, arguments); | ||
return fun.apply(null, flipped); | ||
}; | ||
@@ -233,2 +233,22 @@ }, | ||
}, | ||
// Takes a method-style function (one which uses `this`) and pushes | ||
// `this` into the argument list. The returned function uses its first | ||
// argument as the receiver/context of the original function, and the rest | ||
// of the arguments are used as the original's entire argument list. | ||
functionalize: function(method) { | ||
return function(ctx /*, args */) { | ||
return method.apply(ctx, _.rest(arguments)); | ||
}; | ||
}, | ||
// Takes a function and pulls the first argument out of the argument | ||
// list and into `this` position. The returned function calls the original | ||
// with its receiver (`this`) prepending the argument list. The original | ||
// is called with a receiver of `null`. | ||
methodize: function(func) { | ||
return function(/* args */) { | ||
return func.apply(null, _.cons(this, arguments)); | ||
}; | ||
}, | ||
@@ -235,0 +255,0 @@ k: _.always, |
@@ -5,3 +5,3 @@ // Underscore-contrib (underscore.function.iterators.js 0.0.1) | ||
(function(root) { | ||
(function(root, undefined) { | ||
@@ -31,99 +31,168 @@ // Baseline setup | ||
var undefined = void 0; | ||
// Mixing in the iterator functions | ||
// -------------------------------- | ||
function foldl (iter, binaryFn, seed) { | ||
var state, element; | ||
if (seed !== void 0) { | ||
function foldl (iter, binaryFn, seed) { | ||
var state, element; | ||
if (seed !== void 0) { | ||
state = seed; | ||
} | ||
else { | ||
state = iter(); | ||
} | ||
element = iter(); | ||
while (element != null) { | ||
state = binaryFn.call(element, state, element); | ||
element = iter(); | ||
} | ||
return state; | ||
} | ||
function unfold (seed, unaryFn) { | ||
var state = HASNTBEENRUN; | ||
return function () { | ||
if (state === HASNTBEENRUN) { | ||
state = seed; | ||
} else if (state != null) { | ||
state = unaryFn.call(state, state); | ||
} | ||
return state; | ||
}; | ||
} | ||
// note that the unfoldWithReturn behaves differently than | ||
// unfold with respect to the first value returned | ||
function unfoldWithReturn (seed, unaryFn) { | ||
var state = seed, | ||
pair, | ||
value; | ||
return function () { | ||
if (state != null) { | ||
pair = unaryFn.call(state, state); | ||
value = pair[1]; | ||
state = value != null ? pair[0] : void 0; | ||
return value; | ||
} | ||
else return void 0; | ||
}; | ||
} | ||
function accumulate (iter, binaryFn, initial) { | ||
var state = initial; | ||
return function () { | ||
var element = iter(); | ||
if (element == null) { | ||
return element; | ||
} | ||
else { | ||
state = iter(); | ||
if (state === void 0) { | ||
state = element; | ||
} else { | ||
state = binaryFn.call(element, state, element); | ||
} | ||
return state; | ||
} | ||
}; | ||
} | ||
function accumulateWithReturn (iter, binaryFn, initial) { | ||
var state = initial, | ||
stateAndReturnValue, | ||
element; | ||
return function () { | ||
element = iter(); | ||
while (element != null) { | ||
state = binaryFn.call(element, state, element); | ||
element = iter(); | ||
if (element == null) { | ||
return element; | ||
} | ||
return state; | ||
}; | ||
function unfold (seed, unaryFn) { | ||
var state = HASNTBEENRUN; | ||
return function () { | ||
if (state === HASNTBEENRUN) { | ||
return (state = seed); | ||
else { | ||
if (state === void 0) { | ||
state = element; | ||
return state; | ||
} | ||
else if (state != null) { | ||
return (state = unaryFn.call(state, state)); | ||
else { | ||
stateAndReturnValue = binaryFn.call(element, state, element); | ||
state = stateAndReturnValue[0]; | ||
return stateAndReturnValue[1]; | ||
} | ||
else return state; | ||
}; | ||
} | ||
}; | ||
} | ||
// note that the unfoldWithReturn behaves differently than | ||
// unfold with respect to the first value returned | ||
function unfoldWithReturn (seed, unaryFn) { | ||
var state = seed, | ||
pair, | ||
value; | ||
return function () { | ||
if (state != null) { | ||
pair = unaryFn.call(state, state); | ||
value = pair[1]; | ||
state = value != null | ||
? pair[0] | ||
: void 0; | ||
return value; | ||
} | ||
else return void 0; | ||
}; | ||
function map (iter, unaryFn) { | ||
return function() { | ||
var element; | ||
element = iter(); | ||
if (element != null) { | ||
return unaryFn.call(element, element); | ||
} else { | ||
return void 0; | ||
} | ||
}; | ||
} | ||
function accumulate (iter, binaryFn, initial) { | ||
var state = initial; | ||
return function () { | ||
element = iter(); | ||
if (element == null) { | ||
return element; | ||
function mapcat(iter, unaryFn) { | ||
var lastIter = null; | ||
return function() { | ||
var element; | ||
var gen; | ||
if (lastIter == null) { | ||
gen = iter(); | ||
if (gen == null) { | ||
lastIter = null; | ||
return void 0; | ||
} | ||
else { | ||
if (state === void 0) { | ||
return (state = element); | ||
} | ||
else return (state = binaryFn.call(element, state, element)); | ||
} | ||
}; | ||
}; | ||
function accumulateWithReturn (iter, binaryFn, initial) { | ||
var state = initial, | ||
stateAndReturnValue; | ||
return function () { | ||
element = iter(); | ||
lastIter = unaryFn.call(gen, gen); | ||
} | ||
while (element == null) { | ||
element = lastIter(); | ||
if (element == null) { | ||
return element; | ||
} | ||
else { | ||
if (state === void 0) { | ||
return (state = element); | ||
gen = iter(); | ||
if (gen == null) { | ||
lastIter = null; | ||
return void 0; | ||
} | ||
else { | ||
stateAndReturnValue = binaryFn.call(element, state, element); | ||
state = stateAndReturnValue[0]; | ||
return stateAndReturnValue[1]; | ||
lastIter = unaryFn.call(gen, gen); | ||
} | ||
} | ||
}; | ||
} | ||
return element; | ||
}; | ||
} | ||
function select (iter, unaryPredicateFn) { | ||
return function() { | ||
var element; | ||
element = iter(); | ||
while (element != null) { | ||
if (unaryPredicateFn.call(element, element)) { | ||
return element; | ||
} | ||
element = iter(); | ||
} | ||
return void 0; | ||
}; | ||
} | ||
function map (iter, unaryFn) { | ||
function reject (iter, unaryPredicateFn) { | ||
return select(iter, function (something) { | ||
return !unaryPredicateFn(something); | ||
}); | ||
} | ||
function find (iter, unaryPredicateFn) { | ||
return select(iter, unaryPredicateFn)(); | ||
} | ||
function slice (iter, numberToDrop, numberToTake) { | ||
var count = 0; | ||
while (numberToDrop-- > 0) { | ||
iter(); | ||
} | ||
if (numberToTake != null) { | ||
return function() { | ||
var element; | ||
element = iter(); | ||
if (element != null) { | ||
return unaryFn.call(element, element); | ||
if (++count <= numberToTake) { | ||
return iter(); | ||
} else { | ||
@@ -133,172 +202,136 @@ return void 0; | ||
}; | ||
}; | ||
function select (iter, unaryPredicateFn) { | ||
return function() { | ||
var element; | ||
element = iter(); | ||
while (element != null) { | ||
if (unaryPredicateFn.call(element, element)) { | ||
return element; | ||
} | ||
element = iter(); | ||
} | ||
return void 0; | ||
}; | ||
}; | ||
function reject (iter, unaryPredicateFn) { | ||
return select(iter, function (something) { | ||
return !unaryPredicateFn(something); | ||
}); | ||
}; | ||
function find (iter, unaryPredicateFn) { | ||
return select(iter, unaryPredicateFn)(); | ||
} | ||
function slice (iter, numberToDrop, numberToTake) { | ||
var count = 0; | ||
while (numberToDrop-- > 0) { | ||
iter(); | ||
} | ||
if (numberToTake != null) { | ||
return function() { | ||
if (++count <= numberToTake) { | ||
return iter(); | ||
} else { | ||
return void 0; | ||
} | ||
}; | ||
} | ||
else return iter; | ||
}; | ||
else return iter; | ||
} | ||
function drop (iter, numberToDrop) { | ||
return slice(iter, numberToDrop == null ? 1 : numberToDrop); | ||
} | ||
function take (iter, numberToTake) { | ||
return slice(iter, 0, numberToTake == null ? 1 : numberToTake); | ||
} | ||
function drop (iter, numberToDrop) { | ||
return slice(iter, numberToDrop == null ? 1 : numberToDrop); | ||
} | ||
function List (array) { | ||
var index = 0; | ||
return function() { | ||
return array[index++]; | ||
}; | ||
function take (iter, numberToTake) { | ||
return slice(iter, 0, numberToTake == null ? 1 : numberToTake); | ||
} | ||
function List (array) { | ||
var index = 0; | ||
return function() { | ||
return array[index++]; | ||
}; | ||
} | ||
function Tree (array) { | ||
var index, myself, state; | ||
index = 0; | ||
state = []; | ||
myself = function() { | ||
var element, tempState; | ||
element = array[index++]; | ||
if (element instanceof Array) { | ||
state.push({ | ||
array: array, | ||
index: index | ||
}); | ||
array = element; | ||
index = 0; | ||
function Tree (array) { | ||
var index, myself, state; | ||
index = 0; | ||
state = []; | ||
myself = function() { | ||
var element, tempState; | ||
element = array[index++]; | ||
if (element instanceof Array) { | ||
state.push({ | ||
array: array, | ||
index: index | ||
}); | ||
array = element; | ||
index = 0; | ||
return myself(); | ||
} else if (element === void 0) { | ||
if (state.length > 0) { | ||
tempState = state.pop(); | ||
array = tempState.array; | ||
index = tempState.index; | ||
return myself(); | ||
} else if (element === void 0) { | ||
if (state.length > 0) { | ||
tempState = state.pop(), array = tempState.array, index = tempState.index; | ||
return myself(); | ||
} else { | ||
return void 0; | ||
} | ||
} else { | ||
return element; | ||
return void 0; | ||
} | ||
}; | ||
return myself; | ||
} else { | ||
return element; | ||
} | ||
}; | ||
return myself; | ||
} | ||
function K (value) { | ||
return function () { | ||
return value; | ||
}; | ||
function K (value) { | ||
return function () { | ||
return value; | ||
}; | ||
} | ||
function upRange (from, to, by) { | ||
return function () { | ||
var was; | ||
if (from > to) { | ||
return void 0; | ||
} | ||
else { | ||
was = from; | ||
from = from + by; | ||
return was; | ||
} | ||
function upRange (from, to, by) { | ||
return function () { | ||
var was; | ||
if (from > to) { | ||
return void 0; | ||
} | ||
else { | ||
was = from; | ||
from = from + by; | ||
return was; | ||
} | ||
}; | ||
} | ||
function downRange (from, to, by) { | ||
return function () { | ||
var was; | ||
if (from < to) { | ||
return void 0; | ||
} | ||
else { | ||
was = from; | ||
from = from - by; | ||
return was; | ||
} | ||
}; | ||
}; | ||
function range (from, to, by) { | ||
if (from == null) { | ||
return upRange(1, Infinity, 1); | ||
function downRange (from, to, by) { | ||
return function () { | ||
var was; | ||
if (from < to) { | ||
return void 0; | ||
} | ||
else if (to == null) { | ||
return upRange(from, Infinity, 1); | ||
else { | ||
was = from; | ||
from = from - by; | ||
return was; | ||
} | ||
else if (by == null) { | ||
if (from <= to) { | ||
return upRange(from, to, 1); | ||
} | ||
else return downRange(from, to, 1) | ||
} | ||
else if (by > 0) { | ||
return upRange(from, to, by); | ||
} | ||
else if (by < 0) { | ||
return downRange(from, to, Math.abs(by)) | ||
} | ||
else return k(from); | ||
}; | ||
} | ||
var numbers = unary(range); | ||
function range (from, to, by) { | ||
if (from == null) { | ||
return upRange(1, Infinity, 1); | ||
} | ||
else if (to == null) { | ||
return upRange(from, Infinity, 1); | ||
} | ||
else if (by == null) { | ||
if (from <= to) { | ||
return upRange(from, to, 1); | ||
} | ||
else return downRange(from, to, 1); | ||
} | ||
else if (by > 0) { | ||
return upRange(from, to, by); | ||
} | ||
else if (by < 0) { | ||
return downRange(from, to, Math.abs(by)); | ||
} | ||
else return k(from); | ||
} | ||
var numbers = unary(range); | ||
_.iterators = { | ||
accumulate: accumulate, | ||
accumulateWithReturn: accumulateWithReturn, | ||
foldl: foldl, | ||
reduce: foldl, | ||
unfold: unfold, | ||
unfoldWithReturn: unfoldWithReturn, | ||
map: map, | ||
select: select, | ||
reject: reject, | ||
filter: select, | ||
find: find, | ||
slice: slice, | ||
drop: drop, | ||
take: take, | ||
List: List, | ||
Tree: Tree, | ||
constant: K, | ||
K: K, | ||
numbers: numbers, | ||
range: range | ||
}; | ||
_.iterators = { | ||
accumulate: accumulate, | ||
accumulateWithReturn: accumulateWithReturn, | ||
foldl: foldl, | ||
reduce: foldl, | ||
unfold: unfold, | ||
unfoldWithReturn: unfoldWithReturn, | ||
map: map, | ||
mapcat: mapcat, | ||
select: select, | ||
reject: reject, | ||
filter: select, | ||
find: find, | ||
slice: slice, | ||
drop: drop, | ||
take: take, | ||
List: List, | ||
Tree: Tree, | ||
constant: K, | ||
K: K, | ||
numbers: numbers, | ||
range: range | ||
}; | ||
})(this); | ||
})(this, void 0); |
@@ -38,2 +38,5 @@ // Underscore-contrib (underscore.function.predicates.js 0.0.1) | ||
// Check if an object is an object literal, since _.isObject(function() {}) === _.isObject([]) === true | ||
isPlainObject: function(x) { return _.isObject(x) && x.constructor === root.Object; }, | ||
// These do what you think that they do | ||
@@ -67,2 +70,12 @@ isZero: function(x) { return 0 === x; }, | ||
// checks if a string is a valid JSON | ||
isJSON: function(str) { | ||
try { | ||
JSON.parse(str); | ||
} catch (e) { | ||
return false; | ||
} | ||
return true; | ||
}, | ||
// Returns true if its arguments are monotonically | ||
@@ -69,0 +82,0 @@ // increaing values; false otherwise. |
@@ -30,3 +30,3 @@ // Underscore-contrib (underscore.object.builders.js 0.0.1) | ||
}; | ||
// Mixing in the object builders | ||
@@ -74,3 +74,5 @@ // ---------------------------- | ||
for(var key in obj) { | ||
temp[key] = _.snapshot(obj[key]); | ||
if (obj.hasOwnProperty(key)) { | ||
temp[key] = _.snapshot(obj[key]); | ||
} | ||
} | ||
@@ -86,3 +88,3 @@ | ||
// to the given function. | ||
updatePath: function(obj, fun, ks) { | ||
updatePath: function(obj, fun, ks, defaultValue) { | ||
if (!isAssociative(obj)) throw new TypeError("Attempted to update a non-associative object."); | ||
@@ -98,2 +100,5 @@ if (!existy(ks)) return fun(obj); | ||
_.each(_.initial(keys), function(key) { | ||
if (defaultValue && !_.has(target, key)) { | ||
target[key] = _.clone(defaultValue); | ||
} | ||
target = target[key]; | ||
@@ -108,6 +113,6 @@ }); | ||
// path described by the keys given. | ||
setPath: function(obj, value, ks) { | ||
setPath: function(obj, value, ks, defaultValue) { | ||
if (!existy(ks)) throw new TypeError("Attempted to set a property at a null path."); | ||
return _.updatePath(obj, function() { return value; }, ks); | ||
return _.updatePath(obj, function() { return value; }, ks, defaultValue); | ||
}, | ||
@@ -114,0 +119,0 @@ |
@@ -18,2 +18,4 @@ // Underscore-contrib (underscore.object.selectors.js 0.0.1) | ||
var concat = Array.prototype.concat; | ||
var ArrayProto = Array.prototype; | ||
var slice = ArrayProto.slice; | ||
@@ -55,4 +57,7 @@ // Mixing in the object selectors | ||
// Gets the value at any depth in a nested object based on the | ||
// path described by the keys given. | ||
// path described by the keys given. Keys may be given as an array | ||
// or as a dot-separated string. | ||
getPath: function getPath (obj, ks) { | ||
if (typeof ks == "string") ks = ks.split("."); | ||
// If we have reached an undefined property | ||
@@ -76,2 +81,4 @@ // then stop executing and return undefined | ||
hasPath: function hasPath (obj, ks) { | ||
if (typeof ks == "string") ks = ks.split("."); | ||
var numKeys = ks.length; | ||
@@ -86,5 +93,20 @@ | ||
return hasPath(obj[_.first(ks)], _.rest(ks)); | ||
}, | ||
pickWhen: function(obj, pred) { | ||
var copy = {}; | ||
_.each(obj, function(value, key) { | ||
if (pred(obj[key])) copy[key] = obj[key]; | ||
}); | ||
return copy; | ||
}, | ||
omitWhen: function(obj, pred) { | ||
return _.pickWhen(obj, function(e) { return !pred(e); }); | ||
} | ||
}); | ||
})(this); |
@@ -24,5 +24,10 @@ // Underscore-contrib (underscore.util.existential.js 0.0.1) | ||
falsey: function(x) { return !_.truthy(x); }, | ||
not: function(b) { return !b; } | ||
not: function(b) { return !b; }, | ||
firstExisting: function() { | ||
for (var i = 0; i < arguments.length; i++) { | ||
if (arguments[i] != null) return arguments[i]; | ||
} | ||
} | ||
}); | ||
})(this); |
@@ -12,3 +12,125 @@ // Underscore-contrib (underscore.function.arity.js 0.0.1) | ||
var _ = root._ || require('underscore'); | ||
// Setup for variadic operators | ||
// ---------------------------- | ||
// Turn a binary math operator into a variadic operator | ||
function variadicMath(operator) { | ||
return function() { | ||
return _.reduce(arguments, operator); | ||
}; | ||
} | ||
// Turn a binary comparator into a variadic comparator | ||
function variadicComparator(comparator) { | ||
return function() { | ||
var result; | ||
for (var i = 0; i < arguments.length - 1; i++) { | ||
result = comparator(arguments[i], arguments[i + 1]); | ||
if (result === false) return result; | ||
} | ||
return result; | ||
}; | ||
} | ||
// Turn a boolean-returning function into one with the opposite meaning | ||
function invert(fn) { | ||
return function() { | ||
return !fn.apply(this, arguments); | ||
}; | ||
} | ||
// Basic math operators | ||
function add(x, y) { | ||
return x + y; | ||
} | ||
function sub(x, y) { | ||
return x - y; | ||
} | ||
function mul(x, y) { | ||
return x * y; | ||
} | ||
function div(x, y) { | ||
return x / y; | ||
} | ||
function mod(x, y) { | ||
return x % y; | ||
} | ||
function inc(x) { | ||
return ++x; | ||
} | ||
function dec(x) { | ||
return --x; | ||
} | ||
function neg(x) { | ||
return -x; | ||
} | ||
// Bitwise operators | ||
function bitwiseAnd(x, y) { | ||
return x & y; | ||
} | ||
function bitwiseOr(x, y) { | ||
return x | y; | ||
} | ||
function bitwiseXor(x, y) { | ||
return x ^ y; | ||
} | ||
function bitwiseLeft(x, y) { | ||
return x << y; | ||
} | ||
function bitwiseRight(x, y) { | ||
return x >> y; | ||
} | ||
function bitwiseZ(x, y) { | ||
return x >>> y; | ||
} | ||
function bitwiseNot(x) { | ||
return ~x; | ||
} | ||
// Basic comparators | ||
function eq(x, y) { | ||
return x == y; | ||
} | ||
function seq(x, y) { | ||
return x === y; | ||
} | ||
// Not | ||
function not(x) { | ||
return !x; | ||
} | ||
// Relative comparators | ||
function gt(x, y) { | ||
return x > y; | ||
} | ||
function lt(x, y) { | ||
return x < y; | ||
} | ||
function gte(x, y) { | ||
return x >= y; | ||
} | ||
function lte(x, y) { | ||
return x <= y; | ||
} | ||
// Mixing in the operator functions | ||
@@ -18,75 +140,27 @@ // ----------------------------- | ||
_.mixin({ | ||
add: function(x, y) { | ||
return x + y; | ||
}, | ||
sub: function(x, y) { | ||
return x - y; | ||
}, | ||
mul: function(x, y) { | ||
return x * y; | ||
}, | ||
div: function(x, y) { | ||
return x / y; | ||
}, | ||
mod: function(x, y) { | ||
return x % y; | ||
}, | ||
inc: function(x) { | ||
return ++x; | ||
}, | ||
dec: function(x) { | ||
return --x; | ||
}, | ||
neg: function(x) { | ||
return -x; | ||
}, | ||
eq: function(x, y) { | ||
return x == y; | ||
}, | ||
seq: function(x, y) { | ||
return x === y; | ||
}, | ||
neq: function(x, y) { | ||
return x != y; | ||
}, | ||
sneq: function(x, y) { | ||
return x !== y; | ||
}, | ||
not: function(x) { | ||
return !x; | ||
}, | ||
gt: function(x, y) { | ||
return x > y; | ||
}, | ||
lt: function(x, y) { | ||
return x < y; | ||
}, | ||
gte: function(x, y) { | ||
return x >= y; | ||
}, | ||
lte: function(x, y) { | ||
return x <= y; | ||
}, | ||
bitwiseAnd: function(x, y) { | ||
return x & y; | ||
}, | ||
bitwiseOr: function(x, y) { | ||
return x | y; | ||
}, | ||
bitwiseXor: function(x, y) { | ||
return x ^ y; | ||
}, | ||
bitwiseNot: function(x) { | ||
return ~x; | ||
}, | ||
bitwiseLeft: function(x, y) { | ||
return x << y; | ||
}, | ||
bitwiseRight: function(x, y) { | ||
return x >> y; | ||
}, | ||
bitwiseZ: function(x, y) { | ||
return x >>> y; | ||
} | ||
add: variadicMath(add), | ||
sub: variadicMath(sub), | ||
mul: variadicMath(mul), | ||
div: variadicMath(div), | ||
mod: mod, | ||
inc: inc, | ||
dec: dec, | ||
neg: neg, | ||
eq: variadicComparator(eq), | ||
seq: variadicComparator(seq), | ||
neq: invert(variadicComparator(eq)), | ||
sneq: invert(variadicComparator(seq)), | ||
not: not, | ||
gt: variadicComparator(gt), | ||
lt: variadicComparator(lt), | ||
gte: variadicComparator(gte), | ||
lte: variadicComparator(lte), | ||
bitwiseAnd: variadicMath(bitwiseAnd), | ||
bitwiseOr: variadicMath(bitwiseOr), | ||
bitwiseXor: variadicMath(bitwiseXor), | ||
bitwiseNot: bitwiseNot, | ||
bitwiseLeft: variadicMath(bitwiseLeft), | ||
bitwiseRight: variadicMath(bitwiseRight), | ||
bitwiseZ: variadicMath(bitwiseZ) | ||
}); | ||
})(this); |
@@ -28,4 +28,23 @@ // Underscore-contrib (underscore.util.strings.js 0.0.1) | ||
return a.join(''); | ||
}, | ||
// Converts a string to camel case | ||
camelCase : function( string ){ | ||
return string.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); }); | ||
}, | ||
// Converts camel case to dashed (opposite of _.camelCase) | ||
toDash : function( string ){ | ||
string = string.replace(/([A-Z])/g, function($1){return "-"+$1.toLowerCase();}); | ||
// remove first dash | ||
return ( string.charAt( 0 ) == '-' ) ? string.substr(1) : string; | ||
}, | ||
// Reports whether a string contains a search string. | ||
strContains: function(str, search) { | ||
if (typeof str != 'string') throw new TypeError; | ||
return (str.indexOf(search) != -1); | ||
} | ||
}); | ||
})(this); |
@@ -0,0 +0,0 @@ // Underscore-contrib (underscore.util.trampolines.js 0.0.1) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
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
NPM Shrinkwrap
Supply chain riskPackage contains a shrinkwrap file. This may allow the package to bypass normal install procedures.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
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
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
831727
64
22793
61
8