- Implemented ComfyGenerateRequest type and associated functions for generating images using various architectures and modes. - Added functions for listing generation options and handling image uploads. - Created workflows for different generation modes including SDXL, Z-Image, Z-Image Turbo, and Anima. - Introduced GenerationJobStatus component to display the status of ongoing generation jobs. - Developed MaskControls for managing mask operations and displaying mask analysis. - Created palette items for tool selection, layer management, and generation settings.
120 lines
5.3 KiB
TypeScript
120 lines
5.3 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { createInitialAppState } from "@editor/initial-state";
|
|
import { generationStartJobCommand, generationSucceedJobCommand } from "./generation";
|
|
import { createAppStore } from "@editor/store";
|
|
import { documentAddArtboardCommand } from "./document";
|
|
import { historyCommands } from "./history";
|
|
import { commandIds } from "./ids";
|
|
import { createCommandRegistry } from "./registry";
|
|
import { transformCommands } from "./transform";
|
|
|
|
const registry = createCommandRegistry([documentAddArtboardCommand, generationStartJobCommand, generationSucceedJobCommand, ...historyCommands, ...transformCommands]);
|
|
|
|
describe("history commands", () => {
|
|
test("records document changes and undoes/redoes them", () => {
|
|
const store = createAppStore(createInitialAppState("Test"), registry);
|
|
|
|
store.dispatch(commandIds.documentAddArtboard, { id: "a1", name: "Artboard", bounds: { x: 0, y: 0, w: 100, h: 100 } });
|
|
|
|
expect(store.getState().document.artboards.map((artboard) => artboard.id)).toEqual(["a1"]);
|
|
expect(store.getState().history.past).toHaveLength(1);
|
|
|
|
store.dispatch(commandIds.historyUndo, undefined);
|
|
|
|
expect(store.getState().document.artboards).toEqual([]);
|
|
expect(store.getState().history.future).toHaveLength(1);
|
|
|
|
store.dispatch(commandIds.historyRedo, undefined);
|
|
|
|
expect(store.getState().document.artboards.map((artboard) => artboard.id)).toEqual(["a1"]);
|
|
});
|
|
|
|
test("records one history entry for a transform drag", () => {
|
|
const store = createAppStore(artboardState(), registry);
|
|
|
|
store.dispatch(commandIds.transformBegin, {
|
|
target: { type: "artboard", id: "a1" },
|
|
handle: "body",
|
|
point: { x: 0, y: 0 },
|
|
initialBounds: { x: 0, y: 0, w: 100, h: 80 },
|
|
});
|
|
store.dispatch(commandIds.transformUpdate, { point: { x: 5, y: 10 } });
|
|
store.dispatch(commandIds.transformUpdate, { point: { x: 10, y: 20 } });
|
|
store.dispatch(commandIds.transformUpdate, { point: { x: 15, y: 25 } });
|
|
|
|
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 15, y: 25, w: 100, h: 80 });
|
|
expect(store.getState().history.past).toHaveLength(0);
|
|
|
|
store.dispatch(commandIds.transformEnd, undefined);
|
|
|
|
expect(store.getState().editor.transformSession).toBeUndefined();
|
|
expect(store.getState().history.past).toHaveLength(1);
|
|
expect(store.getState().history.past[0]?.document.artboards[0]?.bounds).toEqual({ x: 0, y: 0, w: 100, h: 80 });
|
|
expect(store.getState().history.past[0]?.editor.transformSession).toBeUndefined();
|
|
|
|
store.dispatch(commandIds.historyUndo, undefined);
|
|
|
|
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 0, y: 0, w: 100, h: 80 });
|
|
expect(store.getState().editor.transformSession).toBeUndefined();
|
|
expect(store.getState().history.future).toHaveLength(1);
|
|
});
|
|
|
|
test("keeps direct transform bounds edits normally undoable", () => {
|
|
const store = createAppStore(artboardState(), registry);
|
|
|
|
store.dispatch(commandIds.transformSetBounds, { target: { type: "artboard", id: "a1" }, bounds: { x: 12, y: 24, w: 120, h: 90 } });
|
|
|
|
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 12, y: 24, w: 120, h: 90 });
|
|
expect(store.getState().history.past).toHaveLength(1);
|
|
|
|
store.dispatch(commandIds.historyUndo, undefined);
|
|
|
|
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 0, y: 0, w: 100, h: 80 });
|
|
});
|
|
|
|
test("does not record history for transform update or end without a session", () => {
|
|
const store = createAppStore(artboardState(), registry);
|
|
|
|
store.dispatch(commandIds.transformUpdate, { point: { x: 10, y: 20 } });
|
|
store.dispatch(commandIds.transformEnd, undefined);
|
|
|
|
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 0, y: 0, w: 100, h: 80 });
|
|
expect(store.getState().history.past).toHaveLength(0);
|
|
expect(store.getState().history.future).toHaveLength(0);
|
|
});
|
|
|
|
test("does not record history for a transform session with no document update", () => {
|
|
const store = createAppStore(artboardState(), registry);
|
|
|
|
store.dispatch(commandIds.transformBegin, {
|
|
target: { type: "artboard", id: "a1" },
|
|
handle: "body",
|
|
point: { x: 0, y: 0 },
|
|
initialBounds: { x: 0, y: 0, w: 100, h: 80 },
|
|
});
|
|
store.dispatch(commandIds.transformEnd, undefined);
|
|
|
|
expect(store.getState().editor.transformSession).toBeUndefined();
|
|
expect(store.getState().document.artboards[0]?.bounds).toEqual({ x: 0, y: 0, w: 100, h: 80 });
|
|
expect(store.getState().history.past).toHaveLength(0);
|
|
});
|
|
|
|
test("does not rewind generation job lifecycle during document undo", () => {
|
|
const store = createAppStore(createInitialAppState("Test"), registry);
|
|
store.dispatch(commandIds.documentAddArtboard, { id: "a1", name: "Artboard", bounds: { x: 0, y: 0, w: 100, h: 100 } });
|
|
store.dispatch(commandIds.generationStartJob, { jobId: "job-1", kind: "generate", label: "Generating", startedAt: 100 });
|
|
store.dispatch(commandIds.generationSucceedJob, { jobId: "job-1", finishedAt: 150 });
|
|
|
|
store.dispatch(commandIds.historyUndo, undefined);
|
|
|
|
expect(store.getState().editor.generation.jobs[0]?.status).toBe("succeeded");
|
|
});
|
|
});
|
|
|
|
function artboardState() {
|
|
return documentAddArtboardCommand.execute(
|
|
{ state: createInitialAppState("Test") },
|
|
{ id: "a1", name: "Artboard", bounds: { x: 0, y: 0, w: 100, h: 80 } },
|
|
);
|
|
}
|