Skip to content

Commit

Permalink
fix: assign-deep to not modify following arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
medikoo committed Aug 13, 2018
1 parent 2a89258 commit bf43d57
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 15 deletions.
26 changes: 11 additions & 15 deletions object/assign-deep.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,28 @@

var includes = require("../array/#/contains")
, uniq = require("../array/#/uniq")
, copyDeep = require("./copy-deep")
, objForEach = require("./for-each")
, isPlainObject = require("./is-plain-object")
, ensureValue = require("./valid-value");

var isArray = Array.isArray, slice = Array.prototype.slice;

var assignObject = function (target, source) {
// eslint-disable-next-line no-use-before-define
objForEach(source, function (value, key) { target[key] = deepAssign(target[key], value); });
};

var assignArray = function (target, source) {
source.forEach(function (item) { if (!includes.call(target, item)) target.push(item); });
};

var deepAssign = function (target, source) {
if (isPlainObject(target)) {
if (!isPlainObject(source)) return source;
assignObject(target, source);
if (target === source) return target;
if (isPlainObject(target) && isPlainObject(source)) {
objForEach(source, function (value, key) { target[key] = deepAssign(target[key], value); });
return target;
}
if (isArray(target)) {
if (!isArray(source)) return source;
assignArray(target, source);
if (isArray(target) && isArray(source)) {
source.forEach(function (item) {
if (includes.call(target, item)) return;
if (isArray(item) || isPlainObject(item)) item = copyDeep(item);
target.push(item);
});
return target;
}
if (isPlainObject(source) || isArray(source)) return copyDeep(source);
return source;
};

Expand Down
12 changes: 12 additions & 0 deletions test/object/assign-deep.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ module.exports = function (t, a) {

var obj1 = { foo: { bar: 3, marko: true } }
, obj2 = { foo: { elo: 12, marko: false }, miszka: [23] };

var copyObj1 = JSON.parse(JSON.stringify(obj1)), copyObj2 = JSON.parse(JSON.stringify(obj2));
a.deep(t({}, obj1, obj2), { foo: { bar: 3, marko: false, elo: 12 }, miszka: [23] });
// Ensure it's side effects free
a.deep(obj1, copyObj1);
a.deep(obj2, copyObj2);

obj1 = [{ foo: "bar" }];
var assignedObj = [];
t(assignedObj, obj1);
a.deep(assignedObj, [{ foo: "bar" }]);
// Ensure array items are copied and not passed
a.not(assignedObj[0], obj1[0]);
a(t(true), true);
};

0 comments on commit bf43d57

Please sign in to comment.