import { expect, it } from "bun:test"; import { applyExtendedPatch, createExtended } from "../extended"; it("handles remove", () => { const state = [ { id: "a", count: 1 }, { id: "b", count: 2 }, { id: "c", count: 3 }, ]; const [updated, patches, inversePatches] = createExtended(state, (draft) => { draft.splice(0, 1); }); expect(updated).toEqual([ { id: "b", count: 2 }, { id: "c", count: 3 }, ]); expect(patches).toEqual([{ op: "remove", path: [{ id: "a" }] }]); expect(inversePatches).toEqual([ { op: "add", path: [0], value: { id: "a", count: 1 } }, ]); expect(applyExtendedPatch(state, patches)).toEqual(updated); expect(applyExtendedPatch(updated, inversePatches)).toEqual(state); }); it("handles move", () => { const state = [ { id: "a", count: 1 }, { id: "b", count: 2 }, { id: "c", count: 3 }, ]; const [updated, patches, inversePatches] = createExtended(state, (draft) => { const last = draft.pop(); draft.unshift(last!); }); expect(updated).toEqual([ { id: "c", count: 3 }, { id: "a", count: 1 }, { id: "b", count: 2 }, ]); expect(patches).toEqual([{ op: "move", from: [{ id: "c" }], path: [0] }]); expect(inversePatches).toEqual([ { op: "move", from: [{ id: "c" }], path: [2] }, ]); expect(applyExtendedPatch(state, patches)).toEqual(updated); expect(applyExtendedPatch(updated, inversePatches)).toEqual(state); }); it("handles assignment in array item", () => { const state = [ { id: "a", count: 1 }, { id: "b", count: 2 }, { id: "c", count: 3 }, ]; const [updated, patches, inversePatches] = createExtended(state, (draft) => { draft[0] = { id: "a", count: 4 }; }); expect(updated).toEqual([ { id: "a", count: 4 }, { id: "b", count: 2 }, { id: "c", count: 3 }, ]); expect(patches).toEqual([ { op: "replace", path: [{ id: "a" }, "count"], value: 4, }, ]); expect(inversePatches).toEqual([ { op: "replace", path: [{ id: "a" }, "count"], value: 1 }, ]); expect(applyExtendedPatch(state, patches)).toEqual(updated); expect(applyExtendedPatch(updated, inversePatches)).toEqual(state); }); it("handles move followed by assignment in array item", () => { const state = [ { id: "a", count: 1 }, { id: "b", count: 2 }, { id: "c", count: 3 }, ]; const [updated, patches, inversePatches] = createExtended(state, (draft) => { const last = draft.pop(); draft.unshift(last!); const itemA = draft.findIndex((item) => item.id === "a"); draft[itemA] = { id: "a", count: 4 }; }); expect(updated).toEqual([ { id: "c", count: 3 }, { id: "a", count: 4 }, { id: "b", count: 2 }, ]); expect(patches).toEqual([ { op: "replace", path: [{ id: "a" }, "count"], value: 4 }, { op: "move", from: [{ id: "c" }], path: [0] }, ]); expect(inversePatches).toEqual([ { op: "move", from: [{ id: "c" }], path: [2] }, { op: "replace", path: [{ id: "a" }, "count"], value: 1 }, ]); expect(applyExtendedPatch(state, patches)).toEqual(updated); expect(applyExtendedPatch(updated, inversePatches)).toEqual(state); });