import { describe, expect, it } from "vitest"; import { DOLLY, across, parsePath, smooth, toPath } from "#lib/components/landing/hackable/dolly.ts"; describe("parsePath", () => { it("reads the mark as its four closed contours", () => { expect(parsePath(DOLLY)).toHaveLength(4); }); it("closes a contour onto its first anchor rather than doubling it", () => { const [contour] = parsePath("M0 0C1 0 2 1 2 2C2 3 1 4 0 4C-1 4 0 1 0 0Z"); expect(contour).toHaveLength(3); expect(contour![0]!.in).toEqual({ x: 0, y: 1 }); }); it("keeps straight lines as anchors without handles", () => { const [contour] = parsePath("M0 0L4 0L4 4Z"); expect(contour).toHaveLength(3); expect(contour!.every((node) => !node.in && !node.out)).toBe(true); }); }); describe("toPath", () => { it("round trips the mark", () => { const d = toPath(parsePath(DOLLY)); expect(toPath(parsePath(d))).toBe(d); expect(parsePath(d).flat()).toHaveLength(parsePath(DOLLY).flat().length); }); it("writes lines where a segment has no handles", () => { expect(toPath(parsePath("M0 0L4 0L4 4Z"))).toBe("M0 0L4 0L4 4L0 0z"); }); }); describe("smooth", () => { it("tells a smooth node from a corner", () => { expect(smooth({ x: 0, y: 0, in: { x: -1, y: 0 }, out: { x: 2, y: 0 } })).toBe(true); expect(smooth({ x: 0, y: 0, in: { x: -1, y: 0 }, out: { x: 0, y: 2 } })).toBe(false); expect(smooth({ x: 0, y: 0, out: { x: 2, y: 0 } })).toBe(false); }); }); describe("across", () => { it("points straight through the anchor at the given length", () => { const p = across({ x: 0, y: 0 }, { x: 3, y: 4 }, 10); expect(p.x).toBeCloseTo(-6); expect(p.y).toBeCloseTo(-8); }); });