clone

a deno framework for local-first web apps that open instantly, work offline and sync when users choose

feat/184-task-notice-migration
lofi / package / testing / scenario / fuzz_generator_test.ts
fuzz_generator_test.ts 3.2K
1// The fuzz generator is pure: these tests pin seed determinism and the2// structural invariants the executor relies on, without booting a server.3import { assert } from "../../runtime/test-assert.ts";4import { type FuzzColumn, type FuzzPlanInput, generateFuzzPlan } from "./fuzz.ts";56const columns: readonly FuzzColumn[] = [7 { name: "id", type: "Uuid", nullable: false, hasDefault: true },8 { name: "title", type: "Text", nullable: false, hasDefault: false },9 { name: "done", type: "Boolean", nullable: false, hasDefault: true },10];1112const input: FuzzPlanInput = {13 seed: 42,14 steps: 60,15 peers: ["alice", "bob"],16 tables: { documents: columns },17};1819Deno.test("same seed yields an identical plan", () => {20 const first = generateFuzzPlan(input);21 const second = generateFuzzPlan(input);22 assert(23 JSON.stringify(first) === JSON.stringify(second),24 "two runs of the generator with one seed diverged",25 );26 assert(first.ops.length > 0, "the plan generated no operations");27});2829Deno.test("plans keep their structural invariants", () => {30 for (const seed of [1, 7, 99, 12345]) {31 const plan = generateFuzzPlan({ ...input, seed });32 const insertsByRef = new Map<number, { table: string; peer: string }>();33 const barrierKnown = new Set<number>();34 const offline = new Set<string>();35 for (const op of plan.ops) {36 if (op.kind === "insert") {37 insertsByRef.set(op.ref, { table: op.table, peer: op.peer });38 } else if (op.kind === "update" || op.kind === "remove") {39 const origin = insertsByRef.get(op.ref);40 assert(origin !== undefined, `seed ${seed}: op targets ref ${op.ref} before its insert`);41 assert(origin.table === op.table, `seed ${seed}: op targets ref ${op.ref} across tables`);42 assert(43 origin.peer === op.peer || barrierKnown.has(op.ref),44 `seed ${seed}: ${op.peer} targets a row it cannot have observed`,45 );46 } else if (op.kind === "offline") {47 assert(!offline.has(op.peer), `seed ${seed}: ${op.peer} went offline twice`);48 offline.add(op.peer);49 } else if (op.kind === "online") {50 assert(offline.has(op.peer), `seed ${seed}: ${op.peer} came online while online`);51 offline.delete(op.peer);52 } else {53 assert(offline.size === 0, `seed ${seed}: sync barrier while a peer is offline`);54 for (const ref of insertsByRef.keys()) barrierKnown.add(ref);55 }56 }57 assert(offline.size === 0, `seed ${seed}: the plan ends with a peer offline`);58 }59});6061Deno.test("tables the generator cannot insert into are skipped", () => {62 const plan = generateFuzzPlan({63 ...input,64 tables: {65 documents: columns,66 attachments: [67 { name: "id", type: "Uuid", nullable: false, hasDefault: true },68 {69 name: "document",70 type: "Uuid",71 nullable: false,72 hasDefault: false,73 references: "documents",74 },75 ],76 },77 });78 assert(79 plan.skippedTables.length === 1 && plan.skippedTables[0] === "attachments",80 "a required foreign-key table was not skipped",81 );82 assert(83 plan.ops.every((op) =>84 op.kind === "offline" || op.kind === "online" || op.kind === "sync" ||85 op.table === "documents"86 ),87 "an op targeted a skipped table",88 );89});