diff --git a/build.js b/build.js index 6e7a8b9ef..520f306b9 100755 --- a/build.js +++ b/build.js @@ -42,10 +42,7 @@ 'select': 'filter', 'tail': 'rest', 'take': 'first', - 'unique': 'uniq', - - // method used by the `backbone` and `underscore` builds - 'findWhere': 'find' + 'unique': 'uniq' }; /** Used to associate real names with their aliases */ @@ -54,7 +51,7 @@ 'contains': ['include'], 'every': ['all'], 'filter': ['select'], - 'find': ['detect', 'findWhere'], + 'find': ['detect'], 'first': ['head', 'take'], 'forEach': ['each'], 'functions': ['methods'], @@ -167,7 +164,8 @@ 'zip': ['max', 'pluck'], // method used by the `backbone` and `underscore` builds - 'chain': ['mixin'] + 'chain': ['mixin'], + 'findWhere': ['where'] }; /** Used to inline `iteratorTemplate` */ @@ -1423,6 +1421,7 @@ dependencyMap.sortedIndex = _.without(dependencyMap.sortedIndex, 'isEqual', 'keys'); dependencyMap.template = _.without(dependencyMap.template, 'keys', 'values'); dependencyMap.uniq = _.without(dependencyMap.uniq, 'isEqual', 'keys'); + dependencyMap.where.push('find', 'isEmpty'); if (useUnderscoreClone) { dependencyMap.clone = _.without(dependencyMap.clone, 'forEach', 'forOwn'); @@ -1864,7 +1863,9 @@ // replace `_.where` source = replaceFunction(source, 'where', [ ' function where(collection, properties, first) {', - ' return (first ? find : filter)(collection, properties);', + ' return (first && isEmpty(properties))', + ' ? null', + ' : (first ? find : filter)(collection, properties);', ' }' ].join('\n')); @@ -1885,9 +1886,19 @@ ' }' ].join('\n')); - // add `_.findWhere` alias of `_.find` + // add `_.findWhere` + source = source.replace(matchFunction(source, 'find'), function (match) { + return match + [ + '', + ' function findWhere(object, properties) {', + ' return where(object, properties, true);', + ' }', + '' + ].join('\n') + }); + source = source.replace(getMethodAssignments(source), function(match) { - return match.replace(/^( *)lodash.find *=.+/m, '$&\n$1lodash.findWhere = find;'); + return match.replace(/^( *)lodash.find *=.+/m, '$&\n$1lodash.findWhere = findWhere;'); }); // remove `_.isEqual` use from `createCallback` diff --git a/lodash.underscore.js b/lodash.underscore.js index cc5ee6676..838147d52 100644 --- a/lodash.underscore.js +++ b/lodash.underscore.js @@ -1782,6 +1782,10 @@ return result; } + function findWhere(object, properties) { + return where(object, properties, true); + } + /** * Iterates over a `collection`, executing the `callback` for each element in * the `collection`. The `callback` is bound to `thisArg` and invoked with three @@ -2351,7 +2355,9 @@ * // => [{ 'name': 'moe', 'age': 40 }] */ function where(collection, properties, first) { - return (first ? find : filter)(collection, properties); + return (first && isEmpty(properties)) + ? null + : (first ? find : filter)(collection, properties); } /*--------------------------------------------------------------------------*/ @@ -3957,7 +3963,7 @@ lodash.escape = escape; lodash.every = every; lodash.find = find; - lodash.findWhere = find; + lodash.findWhere = findWhere; lodash.has = has; lodash.identity = identity; lodash.indexOf = indexOf; diff --git a/lodash.underscore.min.js b/lodash.underscore.min.js index a63ddef4a..49f160e75 100644 --- a/lodash.underscore.min.js +++ b/lodash.underscore.min.js @@ -4,30 +4,30 @@ * Build: `lodash underscore -m -o ./lodash.underscore.min.js` * Underscore.js 1.4.4 underscorejs.org/LICENSE */ -;(function(n,t){function r(n,t){var r;if(n&&Ft[typeof n])for(r in t||(t=V),n)if(t(n[r],r,n)===Y)break}function e(n,t,r){if(n){t=t&&typeof r=="undefined"?t:a(t,r);var e=n.length;if(r=-1,typeof e=="number")for(;++rt||typeof n=="undefined")return 1;if(nr?0:r);++eo&&(o=f)}}else t=a(t,r),e(n,function(n,r,e){r=t(n,r,e),r>u&&(u=r,o=n)});return o}function T(n,t){return F(n,t+"") -}function q(n,t,r,u){var o=3>arguments.length;if(t=a(t,u,4),Tt(n)){var i=-1,f=n.length;for(o&&(r=n[++i]);++iarguments.length;if(typeof u!="number")var i=qt(n),u=i.length;return t=a(t,e,4),k(n,function(e,a,f){a=i?i[--u]:--u,r=o?(o=J,n[a]):t(r,n[a],a,f)}),r}function D(n,t,r){var u;if(t=a(t,r),Tt(n)){r=-1;for(var o=n.length;++rr?yt(0,u+r):r||0)-1;else if(r)return e=C(n,t),n[e]===t?e:-1;for(;++e>>1,r(n[e])I(f,c))&&(r&&f.push(c),i.push(e))}return i}function U(n,t){return St||pt&&2"']/g,ut=/['\n\r\t\u2028\u2029\\]/g,ot=Math.ceil,it=Q.concat,at=Math.floor,ft=L.hasOwnProperty,ct=Q.push,lt=L.toString,pt=tt.test(pt=p.bind)&&pt,st=tt.test(st=Array.isArray)&&st,vt=n.isFinite,ht=n.isNaN,gt=tt.test(gt=Object.keys)&>,yt=Math.max,_t=Math.min,mt=Math.random,dt="[object Arguments]",bt="[object Array]",jt="[object Boolean]",wt="[object Date]",xt="[object Number]",At="[object Object]",Et="[object RegExp]",Ot="[object String]",L=!!n.attachEvent,L=pt&&!/\n|true/.test(pt+L),St=pt&&!L,Nt=(Nt={0:1,length:1},Q.splice.call(Nt,0,1),Nt[0]),kt=arguments.constructor==Object,Ft={"boolean":J,"function":G,object:G,number:J,string:J,undefined:J},Rt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"}; -u.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},v(arguments)||(v=function(n){return n?ft.call(n,"callee"):J});var Tt=st||function(n){return kt&&n instanceof Array||lt.call(n)==bt},qt=gt?function(n){return j(n)?gt(n):[]}:h,Bt={"&":"&","<":"<",">":">",'"':""","'":"'"},Dt=m(Bt);b(/x/)&&(b=function(n){return n instanceof Function||"[object Function]"==lt.call(n)}),u.after=function(n,t){return 1>n?t():function(){return 1>--n?t.apply(this,arguments):void 0 -}},u.bind=U,u.bindAll=function(n){for(var t=it.apply(Q,arguments),r=1I(e,o,r)&&u.push(o)}return u},u.filter=S,u.flatten=$,u.forEach=k,u.functions=_,u.groupBy=function(n,t,r){var e={}; -return t=a(t,r),k(n,function(n,r,u){r=t(n,r,u)+"",(ft.call(e,r)?e[r]:e[r]=[]).push(n)}),e},u.initial=function(n,t,r){if(!n)return[];var e=0,u=n.length;if(typeof t=="function"){var o=u;for(t=a(t,r);o--&&t(n[o],o,n);)e++}else e=t==H||r?1:t||e;return p(n,0,_t(yt(0,u-e),u))},u.intersection=function(n){var t=arguments,r=t.length,e=-1,u=n?n.length:0,o=[];n:for(;++eI(o,i)){for(var a=r;--a;)if(0>I(t[a],i))continue n;o.push(i)}}return o},u.invert=m,u.invoke=function(n,t){var r=p(arguments,2),e=-1,u=typeof t=="function",o=n?n.length:0,i=Array(typeof o=="number"?o:0); -return k(n,function(n){i[++e]=(u?t:n[t]).apply(n,r)}),i},u.keys=qt,u.map=F,u.max=R,u.memoize=function(n,t){var r={};return function(){var e=(t?t.apply(this,arguments):arguments[0])+"";return ft.call(r,e)?r[e]:r[e]=n.apply(this,arguments)}},u.min=function(n,t,r){var u=1/0,o=u;if(!t&&Tt(n)){r=-1;for(var i=n.length;++rI(t,r,1)&&(e[r]=n)}),e},u.once=function(n){var t,r;return function(){return t?r:(t=G,r=n.apply(this,arguments),n=H,r)}},u.pairs=function(n){for(var t=-1,r=qt(n),e=r.length,u=Array(e);++tI(arguments,u,1)&&e.push(u)}return e},u.wrap=function(n,t){return function(){var r=[n];return ct.apply(r,arguments),t.apply(this,r)}},u.zip=function(n){for(var t=-1,r=n?R(T(arguments,"length")):0,e=Array(r);++tr?yt(0,e+r):_t(r,e-1))+1);e--;)if(n[e]===t)return e;return-1},u.mixin=W,u.noConflict=function(){return n._=Z,this},u.random=function(n,t){return n==H&&t==H&&(t=1),n=+n||0,t==H&&(t=n,n=0),n+at(mt()*((+t||0)-n+1))},u.reduce=q,u.reduceRight=B,u.result=function(n,t){var r=n?n[t]:H; -return b(r)?n[t]():r},u.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:qt(n).length},u.some=D,u.sortedIndex=C,u.template=function(n,t,r){n||(n=""),r=y({},r,u.templateSettings);var e=0,o="__p+='",i=r.variable;n.replace(RegExp((r.escape||rt).source+"|"+(r.interpolate||rt).source+"|"+(r.evaluate||rt).source+"|$","g"),function(t,r,u,i,a){return o+=n.slice(e,a).replace(ut,f),r&&(o+="'+_['escape']("+r+")+'"),i&&(o+="';"+i+";__p+='"),u&&(o+="'+((__t=("+u+"))==null?'':__t)+'"),e=a+t.length,t -}),o+="';\n",i||(i="obj",o="with("+i+"||{}){"+o+"}"),o="function("+i+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+o+"return __p}";try{var a=Function("_","return "+o)(u)}catch(c){throw c.source=o,c}return t?a(t):(a.source=o,a)},u.unescape=function(n){return n==H?"":(n+"").replace(nt,s)},u.uniqueId=function(n){var t=++X+"";return n?n+t:t},u.all=O,u.any=D,u.detect=N,u.foldl=q,u.foldr=B,u.include=E,u.inject=q,u.first=M,u.last=function(n,t,r){if(n){var e=0,u=n.length; -if(typeof t=="function"){var o=u;for(t=a(t,r);o--&&t(n[o],o,n);)e++}else if(e=t,e==H||r)return n[u-1];return p(n,yt(0,u-e))}},u.take=M,u.head=M,u.chain=function(n){return n=new u(n),n.__chain__=G,n},u.VERSION="1.0.0-rc.3",W(u),u.prototype.chain=function(){return this.__chain__=G,this},u.prototype.value=function(){return this.__wrapped__},e("pop push reverse shift sort splice unshift".split(" "),function(n){var t=Q[n];u.prototype[n]=function(){var n=this.__wrapped__;return t.apply(n,arguments),Nt&&0===n.length&&delete n[0],this -}}),e(["concat","join","slice"],function(n){var t=Q[n];u.prototype[n]=function(){var n=t.apply(this.__wrapped__,arguments);return this.__chain__&&(n=new u(n),n.__chain__=G),n}}),K?typeof module=="object"&&module&&module.exports==K?(module.exports=u)._=u:K._=u:n._=u})(this); \ No newline at end of file +;(function(n,t){function r(n,t){var r;if(n&&Tt[typeof n])for(r in t||(t=G),n)if(t(n[r],r,n)===nt)break}function e(n,t,r){if(n){t=t&&typeof r=="undefined"?t:a(t,r);var e=n.length;if(r=-1,typeof e=="number")for(;++rt||typeof n=="undefined")return 1;if(nr?0:r);++eo&&(o=f)}}else t=a(t,r),e(n,function(n,r,e){r=t(n,r,e),r>u&&(u=r,o=n) +});return o}function q(n,t){return R(n,t+"")}function B(n,t,r,u){var o=3>arguments.length;if(t=a(t,u,4),Bt(n)){var i=-1,f=n.length;for(o&&(r=n[++i]);++iarguments.length;if(typeof u!="number")var i=Dt(n),u=i.length;return t=a(t,e,4),F(n,function(e,a,f){a=i?i[--u]:--u,r=o?(o=L,n[a]):t(r,n[a],a,f)}),r}function M(n,t,r){var u;if(t=a(t,r),Bt(n)){r=-1;for(var o=n.length;++rr?mt(0,u+r):r||0)-1;else if(r)return e=U(n,t),n[e]===t?e:-1;for(;++e>>1,r(n[e])C(f,c))&&(r&&f.push(c),i.push(e))}return i}function W(n,t){return kt||vt&&2"']/g,it=/['\n\r\t\u2028\u2029\\]/g,at=Math.ceil,ft=Y.concat,ct=Math.floor,lt=X.hasOwnProperty,pt=Y.push,st=X.toString,vt=et.test(vt=p.bind)&&vt,ht=et.test(ht=Array.isArray)&&ht,gt=n.isFinite,yt=n.isNaN,_t=et.test(_t=Object.keys)&&_t,mt=Math.max,dt=Math.min,bt=Math.random,jt="[object Arguments]",wt="[object Array]",xt="[object Boolean]",At="[object Date]",Et="[object Number]",Ot="[object Object]",St="[object RegExp]",Nt="[object String]",X=!!n.attachEvent,X=vt&&!/\n|true/.test(vt+X),kt=vt&&!X,Ft=(Ft={0:1,length:1},Y.splice.call(Ft,0,1),Ft[0]),Rt=arguments.constructor==Object,Tt={"boolean":L,"function":J,object:J,number:L,string:L,undefined:L},qt={"\\":"\\","'":"'","\n":"n","\r":"r"," ":"t","\u2028":"u2028","\u2029":"u2029"}; +u.templateSettings={escape:/<%-([\s\S]+?)%>/g,evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,variable:""},v(arguments)||(v=function(n){return n?lt.call(n,"callee"):L});var Bt=ht||function(n){return Rt&&n instanceof Array||st.call(n)==wt},Dt=_t?function(n){return w(n)?_t(n):[]}:h,Mt={"&":"&","<":"<",">":">",'"':""","'":"'"},$t=m(Mt);j(/x/)&&(j=function(n){return n instanceof Function||"[object Function]"==st.call(n)}),u.after=function(n,t){return 1>n?t():function(){return 1>--n?t.apply(this,arguments):void 0 +}},u.bind=W,u.bindAll=function(n){for(var t=ft.apply(Y,arguments),r=1C(e,o,r)&&u.push(o)}return u},u.filter=N,u.flatten=z,u.forEach=F,u.functions=_,u.groupBy=function(n,t,r){var e={}; +return t=a(t,r),F(n,function(n,r,u){r=t(n,r,u)+"",(lt.call(e,r)?e[r]:e[r]=[]).push(n)}),e},u.initial=function(n,t,r){if(!n)return[];var e=0,u=n.length;if(typeof t=="function"){var o=u;for(t=a(t,r);o--&&t(n[o],o,n);)e++}else e=t==K||r?1:t||e;return p(n,0,dt(mt(0,u-e),u))},u.intersection=function(n){var t=arguments,r=t.length,e=-1,u=n?n.length:0,o=[];n:for(;++eC(o,i)){for(var a=r;--a;)if(0>C(t[a],i))continue n;o.push(i)}}return o},u.invert=m,u.invoke=function(n,t){var r=p(arguments,2),e=-1,u=typeof t=="function",o=n?n.length:0,i=Array(typeof o=="number"?o:0); +return F(n,function(n){i[++e]=(u?t:n[t]).apply(n,r)}),i},u.keys=Dt,u.map=R,u.max=T,u.memoize=function(n,t){var r={};return function(){var e=(t?t.apply(this,arguments):arguments[0])+"";return lt.call(r,e)?r[e]:r[e]=n.apply(this,arguments)}},u.min=function(n,t,r){var u=1/0,o=u;if(!t&&Bt(n)){r=-1;for(var i=n.length;++rC(t,r,1)&&(e[r]=n)}),e},u.once=function(n){var t,r;return function(){return t?r:(t=J,r=n.apply(this,arguments),n=K,r)}},u.pairs=function(n){for(var t=-1,r=Dt(n),e=r.length,u=Array(e);++tC(arguments,u,1)&&e.push(u)}return e},u.wrap=function(n,t){return function(){var r=[n];return pt.apply(r,arguments),t.apply(this,r)}},u.zip=function(n){for(var t=-1,r=n?T(q(arguments,"length")):0,e=Array(r);++tr?mt(0,e+r):dt(r,e-1))+1);e--;)if(n[e]===t)return e;return-1},u.mixin=H,u.noConflict=function(){return n._=tt,this},u.random=function(n,t){return n==K&&t==K&&(t=1),n=+n||0,t==K&&(t=n,n=0),n+ct(bt()*((+t||0)-n+1))},u.reduce=B,u.reduceRight=D,u.result=function(n,t){var r=n?n[t]:K;return j(r)?n[t]():r},u.size=function(n){var t=n?n.length:0;return typeof t=="number"?t:Dt(n).length +},u.some=M,u.sortedIndex=U,u.template=function(n,t,r){n||(n=""),r=y({},r,u.templateSettings);var e=0,o="__p+='",i=r.variable;n.replace(RegExp((r.escape||ut).source+"|"+(r.interpolate||ut).source+"|"+(r.evaluate||ut).source+"|$","g"),function(t,r,u,i,a){return o+=n.slice(e,a).replace(it,f),r&&(o+="'+_['escape']("+r+")+'"),i&&(o+="';"+i+";__p+='"),u&&(o+="'+((__t=("+u+"))==null?'':__t)+'"),e=a+t.length,t}),o+="';\n",i||(i="obj",o="with("+i+"||{}){"+o+"}"),o="function("+i+"){var __t,__p='',__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}"+o+"return __p}"; +try{var a=Function("_","return "+o)(u)}catch(c){throw c.source=o,c}return t?a(t):(a.source=o,a)},u.unescape=function(n){return n==K?"":(n+"").replace(rt,s)},u.uniqueId=function(n){var t=++Z+"";return n?n+t:t},u.all=S,u.any=M,u.detect=k,u.foldl=B,u.foldr=D,u.include=O,u.inject=B,u.first=I,u.last=function(n,t,r){if(n){var e=0,u=n.length;if(typeof t=="function"){var o=u;for(t=a(t,r);o--&&t(n[o],o,n);)e++}else if(e=t,e==K||r)return n[u-1];return p(n,mt(0,u-e))}},u.take=I,u.head=I,u.chain=function(n){return n=new u(n),n.__chain__=J,n +},u.VERSION="1.0.0-rc.3",H(u),u.prototype.chain=function(){return this.__chain__=J,this},u.prototype.value=function(){return this.__wrapped__},e("pop push reverse shift sort splice unshift".split(" "),function(n){var t=Y[n];u.prototype[n]=function(){var n=this.__wrapped__;return t.apply(n,arguments),Ft&&0===n.length&&delete n[0],this}}),e(["concat","join","slice"],function(n){var t=Y[n];u.prototype[n]=function(){var n=t.apply(this.__wrapped__,arguments);return this.__chain__&&(n=new u(n),n.__chain__=J),n +}}),Q?typeof module=="object"&&module&&module.exports==Q?(module.exports=u)._=u:Q._=u:n._=u})(this); \ No newline at end of file diff --git a/test/test-build.js b/test/test-build.js index 6207a8289..c8927b951 100644 --- a/test/test-build.js +++ b/test/test-build.js @@ -42,10 +42,7 @@ 'select': 'filter', 'tail': 'rest', 'take': 'first', - 'unique': 'uniq', - - // method used by the `backbone` and `underscore` builds - 'findWhere': 'find' + 'unique': 'uniq' }; /** Used to associate real names with their aliases */ @@ -54,7 +51,7 @@ 'contains': ['include'], 'every': ['all'], 'filter': ['select'], - 'find': ['detect', 'findWhere'], + 'find': ['detect'], 'first': ['head', 'take'], 'forEach': ['each'], 'functions': ['methods'], @@ -798,7 +795,7 @@ actual = lodash.pick(object, function(value) { return value != 3; }); deepEqual(_.keys(actual), [], '_.pick should not accept a `callback`: ' + basename); - strictEqual(lodash.result(), null, '_.result should return `null` when passed a falsey `object` argument: ' + basename); + strictEqual(lodash.result(), null, '_.result should return `null` for falsey `object` arguments: ' + basename); strictEqual(lodash.some([false, true, false]), true, '_.some: ' + basename); equal(lodash.template('${a}', object), '${a}', '_.template should ignore ES6 delimiters: ' + basename); equal('imports' in lodash.templateSettings, false, '_.templateSettings should not have an "imports" property: ' + basename); @@ -809,7 +806,10 @@ collection = [{ 'a': 1 }, { 'a': 1 }]; deepEqual(lodash.where(collection, { 'a': 1 }, true), collection[0], '_.where supports a `first` argument: ' + basename); + deepEqual(lodash.where(collection, {}, true), null, '_.where should return `null` when passed `first` and falsey `properties`: ' + basename); + deepEqual(lodash.findWhere(collection, { 'a': 1 }), collection[0], '_.findWhere: ' + basename); + strictEqual(lodash.findWhere(collection, {}), null, '_.findWhere should return `null` for falsey `properties`: ' + basename); start(); }); @@ -842,6 +842,23 @@ }); }); + asyncTest('`lodash underscore include=findWhere`', function() { + var start = _.after(2, _.once(QUnit.start)); + + build(['-s', 'underscore', 'include=findWhere'], function(data) { + var basename = path.basename(data.outputPath, '.js'), + context = createContext(); + + vm.runInContext(data.source, context); + var lodash = context._; + + var collection = [{ 'a': 1 }, { 'a': 1 }]; + deepEqual(lodash.findWhere(collection, { 'a': 1 }), collection[0], '_.findWhere: ' + basename); + + start(); + }); + }); + asyncTest('`lodash underscore include=partial`', function() { var start = _.after(2, _.once(QUnit.start)); diff --git a/vendor/underscore/test/utility.js b/vendor/underscore/test/utility.js index 4d2e02afa..0bca8c892 100644 --- a/vendor/underscore/test/utility.js +++ b/vendor/underscore/test/utility.js @@ -207,7 +207,7 @@ $(document).ready(function() { strictEqual(_.result(obj, 'x'), 'x'); strictEqual(_.result(obj, 'y'), 'x'); strictEqual(_.result(obj, 'z'), undefined); - strictEqual(_.result(null, 'x'), undefined); + strictEqual(_.result(null, 'x'), null); }); test('_.templateSettings.variable', function() { diff --git a/vendor/underscore/underscore.js b/vendor/underscore/underscore.js index cf6fc2a87..a12f0d96c 100644 --- a/vendor/underscore/underscore.js +++ b/vendor/underscore/underscore.js @@ -238,7 +238,7 @@ // Convenience version of a common use case of `filter`: selecting only objects // containing specific `key:value` pairs. _.where = function(obj, attrs, first) { - if (_.isEmpty(attrs)) return first ? void 0 : []; + if (_.isEmpty(attrs)) return first ? null : []; return _[first ? 'find' : 'filter'](obj, function(value) { for (var key in attrs) { if (attrs[key] !== value[key]) return false; @@ -1058,7 +1058,7 @@ // If the value of the named property is a function then invoke it; // otherwise, return it. _.result = function(object, property) { - if (object == null) return void 0; + if (object == null) return null; var value = object[property]; return _.isFunction(value) ? value.call(object) : value; };