Ensure _.spread doesn’t include arguments after those spread. [closes #2825]

This commit is contained in:
John-David Dalton
2016-11-15 08:34:41 -08:00
parent eb4861c3cd
commit 4cb7bea97d
4 changed files with 45 additions and 15 deletions

View File

@@ -1,6 +1,9 @@
var mapping = require('./_mapping'),
fallbackHolder = require('./placeholder');
/** Built-in value reference. */
var push = Array.prototype.push;
/**
* Creates a function, with an arity of `n`, that invokes `func` with the
* arguments it receives.
@@ -61,6 +64,36 @@ function createCloner(func) {
};
}
/**
* This function is like `_.spread` except that it includes arguments after those spread.
*
* @private
* @param {Function} func The function to spread arguments over.
* @param {number} start The start position of the spread.
* @returns {Function} Returns the new function.
*/
function spread(func, start) {
return function() {
var length = arguments.length,
args = Array(length);
while (length--) {
args[length] = arguments[length];
}
var array = args[start],
lastIndex = args.length - 1,
otherArgs = args.slice(0, start);
if (array) {
push.apply(otherArgs, array);
}
if (start != lastIndex) {
push.apply(otherArgs, args.slice(start + 1));
}
return func.apply(this, otherArgs);
};
}
/**
* Creates a function that wraps `func` and uses `cloner` to clone the first
* argument it receives.
@@ -141,7 +174,6 @@ function baseConvert(util, name, func, options) {
'iteratee': util.iteratee,
'keys': util.keys,
'rearg': util.rearg,
'spread': util.spread,
'toInteger': util.toInteger,
'toPath': util.toPath
};
@@ -155,7 +187,6 @@ function baseConvert(util, name, func, options) {
isFunction = helpers.isFunction,
keys = helpers.keys,
rearg = helpers.rearg,
spread = helpers.spread,
toInteger = helpers.toInteger,
toPath = helpers.toPath;

View File

@@ -9,7 +9,6 @@ module.exports = {
'iteratee': require('../iteratee'),
'keys': require('../_baseKeys'),
'rearg': require('../rearg'),
'spread': require('../spread'),
'toInteger': require('../toInteger'),
'toPath': require('../toPath')
};

View File

@@ -10853,9 +10853,6 @@
if (array) {
arrayPush(otherArgs, array);
}
if (start != lastIndex) {
arrayPush(otherArgs, castSlice(args, start + 1));
}
return apply(func, this, otherArgs);
});
}

View File

@@ -20870,10 +20870,11 @@
QUnit.test('should spread arguments to `func`', function(assert) {
assert.expect(2);
var spread = _.spread(fn);
var spread = _.spread(fn),
expected = [1, 2];
assert.deepEqual(spread([1, 2]), [1, 2]);
assert.deepEqual(spread([1, 2], 3), [1, 2, 3]);
assert.deepEqual(spread([1, 2]), expected);
assert.deepEqual(spread([1, 2], 3), expected);
});
QUnit.test('should accept a falsey `array`', function(assert) {
@@ -20894,10 +20895,11 @@
QUnit.test('should work with `start`', function(assert) {
assert.expect(2);
var spread = _.spread(fn, 1);
var spread = _.spread(fn, 1),
expected = [1, 2, 3];
assert.deepEqual(spread(1, [2, 3]), [1, 2, 3]);
assert.deepEqual(spread(1, [2, 3], 4), [1, 2, 3, 4]);
assert.deepEqual(spread(1, [2, 3]), expected);
assert.deepEqual(spread(1, [2, 3], 4), expected);
});
QUnit.test('should treat `start` as `0` for negative or `NaN` values', function(assert) {
@@ -20917,10 +20919,11 @@
QUnit.test('should coerce `start` to an integer', function(assert) {
assert.expect(2);
var spread = _.spread(fn, 1.6);
var spread = _.spread(fn, 1.6),
expected = [1, 2, 3];
assert.deepEqual(spread(1, [2, 3]), [1, 2, 3]);
assert.deepEqual(spread(1, [2, 3], 4), [1, 2, 3, 4]);
assert.deepEqual(spread(1, [2, 3]), expected);
assert.deepEqual(spread(1, [2, 3], 4), expected);
});
}());