mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-10 19:07:49 +00:00
Ensure "Arrays" and "Objects" methods work with arguments objects and arrays respectively.
Former-commit-id: aebb7a0004d804b7fd43d73e24d1da28c67f4059
This commit is contained in:
14
build.js
14
build.js
@@ -168,7 +168,7 @@
|
|||||||
'times': ['createCallback'],
|
'times': ['createCallback'],
|
||||||
'toArray': ['isString', 'values'],
|
'toArray': ['isString', 'values'],
|
||||||
'unescape': [],
|
'unescape': [],
|
||||||
'union': ['uniq'],
|
'union': ['isArray', 'uniq'],
|
||||||
'uniq': ['createCallback', 'indexOf'],
|
'uniq': ['createCallback', 'indexOf'],
|
||||||
'uniqueId': [],
|
'uniqueId': [],
|
||||||
'unzip': ['max', 'pluck'],
|
'unzip': ['max', 'pluck'],
|
||||||
@@ -2030,12 +2030,12 @@
|
|||||||
'function difference(array) {',
|
'function difference(array) {',
|
||||||
' var index = -1,',
|
' var index = -1,',
|
||||||
' length = array.length,',
|
' length = array.length,',
|
||||||
' flattened = concat.apply(arrayRef, arguments),',
|
' flattened = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),',
|
||||||
' result = [];',
|
' result = [];',
|
||||||
'',
|
'',
|
||||||
' while (++index < length) {',
|
' while (++index < length) {',
|
||||||
' var value = array[index];',
|
' var value = array[index];',
|
||||||
' if (indexOf(flattened, value, length) < 0) {',
|
' if (indexOf(flattened, value) < 0) {',
|
||||||
' result.push(value);',
|
' result.push(value);',
|
||||||
' }',
|
' }',
|
||||||
' }',
|
' }',
|
||||||
@@ -2219,11 +2219,11 @@
|
|||||||
// replace `_.omit`
|
// replace `_.omit`
|
||||||
source = replaceFunction(source, 'omit', [
|
source = replaceFunction(source, 'omit', [
|
||||||
'function omit(object) {',
|
'function omit(object) {',
|
||||||
' var props = concat.apply(arrayRef, arguments),',
|
' var props = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),',
|
||||||
' result = {};',
|
' result = {};',
|
||||||
'',
|
'',
|
||||||
' forIn(object, function(value, key) {',
|
' forIn(object, function(value, key) {',
|
||||||
' if (indexOf(props, key, 1) < 0) {',
|
' if (indexOf(props, key) < 0) {',
|
||||||
' result[key] = value;',
|
' result[key] = value;',
|
||||||
' }',
|
' }',
|
||||||
' });',
|
' });',
|
||||||
@@ -2234,8 +2234,8 @@
|
|||||||
// replace `_.pick`
|
// replace `_.pick`
|
||||||
source = replaceFunction(source, 'pick', [
|
source = replaceFunction(source, 'pick', [
|
||||||
'function pick(object) {',
|
'function pick(object) {',
|
||||||
' var index = 0,',
|
' var index = -1,',
|
||||||
' props = concat.apply(arrayRef, arguments),',
|
' props = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),',
|
||||||
' length = props.length,',
|
' length = props.length,',
|
||||||
' result = {};',
|
' result = {};',
|
||||||
'',
|
'',
|
||||||
|
|||||||
34
lodash.js
34
lodash.js
@@ -580,16 +580,15 @@
|
|||||||
* @private
|
* @private
|
||||||
* @param {Array} array The array to search.
|
* @param {Array} array The array to search.
|
||||||
* @param {Mixed} value The value to search for.
|
* @param {Mixed} value The value to search for.
|
||||||
* @param {Number} fromIndex The index to search from.
|
|
||||||
* @returns {Boolean} Returns `true`, if `value` is found, else `false`.
|
* @returns {Boolean} Returns `true`, if `value` is found, else `false`.
|
||||||
*/
|
*/
|
||||||
function cachedContains(array, fromIndex) {
|
function cachedContains(array) {
|
||||||
var length = array.length,
|
var length = array.length,
|
||||||
isLarge = (length - fromIndex) >= largeArraySize;
|
isLarge = length >= largeArraySize;
|
||||||
|
|
||||||
if (isLarge) {
|
if (isLarge) {
|
||||||
var cache = {},
|
var cache = {},
|
||||||
index = fromIndex - 1;
|
index = -1;
|
||||||
|
|
||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
var key = keyPrefix + array[index];
|
var key = keyPrefix + array[index];
|
||||||
@@ -601,7 +600,7 @@
|
|||||||
var key = keyPrefix + value;
|
var key = keyPrefix + value;
|
||||||
return cache[key] && indexOf(cache[key], value) > -1;
|
return cache[key] && indexOf(cache[key], value) > -1;
|
||||||
}
|
}
|
||||||
return indexOf(array, value, fromIndex) > -1;
|
return indexOf(array, value) > -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2111,12 +2110,12 @@
|
|||||||
if (isFunc) {
|
if (isFunc) {
|
||||||
callback = lodash.createCallback(callback, thisArg);
|
callback = lodash.createCallback(callback, thisArg);
|
||||||
} else {
|
} else {
|
||||||
var props = concat.apply(arrayRef, arguments);
|
var props = concat.apply(arrayRef, nativeSlice.call(arguments, 1));
|
||||||
}
|
}
|
||||||
forIn(object, function(value, key, object) {
|
forIn(object, function(value, key, object) {
|
||||||
if (isFunc
|
if (isFunc
|
||||||
? !callback(value, key, object)
|
? !callback(value, key, object)
|
||||||
: indexOf(props, key, 1) < 0
|
: indexOf(props, key) < 0
|
||||||
) {
|
) {
|
||||||
result[key] = value;
|
result[key] = value;
|
||||||
}
|
}
|
||||||
@@ -2179,8 +2178,8 @@
|
|||||||
function pick(object, callback, thisArg) {
|
function pick(object, callback, thisArg) {
|
||||||
var result = {};
|
var result = {};
|
||||||
if (typeof callback != 'function') {
|
if (typeof callback != 'function') {
|
||||||
var index = 0,
|
var index = -1,
|
||||||
props = concat.apply(arrayRef, arguments),
|
props = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
|
||||||
length = isObject(object) ? props.length : 0;
|
length = isObject(object) ? props.length : 0;
|
||||||
|
|
||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
@@ -3292,8 +3291,8 @@
|
|||||||
function difference(array) {
|
function difference(array) {
|
||||||
var index = -1,
|
var index = -1,
|
||||||
length = array ? array.length : 0,
|
length = array ? array.length : 0,
|
||||||
flattened = concat.apply(arrayRef, arguments),
|
flattened = concat.apply(arrayRef, nativeSlice.call(arguments, 1)),
|
||||||
contains = cachedContains(flattened, length),
|
contains = cachedContains(flattened),
|
||||||
result = [];
|
result = [];
|
||||||
|
|
||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
@@ -3643,7 +3642,7 @@
|
|||||||
}
|
}
|
||||||
var argsIndex = argsLength;
|
var argsIndex = argsLength;
|
||||||
while (--argsIndex) {
|
while (--argsIndex) {
|
||||||
if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(args[argsIndex], 0)))(value)) {
|
if (!(cache[argsIndex] || (cache[argsIndex] = cachedContains(args[argsIndex])))(value)) {
|
||||||
continue outer;
|
continue outer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3967,8 +3966,11 @@
|
|||||||
* _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
|
* _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
|
||||||
* // => [1, 2, 3, 101, 10]
|
* // => [1, 2, 3, 101, 10]
|
||||||
*/
|
*/
|
||||||
function union() {
|
function union(array) {
|
||||||
return uniq(concat.apply(arrayRef, arguments));
|
return uniq(isArray(array)
|
||||||
|
? concat.apply(arrayRef, arguments)
|
||||||
|
: concat.apply(array ? nativeSlice.call(array) : arrayRef, nativeSlice.call(arguments, 1))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -4258,8 +4260,8 @@
|
|||||||
* // => alerts 'clicked docs', when the button is clicked
|
* // => alerts 'clicked docs', when the button is clicked
|
||||||
*/
|
*/
|
||||||
function bindAll(object) {
|
function bindAll(object) {
|
||||||
var funcs = concat.apply(arrayRef, arguments),
|
var funcs = arguments.length > 1 ? concat.apply(arrayRef, nativeSlice.call(arguments, 1)) : functions(object),
|
||||||
index = funcs.length > 1 ? 0 : (funcs = functions(object), -1),
|
index = -1,
|
||||||
length = funcs.length;
|
length = funcs.length;
|
||||||
|
|
||||||
while (++index < length) {
|
while (++index < length) {
|
||||||
|
|||||||
84
test/test.js
84
test/test.js
@@ -196,6 +196,8 @@
|
|||||||
QUnit.module('lodash.at');
|
QUnit.module('lodash.at');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
|
var args = arguments;
|
||||||
|
|
||||||
test('should return `undefined` for nonexistent keys', function() {
|
test('should return `undefined` for nonexistent keys', function() {
|
||||||
var actual = _.at(['a', 'b', 'c'], [0, 2, 4]);
|
var actual = _.at(['a', 'b', 'c'], [0, 2, 4]);
|
||||||
deepEqual(actual, ['a', 'c', undefined]);
|
deepEqual(actual, ['a', 'c', undefined]);
|
||||||
@@ -210,6 +212,11 @@
|
|||||||
deepEqual(actual, ['a', 'c', 'd']);
|
deepEqual(actual, ['a', 'c', 'd']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should work with an `arguments` object for `collection`', function() {
|
||||||
|
var actual = _.at(args, [0, 2]);
|
||||||
|
deepEqual(actual, ['a', 'c']);
|
||||||
|
});
|
||||||
|
|
||||||
test('should work with an object for `collection`', function() {
|
test('should work with an object for `collection`', function() {
|
||||||
var actual = _.at({ 'a': 1, 'b': 2, 'c': 3 }, ['a', 'c']);
|
var actual = _.at({ 'a': 1, 'b': 2, 'c': 3 }, ['a', 'c']);
|
||||||
deepEqual(actual, [1, 3]);
|
deepEqual(actual, [1, 3]);
|
||||||
@@ -224,7 +231,7 @@
|
|||||||
deepEqual(_.at(collection, [0, 2]), ['a', 'c']);
|
deepEqual(_.at(collection, [0, 2]), ['a', 'c']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}());
|
}('a', 'b', 'c'));
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@@ -295,6 +302,12 @@
|
|||||||
|
|
||||||
deepEqual(actual, [1, 2, 3, undefined]);
|
deepEqual(actual, [1, 2, 3, undefined]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should work with an array `object` argument', function() {
|
||||||
|
var array = ['push', 'pop'];
|
||||||
|
_.bindAll(array);
|
||||||
|
equal(array.pop, Array.prototype.pop);
|
||||||
|
});
|
||||||
}());
|
}());
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
@@ -334,7 +347,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
var objects = {
|
var objects = {
|
||||||
'an arguments object': arguments,
|
'an `arguments` object': arguments,
|
||||||
'an array': ['a', 'b', 'c', ''],
|
'an array': ['a', 'b', 'c', ''],
|
||||||
'an array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 },
|
'an array-like-object': { '0': 'a', '1': 'b', '2': 'c', '3': '', 'length': 5 },
|
||||||
'boolean': false,
|
'boolean': false,
|
||||||
@@ -1900,6 +1913,10 @@
|
|||||||
deepEqual(_.omit(new Foo, 'a'), expected);
|
deepEqual(_.omit(new Foo, 'a'), expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should work with an array `object` argument', function() {
|
||||||
|
deepEqual(_.omit([1, 2, 3], '0', '2'), { '1': 2 });
|
||||||
|
});
|
||||||
|
|
||||||
test('should work with a `callback` argument', function() {
|
test('should work with a `callback` argument', function() {
|
||||||
var actual = _.omit(object, function(value) {
|
var actual = _.omit(object, function(value) {
|
||||||
return value == 1;
|
return value == 1;
|
||||||
@@ -2024,6 +2041,10 @@
|
|||||||
deepEqual(_.pick(new Foo, 'b'), { 'b': 2 });
|
deepEqual(_.pick(new Foo, 'b'), { 'b': 2 });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should work with an array `object` argument', function() {
|
||||||
|
deepEqual(_.pick([1, 2, 3], '1'), { '1': 2 });
|
||||||
|
});
|
||||||
|
|
||||||
test('should work with a `callback` argument', function() {
|
test('should work with a `callback` argument', function() {
|
||||||
var actual = _.pick(object, function(value) {
|
var actual = _.pick(object, function(value) {
|
||||||
return value == 2;
|
return value == 2;
|
||||||
@@ -2855,6 +2876,19 @@
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
QUnit.module('lodash.union');
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
test('should produce correct results when passed a falsey `array` argument', function() {
|
||||||
|
var expected = [1, 2, 3],
|
||||||
|
actual = _.union(null, expected);
|
||||||
|
|
||||||
|
deepEqual(actual, expected);
|
||||||
|
});
|
||||||
|
}());
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
QUnit.module('lodash.uniq');
|
QUnit.module('lodash.uniq');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
@@ -2867,10 +2901,14 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('should distinguish between numbers and numeric strings', function() {
|
test('should distinguish between numbers and numeric strings', function() {
|
||||||
var expected = ['2', 2, Object('2'), Object(2)],
|
var array = [],
|
||||||
actual = _.uniq(expected);
|
expected = ['2', 2, Object('2'), Object(2)];
|
||||||
|
|
||||||
deepEqual(actual, expected);
|
_.times(50, function() {
|
||||||
|
array.push.apply(array, expected);
|
||||||
|
});
|
||||||
|
|
||||||
|
deepEqual(_.uniq(expected), expected);
|
||||||
});
|
});
|
||||||
|
|
||||||
_.each({
|
_.each({
|
||||||
@@ -3167,6 +3205,37 @@
|
|||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
QUnit.module('"Arrays" methods');
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var args = arguments;
|
||||||
|
|
||||||
|
test('should work with `arguments` objects', function() {
|
||||||
|
function message(methodName) {
|
||||||
|
return '_.' + methodName + ' should work with `arguments` objects';
|
||||||
|
}
|
||||||
|
|
||||||
|
deepEqual(_.compact(args), [1, [3], 5], message('compact'));
|
||||||
|
deepEqual(_.difference(args, [null]), [1, [3], 5], message('difference'));
|
||||||
|
deepEqual(_.findIndex(args, _.identity), 0, message('findIndex'));
|
||||||
|
deepEqual(_.first(args), 1, message('first'));
|
||||||
|
deepEqual(_.flatten(args), [1, null, 3, null, 5], message('flatten'));
|
||||||
|
deepEqual(_.indexOf(args, 5), 4, message('indexOf'));
|
||||||
|
deepEqual(_.initial(args, 4), [1], message('initial'));
|
||||||
|
deepEqual(_.intersection(args, [1]), [1], message('intersection'));
|
||||||
|
deepEqual(_.last(args), 5, message('last'));
|
||||||
|
deepEqual(_.lastIndexOf(args, 1), 0, message('lastIndexOf'));
|
||||||
|
deepEqual(_.rest(args, 4), [5], message('rest'));
|
||||||
|
deepEqual(_.sortedIndex(args, 6), 5, message('sortedIndex'));
|
||||||
|
deepEqual(_.union(args, [null, 6]), [1, null, [3], 5, 6], message('union'));
|
||||||
|
deepEqual(_.uniq(args), [1, null, [3], 5], message('uniq'));
|
||||||
|
deepEqual(_.without(args, null), [1, [3], 5], message('without'));
|
||||||
|
deepEqual(_.zip(args, args), [[1, 1], [null, null], [[3], [3]], [null, null], [5, 5]], message('zip'));
|
||||||
|
});
|
||||||
|
}(1, null, [3], null, 5));
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
QUnit.module('lodash methods');
|
QUnit.module('lodash methods');
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
@@ -3227,13 +3296,10 @@
|
|||||||
|
|
||||||
_.each(funcs, function(methodName) {
|
_.each(funcs, function(methodName) {
|
||||||
var actual = [],
|
var actual = [],
|
||||||
|
expected = _.map(falsey, function() { return []; }),
|
||||||
func = _[methodName],
|
func = _[methodName],
|
||||||
pass = true;
|
pass = true;
|
||||||
|
|
||||||
var expected = (methodName == 'union')
|
|
||||||
? _.map(falsey, function(value, index) { return index ? [value] : []; })
|
|
||||||
: _.map(falsey, function() { return []; });
|
|
||||||
|
|
||||||
_.each(falsey, function(value, index) {
|
_.each(falsey, function(value, index) {
|
||||||
try {
|
try {
|
||||||
actual.push(index ? func(value) : func());
|
actual.push(index ? func(value) : func());
|
||||||
|
|||||||
Reference in New Issue
Block a user