From 70126362798b4bf35bdec4343918904a9b602fbe Mon Sep 17 00:00:00 2001 From: Victor Giers Date: Mon, 13 Apr 2026 22:31:07 +0200 Subject: [PATCH] Add tests for path point operations and viewport focus on path points --- tests/domain/path.command.test.ts | 104 +++++++++++++++++++++++++++++- tests/unit/viewport-focus.test.ts | 45 +++++++++++++ 2 files changed, 148 insertions(+), 1 deletion(-) diff --git a/tests/domain/path.command.test.ts b/tests/domain/path.command.test.ts index 08b0d69b..1a20e33f 100644 --- a/tests/domain/path.command.test.ts +++ b/tests/domain/path.command.test.ts @@ -1,10 +1,12 @@ import { describe, expect, it } from "vitest"; +import { createAddPathPointCommand } from "../../src/commands/add-path-point-command"; import { createEditorStore } from "../../src/app/editor-store"; import { createDeletePathCommand } from "../../src/commands/delete-path-command"; +import { createDeletePathPointCommand } from "../../src/commands/delete-path-point-command"; import { createSetPathNameCommand } from "../../src/commands/set-path-name-command"; import { createUpsertPathCommand } from "../../src/commands/upsert-path-command"; -import { createScenePath } from "../../src/document/paths"; +import { createScenePath, createScenePathPoint } from "../../src/document/paths"; import { createEmptySceneDocument } from "../../src/document/scene-document"; describe("path commands", () => { @@ -83,4 +85,104 @@ describe("path commands", () => { expect(store.redo()).toBe(true); expect(store.getState().document.paths[path.id]).toBeUndefined(); }); + + it("adds and deletes path points with undo and redo while keeping point selection coherent", () => { + const path = createScenePath({ + id: "path-point-ops", + points: [ + { + id: "path-point-start", + position: { + x: -1, + y: 0, + z: 0 + } + }, + { + id: "path-point-end", + position: { + x: 1, + y: 0, + z: 0 + } + } + ] + }); + const nextPoint = createScenePathPoint({ + id: "path-point-new", + position: { + x: 3, + y: 0, + z: 0 + } + }); + const store = createEditorStore({ + initialDocument: { + ...createEmptySceneDocument({ + name: "Path Point Command Scene" + }), + paths: { + [path.id]: path + } + } + }); + + store.setSelection({ + kind: "paths", + ids: [path.id] + }); + + store.executeCommand( + createAddPathPointCommand({ + pathId: path.id, + point: nextPoint + }) + ); + + expect(store.getState().document.paths[path.id]?.points).toHaveLength(3); + expect(store.getState().selection).toEqual({ + kind: "pathPoint", + pathId: path.id, + pointId: nextPoint.id + }); + + store.executeCommand( + createDeletePathPointCommand({ + pathId: path.id, + pointId: nextPoint.id + }) + ); + + expect(store.getState().document.paths[path.id]?.points).toHaveLength(2); + expect(store.getState().selection).toEqual({ + kind: "pathPoint", + pathId: path.id, + pointId: path.points[1].id + }); + + expect(store.undo()).toBe(true); + expect(store.getState().document.paths[path.id]?.points).toHaveLength(3); + expect(store.getState().selection).toEqual({ + kind: "pathPoint", + pathId: path.id, + pointId: nextPoint.id + }); + + expect(store.undo()).toBe(true); + expect(store.getState().document.paths[path.id]?.points).toHaveLength(2); + expect(store.getState().selection).toEqual({ + kind: "paths", + ids: [path.id] + }); + + expect(store.redo()).toBe(true); + expect(store.getState().selection).toEqual({ + kind: "pathPoint", + pathId: path.id, + pointId: nextPoint.id + }); + + expect(store.redo()).toBe(true); + expect(store.getState().document.paths[path.id]?.points).toHaveLength(2); + }); }); diff --git a/tests/unit/viewport-focus.test.ts b/tests/unit/viewport-focus.test.ts index 04154f60..c9e07d41 100644 --- a/tests/unit/viewport-focus.test.ts +++ b/tests/unit/viewport-focus.test.ts @@ -211,6 +211,51 @@ describe("resolveViewportFocusTarget", () => { }); }); + it("frames a selected Path Point tightly around its authored position", () => { + const path = createScenePath({ + id: "path-point-focus", + points: [ + { + id: "point-focus-a", + position: { + x: -2, + y: 0, + z: 1 + } + }, + { + id: "point-focus-b", + position: { + x: 4, + y: 2, + z: 3 + } + } + ] + }); + const document = { + ...createEmptySceneDocument(), + paths: { + [path.id]: path + } + }; + + const focusTarget = resolveViewportFocusTarget(document, { + kind: "pathPoint", + pathId: path.id, + pointId: path.points[1].id + }); + + expect(focusTarget).toEqual({ + center: { + x: 4, + y: 2, + z: 3 + }, + radius: 0.5 + }); + }); + it("frames the selected Spot Light helper", () => { const spotLight = createSpotLightEntity({ id: "entity-spot-light-main",