import { clone } from "../clone"; describe("clone", () => { const originalStructuredClone = global.structuredClone; afterEach(() => { // Restore the original structuredClone after each test global.structuredClone = originalStructuredClone; }); describe("when structuredClone is available", () => { beforeEach(() => { // Mock structuredClone if it's not available if (typeof global.structuredClone === "undefined") { global.structuredClone = jest.fn((value) => JSON.parse(JSON.stringify(value)) ); } }); test("clones primitive values", () => { expect(clone(42)).toBe(42); expect(clone("test")).toBe("test"); expect(clone(true)).toBe(true); expect(clone(null)).toBe(null); }); test("clones simple objects", () => { const original = { a: 1, b: 2 }; const cloned = clone(original); expect(cloned).toEqual(original); expect(cloned).not.toBe(original); }); test("clones nested objects", () => { const original = { a: { b: { c: 1 } } }; const cloned = clone(original); expect(cloned).toEqual(original); expect(cloned).not.toBe(original); expect(cloned.a).not.toBe(original.a); expect(cloned.a.b).not.toBe(original.a.b); }); test("clones arrays", () => { const original = [1, 2, 3]; const cloned = clone(original); expect(cloned).toEqual(original); expect(cloned).not.toBe(original); }); test("clones arrays with nested objects", () => { const original = [{ a: 1 }, { b: 2 }]; const cloned = clone(original); expect(cloned).toEqual(original); expect(cloned).not.toBe(original); expect(cloned[0]).not.toBe(original[0]); expect(cloned[1]).not.toBe(original[1]); }); test("does not mutate the original value", () => { const original = { a: 1, b: { c: 2 } }; const cloned = clone(original); cloned.a = 99; cloned.b.c = 99; expect(original.a).toBe(1); expect(original.b.c).toBe(2); }); }); describe("when structuredClone is not available (fallback to cloneDeep)", () => { beforeEach(() => { // Delete structuredClone to force fallback to cloneDeep delete (global as any).structuredClone; }); test("clones primitive values using cloneDeep", () => { expect(clone(42)).toBe(42); expect(clone("test")).toBe("test"); expect(clone(true)).toBe(true); expect(clone(null)).toBe(null); }); test("clones simple objects using cloneDeep", () => { const original = { a: 1, b: 2 }; const cloned = clone(original); expect(cloned).toEqual(original); expect(cloned).not.toBe(original); }); test("clones nested objects using cloneDeep", () => { const original = { a: { b: { c: 1 } } }; const cloned = clone(original); expect(cloned).toEqual(original); expect(cloned).not.toBe(original); expect(cloned.a).not.toBe(original.a); expect(cloned.a.b).not.toBe(original.a.b); }); test("clones arrays using cloneDeep", () => { const original = [1, 2, 3]; const cloned = clone(original); expect(cloned).toEqual(original); expect(cloned).not.toBe(original); }); test("clones arrays with nested objects using cloneDeep", () => { const original = [{ a: 1 }, { b: 2 }]; const cloned = clone(original); expect(cloned).toEqual(original); expect(cloned).not.toBe(original); expect(cloned[0]).not.toBe(original[0]); expect(cloned[1]).not.toBe(original[1]); }); test("does not mutate the original value when using cloneDeep", () => { const original = { a: 1, b: { c: 2 } }; const cloned = clone(original); cloned.a = 99; cloned.b.c = 99; expect(original.a).toBe(1); expect(original.b.c).toBe(2); }); test("handles complex objects with multiple levels", () => { const original = { name: "test", data: { items: [ { id: 1, value: "a" }, { id: 2, value: "b" }, ], meta: { count: 2 }, }, }; const cloned = clone(original); expect(cloned).toEqual(original); expect(cloned).not.toBe(original); expect(cloned.data).not.toBe(original.data); expect(cloned.data.items).not.toBe(original.data.items); expect(cloned.data.items[0]).not.toBe(original.data.items[0]); expect(cloned.data.meta).not.toBe(original.data.meta); }); }); });