test(commands): cover viewport command flow

This commit is contained in:
syntaxbullet
2026-07-03 09:50:03 +02:00
parent a460d6ea05
commit af71a49b09
4 changed files with 132 additions and 1 deletions

View File

@@ -0,0 +1,18 @@
import { describe, expect, test } from "bun:test";
import { createInitialAppState } from "@editor/initial-state";
import { createAppStore } from "@editor/store";
import { createCommandRegistry } from "./registry";
import { viewportPanCommand } from "./viewport";
describe("command dispatcher", () => {
test("throws for unknown commands", () => {
const store = createAppStore(createInitialAppState("Test"), createCommandRegistry([]));
expect(() => store.dispatch("missing", undefined)).toThrow("Unknown command: missing");
});
test("dispatch applies command result to store", () => {
const store = createAppStore(createInitialAppState("Test"), createCommandRegistry([viewportPanCommand]));
store.dispatch("viewport.pan", { delta: { x: 3, y: 7 } });
expect(store.getState().editor.viewport.center).toEqual({ x: 3, y: 7 });
});
});

44
commands/viewport.test.ts Normal file
View File

@@ -0,0 +1,44 @@
import { describe, expect, test } from "bun:test";
import { createInitialAppState } from "@editor/initial-state";
import {
viewportPanCommand,
viewportResetCommand,
viewportSetSizeCommand,
viewportSetZoomCommand,
viewportZoomAroundPointCommand,
} from "./viewport";
const context = () => ({ state: createInitialAppState("Test") });
describe("viewport commands", () => {
test("pans viewport center", () => {
const next = viewportPanCommand.execute(context(), { delta: { x: 10, y: -5 } });
expect(next.editor.viewport.center).toEqual({ x: 10, y: -5 });
});
test("sets zoom with minimum clamp", () => {
const next = viewportSetZoomCommand.execute(context(), { zoom: -1 });
expect(next.editor.viewport.zoom).toBe(0.01);
});
test("sets non-negative viewport size", () => {
const next = viewportSetSizeCommand.execute(context(), { w: 800, h: -1 });
expect(next.editor.viewport.size).toEqual({ w: 800, h: 0 });
});
test("zooms around a viewport point", () => {
const state = viewportSetSizeCommand.execute(context(), { w: 100, h: 100 });
const next = viewportZoomAroundPointCommand.execute({ state }, { zoom: 2, point: { x: 100, y: 50 } });
expect(next.editor.viewport.zoom).toBe(2);
expect(next.editor.viewport.center).toEqual({ x: 25, y: 0 });
});
test("resets viewport but preserves size", () => {
const sized = viewportSetSizeCommand.execute(context(), { w: 640, h: 480 });
const panned = viewportPanCommand.execute({ state: sized }, { delta: { x: 4, y: 8 } });
const next = viewportResetCommand.execute({ state: panned }, undefined);
expect(next.editor.viewport).toEqual({ center: { x: 0, y: 0 }, zoom: 1, rotation: 0, size: { w: 640, h: 480 } });
});
});