Skip to main content
Go to Latest
File
import { assertEquals } from "../testing/asserts.ts";import { deepMerge } from "./deep_merge.ts";
Deno.test("deepMerge: simple merge", () => { assertEquals( deepMerge({ foo: true, }, { bar: true, }), { foo: true, bar: true, }, );});
Deno.test("deepMerge: symbol merge", () => { assertEquals( deepMerge({}, { [Symbol.for("deepmerge.test")]: true, }), { [Symbol.for("deepmerge.test")]: true, }, );});
Deno.test("deepMerge: ignore non enumerable", () => { assertEquals( deepMerge( {}, Object.defineProperties({}, { foo: { enumerable: false, value: true }, bar: { enumerable: true, value: true }, }), ), { bar: true, }, );});
Deno.test("deepMerge: nested merge", () => { assertEquals( deepMerge({ foo: { bar: true, }, }, { foo: { baz: true, quux: {}, }, qux: true, }), { foo: { bar: true, baz: true, quux: {}, }, qux: true, }, );});
Deno.test("deepMerge: prevent prototype merge", () => { assertEquals( deepMerge({ constructor: undefined, }, { foo: true, }), { constructor: undefined, foo: true, }, );});
Deno.test("deepMerge: override target (non-mergeable source)", () => { assertEquals( deepMerge({ foo: { bar: true, }, }, { foo: true, }), { foo: true, }, );});
Deno.test("deepMerge: override target (non-mergeable destination, object like)", () => { const CustomClass = class {}; assertEquals( deepMerge({ foo: new CustomClass(), }, { foo: true, }), { foo: true, }, );});
Deno.test("deepMerge: override target (non-mergeable destination, array like)", () => { assertEquals( deepMerge({ foo: [], }, { foo: true, }), { foo: true, }, );});
Deno.test("deepMerge: override target (different object like source and destination)", () => { assertEquals( deepMerge({ foo: {}, }, { foo: [1, 2], }), { foo: [1, 2], }, ); assertEquals( deepMerge({ foo: [], }, { foo: { bar: true }, }), { foo: { bar: true }, }, );});
Deno.test("deepMerge: primitive types handling", () => { const CustomClass = class {}; const expected = { boolean: true, null: null, undefined: undefined, number: 1, bigint: 1n, string: "string", symbol: Symbol.for("deepmerge.test"), object: { foo: true }, regexp: /regex/, date: new Date(), function() {}, async async() {}, arrow: () => {}, class: new CustomClass(), get get() { return true; }, }; assertEquals( deepMerge({ boolean: false, null: undefined, undefined: null, number: -1, bigint: -1n, string: "foo", symbol: Symbol(), object: null, regexp: /foo/, date: new Date(0), function: function () {}, async: async function () {}, arrow: () => {}, class: null, get: false, }, expected), expected, );});
Deno.test("deepMerge: array merge (replace)", () => { assertEquals( deepMerge({ foo: [1, 2, 3], }, { foo: [4, 5, 6], }, { arrays: "replace" }), { foo: [4, 5, 6], }, );});
Deno.test("deepMerge: array merge (merge)", () => { assertEquals( deepMerge({ foo: [1, 2, 3], }, { foo: [4, 5, 6], }, { arrays: "merge" }), { foo: [1, 2, 3, 4, 5, 6], }, );});
Deno.test("deepMerge: maps merge (replace)", () => { assertEquals( deepMerge({ map: new Map([["foo", true]]), }, { map: new Map([["bar", true]]), }, { maps: "replace" }), { map: new Map([["bar", true]]), }, );});
Deno.test("deepMerge: maps merge (merge)", () => { assertEquals( deepMerge({ map: new Map([["foo", true]]), }, { map: new Map([["bar", true]]), }, { maps: "merge" }), { map: new Map([["foo", true], ["bar", true]]), }, );});
Deno.test("deepMerge: sets merge (replace)", () => { assertEquals( deepMerge({ set: new Set(["foo"]), }, { set: new Set(["bar"]), }, { sets: "replace" }), { set: new Set(["bar"]), }, );});
Deno.test("deepMerge: sets merge (merge)", () => { assertEquals( deepMerge({ set: new Set(["foo"]), }, { set: new Set(["bar"]), }, { sets: "merge" }), { set: new Set(["foo", "bar"]), }, );});
Deno.test("deepMerge: complex test", () => { assertEquals( deepMerge({ foo: { bar: { quux: new Set(["foo"]), grault: {}, }, }, }, { foo: { bar: { baz: true, qux: [1, 2], grault: { garply: false, }, }, corge: "deno", [Symbol.for("deepmerge.test")]: true, }, }), { foo: { bar: { quux: new Set(["foo"]), baz: true, qux: [1, 2], grault: { garply: false, }, }, corge: "deno", [Symbol.for("deepmerge.test")]: true, }, }, );});
Deno.test("deepMerge: handle circular references", () => { const expected = { foo: true } as { foo: boolean; bar: unknown }; expected.bar = expected; assertEquals(deepMerge({}, expected), expected);});
Deno.test("deepMerge: target object is not modified", () => { const record = { foo: { bar: true, }, baz: [1, 2, 3], quux: new Set([1, 2, 3]), }; assertEquals( deepMerge(record, { foo: { qux: false, }, baz: [4, 5, 6], quux: new Set([4, 5, 6]), }, { arrays: "merge", sets: "merge" }), { foo: { bar: true, qux: false, }, baz: [1, 2, 3, 4, 5, 6], quux: new Set([1, 2, 3, 4, 5, 6]), }, ); assertEquals(record, { foo: { bar: true, }, baz: [1, 2, 3], quux: new Set([1, 2, 3]), });});