import assert from "node:assert/strict"; import test from "node:test"; import { appendPathPenAnchor, closePathPenDraft, constrainPathPenPoint, createPathPenNode, pathPenDraftToPathData, setLastPathPenAnchorHandles, startPathPenDraft } from "../src/ui/pages/CanvasWorkspace/canvas/pathPen.ts"; const settings = { color: "#123456", width: 3 }; function point(x, y) { return { screen: { x, y }, world: { x, y } }; } test("creates one Pen anchor for each user click", () => { let draft = startPathPenDraft(settings, 1, point(10, 20)); draft = appendPathPenAnchor(draft, point(110, 20)); draft = appendPathPenAnchor(draft, point(110, 80)); assert.equal(draft.anchors.length, 3); assert.deepEqual(pathPenDraftToPathData(draft), [1, 10, 20, 2, 110, 20, 2, 110, 80]); }); test("turns click-drag anchors into Photoshop-style mirrored Bezier handles", () => { let draft = startPathPenDraft(settings, 1, point(10, 20)); draft = setLastPathPenAnchorHandles(draft, point(40, 20)); draft = appendPathPenAnchor(draft, point(110, 80)); draft = setLastPathPenAnchorHandles(draft, point(130, 100)); assert.deepEqual(draft.anchors[0].handleIn?.world, { x: -20, y: 20 }); assert.deepEqual(draft.anchors[0].handleOut?.world, { x: 40, y: 20 }); assert.deepEqual(draft.anchors[1].handleIn?.world, { x: 90, y: 60 }); assert.deepEqual(pathPenDraftToPathData(draft), [1, 10, 20, 5, 40, 20, 90, 60, 110, 80]); }); test("constrains Pen anchors and handles to 45-degree increments with Shift", () => { const constrained = constrainPathPenPoint({ x: 10, y: 10 }, { x: 42, y: 24 }); assert.equal(Math.round(constrained.x), 35); assert.equal(Math.round(constrained.y), 35); }); test("closes a Pen path back to its first user anchor", () => { let draft = startPathPenDraft(settings, 1, point(0, 0)); draft = appendPathPenAnchor(draft, point(100, 0)); draft = appendPathPenAnchor(draft, point(100, 100)); draft = closePathPenDraft(draft); assert.deepEqual(pathPenDraftToPathData(draft), [1, 0, 0, 2, 100, 0, 2, 100, 100, 11]); }); test("persists a completed Pen path as an editable shape node", () => { let draft = startPathPenDraft(settings, 1, point(10, 20)); draft = appendPathPenAnchor(draft, point(110, 20)); const node = createPathPenNode(draft, "Pen"); const options = JSON.parse(node.content); assert.equal(node.type, "frame"); assert.equal(node.layerRole, "shape"); assert.equal(node.strokeColor, settings.color); assert.equal(options.kind, "path"); assert.deepEqual(options.pathData, [1, 0.04955, 0.5, 2, 0.95045, 0.5]); });