Ensure _.assign and _.merge don't assign the customizer result if it is the same as the destination value.

This commit is contained in:
John-David Dalton
2014-12-27 19:42:10 -06:00
parent 7f823fe2a8
commit fa2058ec77
2 changed files with 35 additions and 9 deletions

View File

@@ -1691,9 +1691,15 @@
while (++index < length) {
var key = props[index];
object[key] = customizer
? customizer(object[key], source[key], key, object, source)
: source[key];
if (customizer) {
var value = object[key],
result = customizer(value, source[key], key, object, source);
} else {
result = source[key];
}
if (!(customizer && result === value)) {
object[key] = result;
}
}
return object;
}
@@ -2487,7 +2493,7 @@
if (typeof result == 'undefined') {
result = srcValue;
}
if (isSrcArr || typeof result != 'undefined') {
if ((isSrcArr || typeof result != 'undefined') && !(customizer && result === value)) {
object[key] = result;
}
return;
@@ -2520,7 +2526,9 @@
if (isDeep) {
baseMerge(result, srcValue, customizer, stackA, stackB);
}
object[key] = result;
if (!(customizer && result === value)) {
object[key] = result;
}
});
return object;
}

View File

@@ -3576,10 +3576,10 @@
var func = _[methodName];
test('`_.' + methodName + '` should ' + (isStrict ? '' : 'not ') + 'throw strict mode errors', 1, function() {
var object = { 'a': null, 'b': function() {} },
pass = !isStrict;
if (freeze) {
var object = { 'a': null, 'b': function() {} },
pass = !isStrict;
freeze(object);
try {
if (methodName == 'bindAll') {
@@ -4771,7 +4771,7 @@
deepEqual(argsList, expected, 'non-primitive property values');
});
test('`_.' + methodName + '`should support the `thisArg` argument', 1, function() {
test('`_.' + methodName + '` should support the `thisArg` argument', 1, function() {
var actual = func({}, { 'a': 0 }, function(a, b) {
return this[b];
}, [2]);
@@ -4789,6 +4789,24 @@
actual = func({ 'a': 1 }, callback, { 'c': 3 });
deepEqual(actual, { 'a': 1, 'b': 2, 'c': 3 });
});
test('`_.' + methodName + '` should not assign the `customizer` result if it is the same as the destination value', 1, function() {
if (defineProperty) {
var object = {},
pass = true;
defineProperty(object, 'a', {
'get': _.constant({}),
'set': function() { pass = false; }
});
func(object, { 'a': object.a }, _.identity);
ok(pass);
}
else {
skipTest();
}
});
});
/*--------------------------------------------------------------------------*/