From 46341fea9633f93d5f12935e6042727127834842 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 27 Dec 2014 21:51:13 -0600 Subject: [PATCH] Ensure `_.merge` handles source arrays with `undefined` values correctly with a `customizer`. --- lodash.js | 21 +++++++++++---------- test/test.js | 6 +++++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/lodash.js b/lodash.js index af44453c9..3be6d1dcf 100644 --- a/lodash.js +++ b/lodash.js @@ -2490,11 +2490,13 @@ value = object[key]; if (!(isArr || isObj)) { - result = customizer ? customizer(value, srcValue, key, object, source) : undefined; - if (typeof result == 'undefined') { + var result = customizer ? customizer(value, srcValue, key, object, source) : undefined, + isCommon = typeof result == 'undefined'; + + if (isCommon) { result = srcValue; } - if ((isSrcArr || typeof result != 'undefined') && !(customizer && result === value)) { + if ((isSrcArr || typeof result != 'undefined') && (isCommon || result !== value)) { object[key] = result; } return; @@ -2510,10 +2512,10 @@ return; } } - var result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isDeep = typeof result == 'undefined'; + result = customizer ? customizer(value, srcValue, key, object, source) : undefined; + isCommon = typeof result == 'undefined'; - if (isDeep) { + if (isCommon) { result = isArr ? (isArray(value) ? value : []) : (isPlainObject(value) ? value : {}); @@ -2524,10 +2526,9 @@ stackB.push(result); // Recursively merge objects and arrays (susceptible to call stack limits). - if (isDeep) { - baseMerge(result, srcValue, customizer, stackA, stackB); - } - if (!(customizer && result === value)) { + if (isCommon) { + object[key] = baseMerge(result, srcValue, customizer, stackA, stackB); + } else if (result !== value) { object[key] = result; } }); diff --git a/test/test.js b/test/test.js index eb294592b..471113d53 100644 --- a/test/test.js +++ b/test/test.js @@ -8478,15 +8478,19 @@ deepEqual(actual, { 'a': 1 }); }); - test('should handle merging if `customizer` returns `undefined`', 1, function() { + test('should handle merging if `customizer` returns `undefined`', 2, function() { var actual = _.merge({ 'a': { 'b': [1, 1] } }, { 'a': { 'b': [0] } }, _.noop); deepEqual(actual, { 'a': { 'b': [0, 1] } }); + + actual = _.merge([], [undefined], _.identity); + deepEqual(actual, [undefined]); }); test('should defer to `customizer` when it returns a value other than `undefined`', 1, function() { var actual = _.merge({ 'a': { 'b': [0, 1] } }, { 'a': { 'b': [2] } }, function(a, b) { return _.isArray(a) ? a.concat(b) : undefined; }); + deepEqual(actual, { 'a': { 'b': [0, 1, 2] } }); }); }(1, 2, 3));