Files
image-studio/view/useAppState.test.ts
2026-07-04 15:37:54 +02:00

69 lines
2.5 KiB
TypeScript

import { describe, expect, test } from "bun:test";
import { createInitialAppState } from "@editor/initial-state";
import type { AppState } from "@editor/state";
import { createAppStateSelectorSnapshot, shallowEqual } from "./useAppState";
describe("app state selector snapshot", () => {
test("reuses selected snapshots when equality reports no relevant changes", () => {
const state = createInitialAppState("Test");
const snapshot = createAppStateSelectorSnapshot(selectShellLikeState, shallowEqual);
const selected = snapshot.getSnapshot(state);
const previewOnlyUpdate: AppState = {
...state,
editor: {
...state.editor,
brushStrokePreview: { layerId: "layer", assetId: "asset", source: "preview" },
},
};
expect(snapshot.updateSnapshot(previewOnlyUpdate)).toBe(false);
expect(snapshot.getSnapshot(previewOnlyUpdate)).toBe(selected);
});
test("can collapse brush preview updates to presence instead of position", () => {
const state = createInitialAppState("Test");
const snapshot = createAppStateSelectorSnapshot((next: AppState) => ({ hasBrushPreview: Boolean(next.editor.brushPreview) }), shallowEqual);
const withoutPreview = snapshot.getSnapshot(state);
const withPreview: AppState = {
...state,
editor: {
...state.editor,
brushPreview: { position: { x: 10, y: 20 } },
},
};
expect(snapshot.updateSnapshot(withPreview)).toBe(true);
const previewPresent = snapshot.getSnapshot(withPreview);
expect(previewPresent).not.toBe(withoutPreview);
expect(previewPresent.hasBrushPreview).toBe(true);
const movedPreview: AppState = {
...withPreview,
editor: {
...withPreview.editor,
brushPreview: { position: { x: 30, y: 40 } },
},
};
expect(snapshot.updateSnapshot(movedPreview)).toBe(false);
expect(snapshot.getSnapshot(movedPreview)).toBe(previewPresent);
});
test("shallow equality uses object keys and Object.is value checks", () => {
expect(shallowEqual({ id: "a", value: Number.NaN }, { id: "a", value: Number.NaN })).toBe(true);
expect(shallowEqual({ id: "a", value: 0 }, { id: "a", value: -0 })).toBe(false);
expect(shallowEqual({ id: "a" }, { id: "a", extra: true })).toBe(false);
});
});
function selectShellLikeState(state: AppState) {
return {
document: state.document,
selection: state.editor.selection,
viewport: state.editor.viewport,
tools: state.editor.tools,
transformSession: state.editor.transformSession,
maskEdit: state.editor.maskEdit,
};
}