diff --git a/build.js b/build.js index 0d6cb0a92..4bb8eeac9 100755 --- a/build.js +++ b/build.js @@ -971,6 +971,15 @@ : accumulator; }, []); + // update dependencies + if (isUnderscore) { + dependencyMap.isEqual = ['isArray', 'isFunction']; + dependencyMap.isEmpty = ['isArray', 'isString']; + + if (useUnderscoreClone) { + dependencyMap.clone = ['extend', 'isArray']; + } + } // add method names explicitly options.some(function(value) { return /include/.test(value) && @@ -1006,11 +1015,9 @@ return (result = _.union(result || [], getDependencies(methodNames))); }); - // init `result` if it hasn't been inited if (!result) { result = allMethods.slice(); } - if (plusMethods.length) { result = _.union(result, getDependencies(plusMethods)); } @@ -1047,10 +1054,6 @@ source = removeKeysOptimization(source); } else if (isUnderscore) { - // update dependencies - dependencyMap.isEqual = ['isArray', 'isFunction']; - dependencyMap.isEmpty = ['isArray']; - // remove unneeded variables source = removeVar(source, 'arrayLikeClasses'); source = removeVar(source, 'cloneableClasses'); @@ -1061,7 +1064,6 @@ // replace `_.clone` if (useUnderscoreClone) { - dependencyMap.clone = ['extend', 'isArray']; source = source.replace(/^( +)function clone[\s\S]+?\n\1}/m, [ ' function clone(value) {', ' return value && objectTypes[typeof value]', @@ -1112,6 +1114,24 @@ ' }' ].join('\n')); + // replace `_.isEmpty` + source = source.replace(/^( +)function isEmpty[\s\S]+?\n\1}/m, [ + ' function isEmpty(value) {', + ' if (!value) {', + ' return true;', + ' }', + ' if (isArray(value) || isString(value)) {', + ' return !value.length;', + ' }', + ' for (var key in value) {', + ' if (hasOwnProperty.call(value, key)) {', + ' return false;', + ' }', + ' }', + ' return true;', + ' }' + ].join('\n')); + // replace `_.without` source = source.replace(/^( +)function without[\s\S]+?\n\1}/m, [ ' function without(array) {', @@ -1129,9 +1149,6 @@ ' }' ].join('\n')); - // replace `arrayLikeClasses` in `_.isEmpty` - source = source.replace(/if *\(\(arrayLikeClasses.+?noArgsClass.+/, 'if (isArray(value) || className == stringClass ||'); - // replace `arrayLikeClasses` in `_.isEqual` source = source.replace(/(?: *\/\/.*\n)*( +)var isArr *= *arrayLikeClasses[^}]+}/, '$1var isArr = isArray(a);'); diff --git a/test/test-build.js b/test/test-build.js index bd704449c..5a649c25e 100644 --- a/test/test-build.js +++ b/test/test-build.js @@ -632,9 +632,11 @@ }); equal(last.value, 2, '_.each: ' + basename); - equal(lodash.isEmpty('moe'), false, '_.isEmpty: ' + basename); - var object = { 'fn': lodash.bind(function(x) { return this.x + x; }, { 'x': 1 }, 1) }; + var object = { 'length': 0, 'splice': Array.prototype.splice }; + equal(lodash.isEmpty(object), false, '_.isEmpty: ' + basename); + + object = { 'fn': lodash.bind(function(x) { return this.x + x; }, { 'x': 1 }, 1) }; equal(object.fn(), 2, '_.bind: ' + basename); ok(lodash.clone(array, true)[0] === array[0], '_.clone: ' + basename); @@ -642,6 +644,31 @@ }); }); + asyncTest('should not have any Lo-Dash-only methods', function() { + var start = _.after(2, _.once(QUnit.start)); + + build(['-s', 'underscore'], function(source, filePath) { + var basename = path.basename(filePath, '.js'), + context = createContext(); + + vm.runInContext(source, context); + var lodash = context._; + + _.each([ + 'forIn', + 'forOwn', + 'isPlainObject', + 'lateBind', + 'merge', + 'partial' + ], function(methodName) { + equal(lodash[methodName], undefined, '_.' + methodName + ' exists: ' + basename); + }); + + start(); + }); + }); + asyncTest('`lodash underscore include=partial`', function() { var start = _.after(2, _.once(QUnit.start));