From 163fdb46f03d7a122c4ab78fbf0c82ced17931d4 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sun, 31 Jan 2016 22:26:27 -0800 Subject: [PATCH] Ensure fp `_.partial` and `_.partialRight` accept an `args` param. --- fp/_baseConvert.js | 17 +++++++++++++---- fp/_mapping.js | 8 +++++++- lib/fp/template/_util.jst | 3 ++- test/test-fp.js | 26 ++++++++++++++++++++++++-- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/fp/_baseConvert.js b/fp/_baseConvert.js index d116bc9fe..253caff18 100644 --- a/fp/_baseConvert.js +++ b/fp/_baseConvert.js @@ -29,7 +29,8 @@ function baseConvert(util, name, func) { 'isFunction': util.isFunction, 'iteratee': util.iteratee, 'keys': util.keys, - 'rearg': util.rearg + 'rearg': util.rearg, + 'rest': util.rest }; var ary = _.ary, @@ -38,7 +39,8 @@ function baseConvert(util, name, func) { each = _.forEach, isFunction = _.isFunction, keys = _.keys, - rearg = _.rearg; + rearg = _.rearg, + spread = _.spread; var baseArity = function(func, n) { return n == 2 @@ -168,9 +170,13 @@ function baseConvert(util, name, func) { each(mapping.aryMethod[cap], function(otherName) { if (name == otherName) { var aryN = !isLib && mapping.iterateeAry[name], - reargIndexes = mapping.iterateeRearg[name]; + reargIndexes = mapping.iterateeRearg[name], + spreadStart = mapping.methodSpread[name]; + + result = spreadStart === undefined + ? ary(func, cap) + : spread(func, spreadStart); - result = ary(func, cap); if (cap > 1 && !mapping.skipRearg[name]) { result = rearg(result, mapping.methodRearg[name] || mapping.aryRearg[cap]); } @@ -198,6 +204,9 @@ function baseConvert(util, name, func) { if (!isLib) { return wrap(name, func); } + // Add placeholder alias. + _.__ = placeholder; + // Iterate over methods for the current ary cap. var pairs = []; each(mapping.caps, function(cap) { diff --git a/fp/_mapping.js b/fp/_mapping.js index bed8bde5f..2cfd21842 100644 --- a/fp/_mapping.js +++ b/fp/_mapping.js @@ -41,7 +41,7 @@ exports.aryMethod = { 'attempt', 'ceil', 'create', 'curry', 'curryRight', 'floor', 'fromPairs', 'invert', 'iteratee', 'memoize', 'method', 'methodOf', 'mixin', 'over', 'overEvery', 'overSome', 'rest', 'reverse', 'round', 'runInContext', - 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' + 'spread', 'template', 'trim', 'trimEnd', 'trimStart', 'uniqueId', 'words' ], 2: [ 'add', 'after', 'ary', 'assign', 'assignIn', 'at', 'before', 'bind', 'bindKey', @@ -147,6 +147,12 @@ exports.methodRearg = { 'transform': [2, 0, 1] }; +/** Used to map method names to spread configs. */ +exports.methodSpread = { + 'partial': 1, + 'partialRight': 1 +}; + /** Used to identify methods which mutate arrays or objects. */ exports.mutate = { 'array': { diff --git a/lib/fp/template/_util.jst b/lib/fp/template/_util.jst index d076f4643..e1baf3b0a 100644 --- a/lib/fp/template/_util.jst +++ b/lib/fp/template/_util.jst @@ -6,5 +6,6 @@ module.exports = { 'isFunction': require('../isFunction'), 'iteratee': require('../iteratee'), 'keys': require('../_baseKeys'), - 'rearg': require('../rearg') + 'rearg': require('../rearg'), + 'spread': require('../spread') }; diff --git a/test/test-fp.js b/test/test-fp.js index e2cca7201..472370b8f 100644 --- a/test/test-fp.js +++ b/test/test-fp.js @@ -161,7 +161,7 @@ var funcMethods = [ 'after', 'ary', 'before', 'bind', 'bindKey', 'curryN', 'debounce', 'delay', - 'overArgs', 'rearg', 'throttle', 'wrap' + 'overArgs', 'partial', 'partialRight', 'rearg', 'throttle', 'wrap' ]; var exceptions = _.difference(funcMethods.concat('matchesProperty'), ['cloneDeepWith', 'cloneWith', 'delay']), @@ -514,9 +514,10 @@ var func = fp[methodName]; QUnit.test('`_.' + methodName + '` should have a `placeholder` property', function(assert) { - assert.expect(1); + assert.expect(2); assert.ok(_.isObject(func.placeholder)); + assert.strictEqual(func.placeholder, fp.__); }); }); @@ -865,6 +866,27 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('fp.partial and fp.partialRight'); + + _.each(['partial', 'partialRight'], function(methodName) { + var func = fp[methodName], + isPartial = methodName == 'partial'; + + QUnit.test('`_.' + methodName + '` should accept an `args` param', function(assert) { + assert.expect(1); + + var expected = isPartial ? [1, 2, 3] : [0, 1, 2]; + + var actual = func(function(a, b, c) { + return [a, b, c]; + })([1, 2])(isPartial ? 3 : 0); + + assert.deepEqual(actual, expected); + }); + }); + + /*--------------------------------------------------------------------------*/ + QUnit.module('fp.random'); (function() {