deepmerge2
Version:
A library for deep (recursive) merging of Javascript objects
331 lines (268 loc) • 6.25 kB
JavaScript
var merge = require('../')
var test = require('tap').test
test('add keys in target that do not exist at the root', function (t) {
var src = { key1: 'value1', key2: 'value2' };
target = {};
var res = merge(target, src);
t.deepEqual(target, {}, 'merge should be immutable');
t.deepEqual(res, src);
t.end();
});
test('merge existing simple keys in target at the roots', function (t) {
var src = { key1: 'changed', key2: 'value2' };
var target = { key1: 'value1', key3: 'value3' };
var expected = {
key1: 'changed',
key2: 'value2',
key3: 'value3'
};
t.deepEqual(target, { key1: 'value1', key3: 'value3' });
t.deepEqual(merge(target, src), expected);
t.end();
});
test('merge nested objects into target', function (t) {
var src = {
key1: {
subkey1: 'changed',
subkey3: 'added'
}
};
var target = {
key1: {
subkey1: 'value1',
subkey2: 'value2'
}
};
var expected = {
key1: {
subkey1: 'changed',
subkey2: 'value2',
subkey3: 'added'
}
};
t.deepEqual(target, {
key1: {
subkey1: 'value1',
subkey2: 'value2'
}
});
t.deepEqual(merge(target, src), expected);
t.end();
});
test('replace simple key with nested object in target', function (t) {
var src = {
key1: {
subkey1: 'subvalue1',
subkey2: 'subvalue2'
}
};
var target = {
key1: 'value1',
key2: 'value2'
};
var expected = {
key1: {
subkey1: 'subvalue1',
subkey2: 'subvalue2'
},
key2: 'value2'
};
t.deepEqual(target, { key1: 'value1', key2: 'value2' });
t.deepEqual(merge(target, src), expected);
t.end();
});
test('should add nested object in target', function(t) {
var src = {
"b": {
"c": {}
}
};
var target = {
"a": {}
};
var expected = {
"a": {},
"b": {
"c": {}
}
};
t.deepEqual(merge(target, src), expected);
t.end();
});
test('should replace object with simple key in target', function (t) {
var src = { key1: 'value1' }
var target = {
key1: {
subkey1: 'subvalue1',
subkey2: 'subvalue2'
},
key2: 'value2'
};
var expected = { key1: 'value1', key2: 'value2' };
t.deepEqual(target, {
key1: {
subkey1: 'subvalue1',
subkey2: 'subvalue2'
},
key2: 'value2'
});
t.deepEqual(merge(target, src), expected);
t.end();
});
test('should work on simple array', function (t) {
var src = ['one', 'three'];
var target = ['one', 'two'];
var expected = ['one', 'two', 'three'];
t.deepEqual(target, ['one', 'two']);
t.deepEqual(merge(target, src), expected);
t.ok(Array.isArray(merge(target, src)));
t.end();
});
test('should work on another simple array', function(t) {
var target = ["a1","a2","c1","f1","p1"];
var src = ["t1","s1","c2","r1","p2","p3"];
var expected = ["a1", "a2", "c1", "f1", "p1", "t1", "s1", "c2", "r1", "p2", "p3"];
t.deepEqual(target, ["a1", "a2", "c1", "f1", "p1"]);
t.deepEqual(merge(target, src), expected);
t.ok(Array.isArray(merge(target, src)));
t.end();
});
test('should work on array properties', function (t) {
var src = {
key1: ['one', 'three'],
key2: ['four']
};
var target = {
key1: ['one', 'two']
};
var expected = {
key1: ['one', 'two', 'three'],
key2: ['four']
};
t.deepEqual(target, {
key1: ['one', 'two']
});
t.deepEqual(merge(target, src), expected);
t.ok(Array.isArray(merge(target, src).key1));
t.ok(Array.isArray(merge(target, src).key2));
t.end();
});
test('should work on array of objects', function (t) {
var src = [
{ key1: ['one', 'three'], key2: ['one'] },
{ key3: ['five'] }
];
var target = [
{ key1: ['one', 'two'] },
{ key3: ['four'] }
];
var expected = [
{ key1: ['one', 'two', 'three'], key2: ['one'] },
{ key3: ['four', 'five'] }
];
t.deepEqual(target, [
{ key1: ['one', 'two'] },
{ key3: ['four'] }
]);
t.deepEqual(merge(target, src), expected);
t.ok(Array.isArray(merge(target, src)), 'result should be an array');
t.ok(Array.isArray(merge(target, src)[0].key1), 'subkey should be an array too');
t.end();
});
test('should work on arrays of nested objects', function(t) {
var target = [
{ key1: { subkey: 'one' }}
];
var src = [
{ key1: { subkey: 'two' }},
{ key2: { subkey: 'three' }}
];
var expected = [
{ key1: { subkey: 'two' }},
{ key2: { subkey: 'three' }}
];
t.deepEqual(merge(target, src), expected);
t.end();
})
test('should work on dates', function(t) {
var target = {
d1: new Date(2016, 10, 10),
d3: new Date(2015, 10, 10)
};
var src = {
d1: new Date(2014, 10, 10),
d2: new Date(2013, 10, 10)
};
var expected = {
d1: new Date(2014, 10, 10),
d2: new Date(2013, 10, 10),
d3: new Date(2015, 10, 10)
};
var result = merge(target, src);
for(var key in expected) {
t.assert(+expected[key] == +result[key], 'date invalid', {
payload: {
expected: expected[key],
result: result[key]
}
});
}
t.end();
});
test('should work on regular expressions', function(t) {
var target = {
r1: /foo/,
r3: /bar/
};
var src = {
r1: /baz/,
r2: /world/
};
var expected = {
r1: /baz/,
r2: /world/,
r3: /bar/
};
var result = merge(target, src);
for(var key in expected) {
t.assert(expected[key].toString() == result[key].toString(), 'regexp invalid', {
payload: {
expected: expected[key],
result: result[key]
}
});
}
t.end();
});
test('should work on multiple sources', function(t) {
var target = {
key1: 123,
key2: {
key3: 321
}
};
var sources = [
{ key1: 555 },
{ key3: 666 },
{ key2: { key4: 777 } },
{ key1: 888 }
];
var expected = {
key1: 888,
key2: {
key3: 321,
key4: 777
},
key3: 666
};
var result = merge.apply(null, [target].concat(sources));
t.deepEqual(result, expected);
t.end();
});
test('should work on array with null in it', function(t) {
var target = [1];
var src = [null];
var expected = [1, null];
t.deepEqual(merge(target, src), expected);
t.end();
});