import { describe, expect, it } from "@suaveplan/testing/runner"; import fc from "fast-check"; import { CURRENT_SCHEMA_VERSION } from "../src/constants/constants.js"; import { CONTROL_KIND_VALUES } from "../src/types/control-kind.types.js"; import type { Control, ControlNode, Group, } from "../src/types/control-node.types.js"; import type { ControlSurface } from "../src/types/control-surface.types.js"; import { validateSurface } from "../src/validate/validate.js"; import { walkSurface } from "../src/walk/walk.js"; const idArb = fc.uuidV(7).map((s) => s.toString()); const controlKindArb = fc.constantFrom(...CONTROL_KIND_VALUES); const controlLeafArb: fc.Arbitrary = fc.record({ type: fc.constant("control" as const), id: idArb, kind: controlKindArb, transform: fc.record({ position: fc.record({ x: fc.integer({ min: -1000, max: 1000 }), y: fc.integer({ min: -1000, max: 1000 }), }), }), }); const nodeArb: fc.Arbitrary = fc.letrec<{ node: ControlNode; group: Group; }>((tie) => ({ node: fc.oneof({ depthSize: "small" }, controlLeafArb, tie("group")), group: fc.record({ type: fc.constant("group" as const), id: idArb, layout: fc.constant({ kind: "absolute" as const }), transform: fc.record({ position: fc.record({ x: fc.integer({ min: -100, max: 100 }), y: fc.integer({ min: -100, max: 100 }), }), }), children: fc.array(tie("node"), { maxLength: 4 }), }), })).node; const surfaceArb: fc.Arbitrary = fc.record({ id: idArb, name: fc.string({ minLength: 1, maxLength: 16 }), version: fc.constant(CURRENT_SCHEMA_VERSION), createdAt: fc.integer({ min: 0, max: 2 ** 40 }), updatedAt: fc.integer({ min: 0, max: 2 ** 40 }), skin: fc.record({ id: fc.constant("default") }), root: nodeArb, }); function dedupeIds( node: ControlNode, seen: Set, depth = 0 ): ControlNode { let id = node.id; while (seen.has(id)) id = `${node.id}-${seen.size}-${depth}`; seen.add(id); if (node.type === "control") return { ...node, id }; return { ...node, id, children: node.children.map((c) => dedupeIds(c, seen, depth + 1)), }; } describe("property tests", () => { it("validator accepts well-formed random surfaces", { timeout: 5000, }, () => { fc.assert( fc.property(surfaceArb, (s) => { const surface: ControlSurface = { ...s, root: dedupeIds(s.root, new Set()), }; const result = validateSurface(surface); if (result.error !== undefined) { throw result.error; } expect(result.surface).toBeDefined(); }), { numRuns: 50 } ); }); it("walkSurface visits every node exactly once", { timeout: 5000 }, () => { fc.assert( fc.property(surfaceArb, (s) => { const surface: ControlSurface = { ...s, root: dedupeIds(s.root, new Set()), }; const validated = validateSurface(surface); expect(validated.surface).toBeDefined(); const seen = new Set(); walkSurface(validated.surface!, (n) => seen.add(n.id)); let count = 0; const tally = (n: ControlNode): void => { count += 1; if (n.type === "group") { for (const c of n.children) tally(c); } }; tally(validated.surface!.root); expect(seen.size).toBe(count); }), { numRuns: 30 } ); }); });