import { describe, expect, it } from "vitest"; import { getToolcraftHistoryPatchDomains, isToolcraftControlsResetHistoryPatch, tagToolcraftControlsResetHistoryPatch, } from "./history-patch-metadata"; import { commitToolcraftStatePatch, commitToolcraftValuePatch } from "./history-patches"; import { toolcraftReducer } from "../composition/public-state"; import { createState } from "./reducer-test-utils"; describe("explicit Reset history metadata", () => { it("survives spread and group merging without overwriting its original before side", () => { const base = createState(); const initial = { ...base, values: { ...base.values, layers: 75 } }; const firstPatch = tagToolcraftControlsResetHistoryPatch({ before: {}, after: {}, label: "First reset", }, { state: { before: { layers: initial.layers }, after: { layers: [] } }, values: { before: { layers: 75 }, after: { layers: 50 } }, }); const firstData = getToolcraftHistoryPatchDomains(firstPatch)!; expect(getToolcraftHistoryPatchDomains({ ...firstPatch })).toBe(firstData); expect(isToolcraftControlsResetHistoryPatch({ ...firstPatch })).toBe(true); expect(Object.keys(firstPatch).sort()).toEqual(["after", "before", "label"]); const first = commitToolcraftStatePatch(initial, firstPatch, { group: "reset", mode: "merge" }); const secondPatch = tagToolcraftControlsResetHistoryPatch({ before: {}, after: {}, label: "Second reset", }, { state: { before: { layers: first.layers }, after: { layers: [] } }, values: { before: { layers: 50 }, after: { layers: 25 } }, }); const second = commitToolcraftStatePatch(first, secondPatch, { group: "reset", mode: "merge" }); expect(second.history.undo).toHaveLength(1); const merged = second.history.undo[0]!; expect(getToolcraftHistoryPatchDomains(merged)).toEqual({ state: { before: firstData.state.before, after: getToolcraftHistoryPatchDomains(secondPatch)!.state.after }, values: { before: { layers: 75 }, after: { layers: 25 } }, }); expect(firstData.values.after).toEqual({ layers: 50 }); expect(second.values.layers).toBe(25); const undone = toolcraftReducer(second, { type: "history.undo" }); expect(undone.values.layers).toBe(75); expect(undone.layers).toBe(initial.layers); const redone = toolcraftReducer(undone, { type: "history.redo" }); expect(redone.values.layers).toBe(25); expect(redone.layers).toEqual([]); }); it("does not merge legacy tagged patches into explicit Reset patch data", () => { const initial = createState(); const explicit = commitToolcraftStatePatch(initial, tagToolcraftControlsResetHistoryPatch({ before: {}, after: {}, label: "Explicit reset", }, { state: { before: {}, after: {} }, values: { before: { "selectedLayer.opacity": 75 }, after: { "selectedLayer.opacity": 50 } }, }), { group: "reset", mode: "merge" }); const legacy = commitToolcraftValuePatch(explicit, tagToolcraftControlsResetHistoryPatch({ before: { "selectedLayer.opacity": 50 }, after: { "selectedLayer.opacity": 25 }, label: "Legacy reset", }), { ...explicit.values, "selectedLayer.opacity": 25 }, { group: "reset", mode: "merge" }); expect(legacy.history.undo).toHaveLength(2); expect(toolcraftReducer(legacy, { type: "history.undo" }).values["selectedLayer.opacity"]).toBe(50); }); });