@empathyco/x-deep-merge
Version:
Utility for deep cloning objects.
162 lines • 7.08 kB
JavaScript
import { deepMerge, deepMergeBehaviour, replaceBehaviour } from '../deep-merge';
describe('deep-merge.ts', function () {
it('copies simple objects', function () {
var target = {};
var source = { a: 1, b: '2', c: true, d: null, e: undefined };
deepMerge(target, source);
expect(target).toEqual(source);
});
it('overrides with null and undefined values', function () {
var target = { a: 1, b: 1 };
var source = { a: null, b: undefined };
deepMerge(target, source);
expect(target).toEqual(source);
});
it('clones deep objects', function () {
var target = {};
var source = { a: { b: { c: 1 } } };
deepMerge(target, source);
expect(target.a.b).not.toBe(source.a.b);
expect(target).toEqual(source);
});
it('assigns objects value in received order', function () {
var target = {};
var firstSource = { a: 1 };
var secondSource = { a: 2 };
var thirdSource = { a: 3 };
deepMerge(target, firstSource, secondSource, thirdSource);
expect(target.a).toEqual(thirdSource.a);
});
it('assigns all values from sources without mutating them', function () {
var target = {};
var firstSource = { a: { value: 1 } };
var secondSource = { b: { value: 2 } };
var thirdSource = { c: { value: 3 } };
deepMerge(target, firstSource, secondSource, thirdSource);
expect(firstSource).not.toHaveProperty('b');
expect(firstSource).not.toHaveProperty('c');
expect(secondSource).not.toHaveProperty('c');
expect(target).toEqual({
a: { value: 1 },
b: { value: 2 },
c: { value: 3 },
});
});
it('overrides deeply nested objects', function () {
var target = {};
var firstSource = { a: { value: 1 } };
var secondSource = { b: { value: 2 } };
var thirdSource = { a: { value: 3 } };
deepMerge(target, firstSource, secondSource, thirdSource);
expect(target).toEqual({
a: { value: 3 },
b: { value: 2 },
});
});
it('extends deeply nested objects', function () {
var target = {};
var firstSource = { a: { value: 1 } };
var secondSource = { a: { newValue: 2 } };
deepMerge(target, firstSource, secondSource);
expect(target).toEqual({
a: { value: 1, newValue: 2 },
});
});
it('clones and replaces arrays', function () {
var target = { arr: [1, 2, 3] };
var source = { arr: [4, 5] };
deepMerge(target, source);
expect(target).toEqual({ arr: [4, 5] });
expect(target.arr).not.toBe(source.arr);
});
it('modifies the target', function () {
var target = {};
var source = { a: { b: { c: 1 } } };
var returnedTarget = deepMerge(target, source);
expect(returnedTarget).toBe(target);
});
it('does nothing and does not crash if a source object is undefined or null', function () {
var target = { a: 1 };
var firstSource = undefined;
var secondSource = null;
var thirdSource = { a: 2, b: 3 };
deepMerge(target, firstSource, secondSource, thirdSource);
expect(target).toEqual({ a: 2, b: 3 });
});
it('removes target object properties if they are `undefined` in the source object', function () {
var target = {
a: 1,
b: 'b',
c: [1, 2, 3],
d: { d1: 5 },
f: { f1: 'f1', f2: 'f2' },
};
var firstSource = { a: undefined, b: undefined };
var secondSource = { c: undefined, d: undefined };
var thirdSource = { f: { f1: undefined, f2: 'f2' } };
deepMerge(target, firstSource, secondSource, thirdSource);
expect(target).toEqual({ f: { f2: 'f2' } });
});
it('does not remove target object properties if they are `null` in the source object', function () {
var target = { a: 1, b: 'b', c: [1, 2, 3], d: { d1: 5 } };
var firstSource = { a: null, b: undefined };
var secondSource = { c: null, d: undefined };
deepMerge(target, firstSource, secondSource);
expect(target).toEqual({ a: null, c: null });
});
it('merges into a new object if target is undefined', function () {
var target = undefined;
var firstSource = { a: 1, b: 2 };
var result = deepMerge(target, firstSource);
expect(result).toEqual({ a: 1, b: 2 });
});
it('fully replaces object if replace behaviour is selected on source object', function () {
var target = { children: { a: 1, b: 2, c: 3 } };
var firstSource = { children: replaceBehaviour({ c: 4, d: 5 }) };
deepMerge(target, firstSource);
expect(target).toEqual({ children: { c: 4, d: 5 } });
});
it('makes a copy of the object when replacing, to avoid unexpected modifications', function () {
var target = { children: { a: 1, b: 2, c: 3 } };
var firstSource = { children: replaceBehaviour({ c: 4, d: 5 }) };
deepMerge(target, firstSource);
expect(target.children).not.toBe(firstSource.children);
});
it("passes replace behaviour to the sources objects if it's present in target object", function () {
var target = { children: replaceBehaviour({ a: 1, b: 2, c: 3 }) };
var firstSource = { children: { c: 4, d: 5 } };
var secondSource = { children: { e: 5, f: 6 } };
deepMerge(target, firstSource, secondSource);
expect(target).toEqual({ children: { e: 5, f: 6 } });
});
it('stops passing replace behaviour to the sources objects if deep-merge behaviour is specified', function () {
var target = { children: replaceBehaviour({ a: 1, b: 2, c: 3 }) };
var firstSource = { children: deepMergeBehaviour({ c: 4, d: 5 }) };
var secondSource = { children: { e: 5, f: 6 } };
deepMerge(target, firstSource, secondSource);
expect(target).toEqual({
children: { a: 1, b: 2, c: 4, d: 5, e: 5, f: 6 },
});
});
it('replaces the target which contains a function', function () {
var target = { a: function () { return undefined; } };
deepMerge(target, { a: { a1: 'h1' } });
expect(target).toEqual({ a: { a1: 'h1' } });
});
it('replaces the target which contains a string', function () {
var target = { a: 'test' };
deepMerge(target, { a: { a1: 'h1' } });
expect(target).toEqual({ a: { a1: 'h1' } });
});
it('replaces the target which contains a boolean', function () {
var target = { a: true };
deepMerge(target, { a: { a1: 'h1' } });
expect(target).toEqual({ a: { a1: 'h1' } });
});
it('replaces the target which contains a number', function () {
var target = { a: 123 };
deepMerge(target, { a: { a1: 'h1' } });
expect(target).toEqual({ a: { a1: 'h1' } });
});
});
//# sourceMappingURL=deep-merge.spec.js.map