diff --git a/lodash.js b/lodash.js index 4d7b7fbaf..ff67831a0 100644 --- a/lodash.js +++ b/lodash.js @@ -4320,24 +4320,22 @@ * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }] */ function first(array, callback, thisArg) { - if (array) { - var n = 0, - length = array.length; + var n = 0, + length = array ? array.length : 0; - if (typeof callback != 'number' && callback != null) { - var index = -1; - callback = lodash.createCallback(callback, thisArg, 3); - while (++index < length && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array[0]; - } + if (typeof callback != 'number' && callback != null) { + var index = -1; + callback = lodash.createCallback(callback, thisArg, 3); + while (++index < length && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[0] : undefined; } - return slice(array, 0, nativeMin(nativeMax(0, n), length)); } + return slice(array, 0, nativeMin(nativeMax(0, n), length)); } /** @@ -4485,11 +4483,8 @@ * // => [{ 'name': 'banana', 'type': 'fruit' }] */ function initial(array, callback, thisArg) { - if (!array) { - return []; - } var n = 0, - length = array.length; + length = array ? array.length : 0; if (typeof callback != 'number' && callback != null) { var index = length; @@ -4618,24 +4613,22 @@ * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }] */ function last(array, callback, thisArg) { - if (array) { - var n = 0, - length = array.length; + var n = 0, + length = array ? array.length : 0; - if (typeof callback != 'number' && callback != null) { - var index = length; - callback = lodash.createCallback(callback, thisArg, 3); - while (index-- && callback(array[index], index, array)) { - n++; - } - } else { - n = callback; - if (n == null || thisArg) { - return array[length - 1]; - } + if (typeof callback != 'number' && callback != null) { + var index = length; + callback = lodash.createCallback(callback, thisArg, 3); + while (index-- && callback(array[index], index, array)) { + n++; + } + } else { + n = callback; + if (n == null || thisArg) { + return array ? array[length - 1] : undefined; } - return slice(array, nativeMax(0, length - n)); } + return slice(array, nativeMax(0, length - n)); } /** diff --git a/test/test.js b/test/test.js index 7d688efb4..f8d8137bc 100644 --- a/test/test.js +++ b/test/test.js @@ -4380,7 +4380,7 @@ ]; _.forEach(funcs, function(methodName) { - test('`_.' + methodName + '` should return an unwrapped value', function() { + test('`_(...).' + methodName + '` should return an unwrapped value', function() { var result = methodName == 'reduceRight' ? wrapped[methodName](_.identity) : wrapped[methodName](); @@ -4400,17 +4400,46 @@ var funcs = [ 'first', - 'last' + 'last', + 'sample' ]; _.forEach(funcs, function(methodName) { - test('`_.' + methodName + '` should return an unwrapped value', function() { + test('`_(...).' + methodName + '` called without an `n` argument should return an unwrapped value', function() { equal(typeof wrapped[methodName](), 'number'); }); - test('`_.' + methodName + '` should return a wrapped value', function() { + test('`_(...).' + methodName + '` called with an `n` argument should return a wrapped value', function() { ok(wrapped[methodName](1) instanceof _); }); + + test('`_.' + methodName + '` should return `undefined` when querying falsey arguments without an `n` argument', function() { + var actual = [], + expected = _.map(falsey, function() { return undefined; }), + func = _[methodName]; + + _.forEach(falsey, function(value, index) { + try { + actual.push(index ? func(value) : func()); + } catch(e) { console.log(e)} + }); + + deepEqual(actual, expected); + }); + + test('`_.' + methodName + '` should return an empty array when querying falsey arguments with an `n` argument', function() { + var actual = [], + expected = _.map(falsey, function() { return []; }), + func = _[methodName]; + + _.forEach(falsey, function(value, index) { + try { + actual.push(func(value, 2)); + } catch(e) { } + }); + + deepEqual(actual, expected); + }); }); }());