import { describe, expect, test } from "bun:test"; import { pointPlugin } from "../plugins/pointPlugin"; import { createPointerEvent, createTestCanvas } from "./canvasTestUtils"; describe("point plugin", () => { test("highlights and moves a point", () => { const points = [{ id: "p1", x: 0.5, y: 0.5 }]; const rect = { x: 0, y: 0, width: 10, height: 10 }; const moves: any[] = []; const harness = createTestCanvas((canvas) => canvas.addPlugins(pointPlugin<{ snapshot: string }>({ movementThreshold: 0 })), { data: { zoom: 1, pointHandleSize: 8 }, contextProperties: { filterPoints: ({ at, predicate }) => { const absolutized = points.map((point) => ({ ...point, x: rect.x + rect.width * point.x, y: rect.y + rect.height * point.y, })); const within = at ? absolutized.filter( (point) => point.x >= at.x && point.x <= at.x + at.width && point.y >= at.y && point.y <= at.y + at.height ) : absolutized; const filtered = predicate ? within.filter(predicate) : within; // Return points in original coordinate space expected by the plugin return filtered.map((point) => ({ id: point.id, x: point.x, y: point.y, })); }, isPointHighlightable: () => true, getPoints: () => ({ points, rect }), getStateSnapshot: () => ({ snapshot: "state" }), movePoint: (params) => moves.push(params), }, }); harness.handlers.onPointerMove?.(createPointerEvent({ x: 5, y: 5 })); expect(harness.getData().highlightedPointId).toBe("p1"); harness.handlers.onPointerDown?.(createPointerEvent({ x: 5, y: 5 })); expect(harness.getMode().type).toBe("movingPoint"); harness.handlers.onPointerMove?.(createPointerEvent({ x: 6, y: 5 })); expect(moves[0]).toMatchObject({ id: "p1", snapshot: { snapshot: "state" } }); harness.handlers.onPointerUp?.(createPointerEvent({ x: 6, y: 5 })); expect(harness.getMode().type).toBe("none"); }); test("movement threshold prevents move and clears on leave", () => { const points = [{ id: "p1", x: 0.5, y: 0.5 }]; const rect = { x: 0, y: 0, width: 10, height: 10 }; const moves: any[] = []; const harness = createTestCanvas((canvas) => canvas.addPlugins(pointPlugin<{ snapshot: string }>({ movementThreshold: 20 })), { data: { zoom: 1, pointHandleSize: 8 }, contextProperties: { filterPoints: (options) => points, isPointHighlightable: () => true, getPoints: () => ({ points, rect }), getStateSnapshot: () => ({ snapshot: "state" }), movePoint: (params) => moves.push(params), }, }); harness.handlers.onPointerDown?.(createPointerEvent({ x: 5, y: 5 })); harness.handlers.onPointerMove?.(createPointerEvent({ x: 6, y: 5 })); expect(moves.length).toBe(0); harness.handlers.onPointerLeave?.(createPointerEvent({})); expect(harness.getData().highlightedPointId).toBeUndefined(); }); });