From 445445603f08dbe06cc9dab46582f7fbf8e112cf Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 8 Mar 2014 13:16:47 -0800 Subject: [PATCH] Remove `_.isObject` dep from `_.merge` and ensure `_.assign` and `_.defaults` don't error when `object` is `null` or `undefined` and source objects are provided. --- lodash.js | 47 +++++++++++++++++++++++------------------------ test/test.js | 38 ++++++++++++++++++++++---------------- 2 files changed, 45 insertions(+), 40 deletions(-) diff --git a/lodash.js b/lodash.js index 802904960..538c05a90 100644 --- a/lodash.js +++ b/lodash.js @@ -5488,6 +5488,9 @@ * // => { 'name': 'barney', 'employer': 'slate' } */ function assign(object, source, guard) { + if (!object) { + return object; + } var args = arguments, argsIndex = 0, argsLength = args.length, @@ -5505,15 +5508,13 @@ } while (++argsIndex < argsLength) { source = args[argsIndex]; - if (isObject(source)) { - var index = -1, - props = keys(source), - length = props.length; + var index = -1, + props = keys(source), + length = props.length; - while (++index < length) { - var key = props[index]; - object[key] = callback ? callback(object[key], source[key]) : source[key]; - } + while (++index < length) { + var key = props[index]; + object[key] = callback ? callback(object[key], source[key]) : source[key]; } } return object; @@ -5684,6 +5685,9 @@ * // => { 'name': 'barney', 'employer': 'slate' } */ function defaults(object, source, guard) { + if (!object) { + return object; + } var args = arguments, argsIndex = 0, argsLength = args.length, @@ -5695,16 +5699,14 @@ } while (++argsIndex < argsLength) { source = args[argsIndex]; - if (isObject(source)) { - var index = -1, - props = keys(source), - length = props.length; + var index = -1, + props = keys(source), + length = props.length; - while (++index < length) { - var key = props[index]; - if (typeof object[key] == 'undefined') { - object[key] = source[key]; - } + while (++index < length) { + var key = props[index]; + if (typeof object[key] == 'undefined') { + object[key] = source[key]; } } } @@ -6503,14 +6505,11 @@ * // => ['x', 'y'] (property order is not guaranteed across environments) */ var keys = !nativeKeys ? shimKeys : function(object) { - if (!isObject(object)) { - return []; - } if ((support.enumPrototypes && typeof object == 'function') || - (support.nonEnumArgs && object.length && isArguments(object))) { + (support.nonEnumArgs && object && object.length && isArguments(object))) { return shimKeys(object); } - return nativeKeys(object); + return isObject(object) ? nativeKeys(object) : []; }; /** @@ -6538,7 +6537,7 @@ if (!isObject(object)) { return result; } - if (support.nonEnumArgs && typeof object.length == 'number' && isArguments(object)) { + if (support.nonEnumArgs && object.length && isArguments(object)) { object = slice(object); } var skipProto = support.enumPrototypes && typeof object == 'function', @@ -6671,7 +6670,7 @@ * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } */ function merge(object, source, guard) { - if (!isObject(object)) { + if (!object) { return object; } var args = arguments, diff --git a/test/test.js b/test/test.js index 10df0ce49..44994957e 100644 --- a/test/test.js +++ b/test/test.js @@ -647,14 +647,6 @@ deepEqual(_.assign({ 'a': 1, 'b': 2 }, expected), expected); }); - test('should not error on `null` or `undefined` sources (test in IE < 9)', 1, function() { - try { - deepEqual(_.assign({}, null, undefined, { 'a': 1 }), { 'a': 1 }); - } catch(e) { - ok(false); - } - }); - test('should work with a callback', 1, function() { var actual = _.assign({ 'a': 1, 'b': 2 }, { 'a': 3, 'c': 3 }, function(a, b) { return typeof a == 'undefined' ? b : a; @@ -1984,14 +1976,6 @@ var actual = _.defaults({ 'a': undefined }, { 'a': 1 }); strictEqual(actual.a, 1); }); - - test('should not error on `null` or `undefined` sources (test in IE < 9)', 1, function() { - try { - deepEqual(_.defaults({ 'a': 1 }, null, undefined, { 'a': 2, 'b': 2 }), { 'a': 1, 'b': 2 }); - } catch(e) { - ok(false); - } - }); }()); /*--------------------------------------------------------------------------*/ @@ -2977,6 +2961,28 @@ var array = [{ 'b': 2 }, { 'c': 3 }]; deepEqual(_.reduce(array, func, { 'a': 1}), { 'a': 1, 'b': 2, 'c': 3 }); }); + + test('`_.' + methodName + '` should not error on `null` or `undefined` sources (test in IE < 9)', 1, function() { + try { + deepEqual(func({ 'a': 1 }, undefined, { 'b': 2 }, null), { 'a': 1, 'b': 2 }); + } catch(e) { + ok(false); + } + }); + + test('`_.' + methodName + '` should not error when `object` is `null` or `undefined` and source objects are provided', 1, function() { + var expected = _.times(2, _.constant(true)); + + var actual = _.map([null, undefined], function(value) { + try { + return _.isEqual(func(value, { 'a': 1 }), value); + } catch(e) { + return false; + } + }); + + deepEqual(actual, expected); + }); }); _.forEach(['assign', 'merge'], function(methodName) {