import { act, cleanup, render } from "@testing-library/react"; import * as React from "react"; import { afterEach, describe, expect, it, vi } from "vitest"; import { defineToolcraft } from "../../../schema/define-toolcraft"; import { isToolcraftControlsResetHistoryPatch } from "../../../state/history-patch-metadata"; import type { ToolcraftExternalStore } from "../../../state/toolcraft-external-store"; import { ToolcraftRoot } from "../../app-shell/toolcraft-root"; import { useToolcraftStore } from "../../app-shell/toolcraft-store-context"; import { ControlsPanel } from "../controls-panel"; const counters = vi.hoisted(() => ({ resetGenerationScans: 0, sectionCommits: 0, shellSelectorExecutions: 0, })); function CommitProbe(): null { React.useLayoutEffect(() => { counters.sectionCommits += 1; }); return null; } vi.mock("../../../state/toolcraft-external-store-dependencies", async (importOriginal) => { const actual = await importOriginal< typeof import("../../../state/toolcraft-external-store-dependencies") >(); return { ...actual, getToolcraftHistorySourceGeneration: ( ...args: Parameters ): number => { counters.resetGenerationScans += 1; return actual.getToolcraftHistorySourceGeneration(...args); }, }; }); vi.mock("../conditions/control-conditions", async (importOriginal) => { const actual = await importOriginal< typeof import("../conditions/control-conditions") >(); return { ...actual, isToolcraftSectionVisible: ( ...args: Parameters ): boolean => { if (args[1].title === "Transform") { counters.shellSelectorExecutions += 1; } return actual.isToolcraftSectionVisible(...args); }, }; }); vi.mock("@repo/ui", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, PanelSection: (props: React.ComponentProps) => ( <> {props.title === "Transform" ? : null} ), }; }); function CaptureStore({ capture, }: { capture: (store: ToolcraftExternalStore) => void; }): null { capture(useToolcraftStore()); return null; } function resetCounters(): void { counters.resetGenerationScans = 0; counters.sectionCommits = 0; counters.shellSelectorExecutions = 0; } function renderPanel(): { store: ToolcraftExternalStore; target: string; } { const schema = defineToolcraft({ canvas: { enabled: false }, panels: { controls: { sections: [ { controls: { amount: { defaultValue: 75, label: "Amount", max: 100, min: 0, target: "effect.amount", type: "slider", }, }, title: "Transform", }, ], title: "Controls", }, }, }); const target = schema.panels.controls?.sections.find( (section) => section.controls.amount !== undefined, )?.controls.amount?.target; let store: ToolcraftExternalStore | undefined; render( { store = value; }} /> , ); if (!store || !target) { throw new Error("Expected the controls panel store and amount target."); } resetCounters(); return { store, target }; } function expectNoShellWork(): void { expect(counters.shellSelectorExecutions).toBe(0); expect(counters.resetGenerationScans).toBe(0); expect(counters.sectionCommits).toBe(0); } function expectOneResetGeneration(): void { expect(counters.shellSelectorExecutions).toBe(1); expect(counters.resetGenerationScans).toBe(1); expect(counters.sectionCommits).toBe(1); } afterEach(() => { cleanup(); resetCounters(); window.localStorage.clear(); }); describe("ControlsPanel reset dependency isolation", () => { it("keeps shell selection cold across growing ordinary history", () => { const { store, target } = renderPanel(); for (let value = 1; value <= 40; value += 1) { act(() => { store.dispatch({ target, type: "controls.setValue", value }); }); } expect(store.getState().history.undo).toHaveLength(40); expectNoShellWork(); }); it("executes once for reset, undo, and redo generation changes", () => { const { store, target } = renderPanel(); act(() => { store.dispatch({ target, type: "controls.setValue", value: 40 }); }); resetCounters(); act(() => { store.dispatch({ type: "controls.reset" }); }); expectOneResetGeneration(); expect( store.getState().history.undo.filter( isToolcraftControlsResetHistoryPatch, ), ).toHaveLength(1); resetCounters(); act(() => { store.dispatch({ target, type: "controls.setValue", value: 41 }); }); act(() => { store.dispatch({ type: "history.undo" }); }); expectNoShellWork(); resetCounters(); act(() => { store.dispatch({ type: "history.undo" }); }); expect(store.getState().values[target]).toBe(40); expectOneResetGeneration(); resetCounters(); act(() => { store.dispatch({ type: "history.redo" }); }); expect(store.getState().values[target]).toBe(75); expectOneResetGeneration(); resetCounters(); act(() => { store.dispatch({ type: "history.undo" }); }); resetCounters(); act(() => { store.dispatch({ target, type: "controls.setValue", value: 42 }); }); expect(store.getState().history.redo).toEqual([]); expectNoShellWork(); }); });