From 4e2ef908dcea9d561fa999bb19d0864496d888ae Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 18 Mar 2013 02:38:06 -0600 Subject: [PATCH] Limit the `category` build option to adding only those methods available for specific builds (i.e. `underscore` and `backbone` builds). Former-commit-id: 63a5509cd953b20376723335d42fb5a136eb3a5c --- build.js | 45 ++++++++++++++++++-------- test/test-build.js | 79 ++++++++++++++++++++++++---------------------- 2 files changed, 72 insertions(+), 52 deletions(-) diff --git a/build.js b/build.js index b4ff99098..dd77babb9 100755 --- a/build.js +++ b/build.js @@ -893,7 +893,10 @@ * @returns {Array} Returns the new converted array. */ function optionToArray(value) { - return _.compact(value.match(/\w+=(.*)$/)[1].split(/, */)); + return _.compact(_.isArray(value) + ? value + : value.match(/\w+=(.*)$/)[1].split(/, */) + ); } /** @@ -908,11 +911,6 @@ function optionToMethodsArray(source, value) { var methodNames = optionToArray(value); - // convert categories to method names - methodNames.forEach(function(category) { - push.apply(methodNames, getMethodsByCategory(source, category)); - }); - // convert aliases to real method names methodNames = methodNames.map(getRealName); @@ -1606,11 +1604,6 @@ // flag to specify a legacy build var isLegacy = !(isModern || isUnderscore) && options.indexOf('legacy') > -1; - // used to specify methods of specific categories - var categories = options.reduce(function(result, value) { - return /category/.test(value) ? optionToArray(value) : result; - }, []); - // used to specify the ways to export the `lodash` function var exportsOptions = options.reduce(function(result, value) { return /exports/.test(value) ? optionToArray(value).sort() : result; @@ -1644,7 +1637,7 @@ : result; }, ''); - // used when precompiling template files + // used as the template settings for precompiled templates var templateSettings = options.reduce(function(result, value) { var match = value.match(/settings=(.+)$/); return match @@ -1701,6 +1694,17 @@ : accumulator; }, []); + var categories = options.reduce(function(accumulator, value) { + if (/category|exclude|include|minus|plus/.test(value)) { + var array = optionToArray(value); + accumulator = _.union(accumulator, /category/.test(value) + ? array + : array.filter(function(category) { return /^[A-Z]/.test(category); }) + ); + } + return accumulator; + }, []); + // set flags to include Lo-Dash's methods if explicitly requested if (isUnderscore) { var methods = _.without.apply(_, [_.union(includeMethods, plusMethods)].concat(minusMethods)); @@ -1775,8 +1779,21 @@ // add method names by category if (categories.length) { result = _.union(result || [], getDependencies(categories.reduce(function(accumulator, category) { - // resolve method names belonging to each category (case-insensitive) - return accumulator.concat(getMethodsByCategory(source, capitalize(category))); + // get method names belonging to each category (case-insensitive) + var methodNames = getMethodsByCategory(source, capitalize(category)); + + // limit category methods to those available for specific builds + if (isBackbone) { + methodNames = methodNames.filter(function(methodName) { + return _.contains(backboneDependencies, methodName); + }); + } + else if (isUnderscore) { + methodNames = methodNames.filter(function(methodName) { + return _.contains(underscoreMethods, methodName); + }); + } + return accumulator.concat(methodNames); }, []))); } if (!result) { diff --git a/test/test-build.js b/test/test-build.js index 6f4eb9187..d65b3898e 100644 --- a/test/test-build.js +++ b/test/test-build.js @@ -33,6 +33,9 @@ global.QUnit ); + /** Shortcut used to push arrays of values to an array */ + var push = Array.prototype.push; + /** The time limit for the tests to run (milliseconds) */ var timeLimit = process.argv.reduce(function(result, value, index) { if (/--time-limit/.test(value)) { @@ -308,6 +311,17 @@ /*--------------------------------------------------------------------------*/ + /** + * Capitalizes a given string. + * + * @private + * @param {String} string The string to capitalize. + * @returns {String} Returns the capitalized string. + */ + function capitalize(string) { + return string[0].toUpperCase() + string.toLowerCase().slice(1); + } + /** * Creates a context object to use with `vm.runInContext`. * @@ -331,7 +345,7 @@ function expandMethodNames(methodNames) { return methodNames.reduce(function(result, methodName) { var realName = getRealName(methodName); - result.push.apply(result, [realName].concat(getAliases(realName))); + push.apply(result, [realName].concat(getAliases(realName))); return result; }, []); } @@ -1365,12 +1379,9 @@ var methodNames, basename = path.basename(data.outputPath, '.js'), context = createContext(), - isUnderscore = /backbone|underscore/.test(command), + isBackbone = /backbone/.test(command), + isUnderscore = isBackbone || /underscore/.test(command), exposeAssign = !isUnderscore, - exposeCreateCallback = !isUnderscore, - exposeForIn = !isUnderscore, - exposeForOwn = !isUnderscore, - exposeIsPlainObject = !isUnderscore, exposeZipObject = !isUnderscore; try { @@ -1389,21 +1400,14 @@ if (isUnderscore) { if (methodNames) { exposeAssign = methodNames.indexOf('assign') > -1; - exposeCreateCallback = methodNames.indexOf('createCallback') > -1; exposeZipObject = methodNames.indexOf('zipObject') > -1; } else { methodNames = underscoreMethods.slice(); } } - // add method names explicitly by category if (/category/.test(command)) { - // resolve method names belonging to each category (case-insensitive) - methodNames = command.match(/category=(\S*)/)[1].split(/, */).reduce(function(result, category) { - var capitalized = category[0].toUpperCase() + category.toLowerCase().slice(1); - return result.concat(getMethodsByCategory(capitalized)); - }, methodNames || []); + methodNames = (methodNames || []).concat(command.match(/category=(\S*)/)[1].split(/, */).map(capitalize)); } - // init `methodNames` if it hasn't been inited if (!methodNames) { methodNames = allMethods.slice(); } @@ -1411,40 +1415,39 @@ methodNames = methodNames.concat(command.match(/plus=(\S*)/)[1].split(/, */)); } if (/minus/.test(command)) { - methodNames = _.without.apply(_, [methodNames] - .concat(expandMethodNames(command.match(/minus=(\S*)/)[1].split(/, */)))); + methodNames = _.without.apply(_, [methodNames].concat(expandMethodNames(command.match(/minus=(\S*)/)[1].split(/, */)))); } if (/exclude/.test(command)) { - methodNames = _.without.apply(_, [methodNames] - .concat(expandMethodNames(command.match(/exclude=(\S*)/)[1].split(/, */)))); + methodNames = _.without.apply(_, [methodNames].concat(expandMethodNames(command.match(/exclude=(\S*)/)[1].split(/, */)))); } - // expand aliases and categories to real method names - methodNames = expandMethodNames(methodNames).reduce(function(result, methodName) { - return result.concat(methodName, getMethodsByCategory(methodName)); - }, []); + // expand categories to real method names + methodNames.slice().forEach(function(category) { + var result = getMethodsByCategory(category); - // remove nonexistent and duplicate method names + // limit category methods to those available for specific builds + if (isBackbone) { + result = result.filter(function(methodName) { + return _.contains(backboneDependencies, methodName); + }); + } + else if (isUnderscore) { + result = result.filter(function(methodName) { + return _.contains(underscoreMethods, methodName); + }); + } + if (result.length) { + methodNames = _.without(methodNames, category); + push.apply(methodNames, result); + } + }); + + // expand aliases and remove nonexistent and duplicate method names methodNames = _.uniq(_.intersection(allMethods, expandMethodNames(methodNames))); - if (isUnderscore) { - methodNames = _.without.apply(_, [methodNames].concat(['findIndex', 'findKey'])); - } if (!exposeAssign) { methodNames = _.without(methodNames, 'assign'); } - if (!exposeCreateCallback) { - methodNames = _.without(methodNames, 'createCallback'); - } - if (!exposeForIn) { - methodNames = _.without(methodNames, 'forIn'); - } - if (!exposeForOwn) { - methodNames = _.without(methodNames, 'forOwn'); - } - if (!exposeIsPlainObject) { - methodNames = _.without(methodNames, 'isPlainobject'); - } if (!exposeZipObject) { methodNames = _.without(methodNames, 'zipObject'); }