/* RFC-0564: Property-based tests for the G-Set genome log merge operation. Verifies commutativity, associativity, and idempotency properties of mergeGenomeLogs using fast-check. Do not test command handlers — those are integration tests. Fixtures stay inline and minimal so each case states its own setup. RFC-0564: initial implementation — G-Set merge property-based tests. */ // @ai-invariant fixtures must not couple to internals beyond the public surface under test import { describe, it, expect } from "vitest"; import fc from "fast-check"; import { mergeGenomeLogs } from "./genome-log.ts"; import type { GenomeLogEntry } from "./types.ts"; const entryArbitrary = fc.record({ workshopId: fc.string({ minLength: 1, maxLength: 20 }), event: fc.constantFrom("alive", "suspect", "dead", "left"), timestamp: fc.string({ minLength: 1, maxLength: 30 }), source: fc.string({ minLength: 1, maxLength: 20 }), signature: fc.string({ minLength: 1, maxLength: 40 }), }); const logArbitrary = fc.array(entryArbitrary, { maxLength: 20 }); function sameEntries(a: GenomeLogEntry[], b: GenomeLogEntry[]): boolean { if (a.length !== b.length) return false; const aIds = new Set(a.map((e) => `${e.workshopId}|${e.event}|${e.timestamp}|${e.source}`)); const bIds = new Set(b.map((e) => `${e.workshopId}|${e.event}|${e.timestamp}|${e.source}`)); if (aIds.size !== bIds.size) return false; for (const id of aIds) { if (!bIds.has(id)) return false; } return true; } describe("mergeGenomeLogs properties (G-Set)", () => { it("commutativity: merge(a, b) == merge(b, a)", () => { fc.assert( fc.property(logArbitrary, logArbitrary, (a, b) => { const mergeAB = mergeGenomeLogs(a, b); const mergeBA = mergeGenomeLogs(b, a); expect(sameEntries(mergeAB, mergeBA)).toBe(true); }), ); }); it("associativity: merge(merge(a, b), c) == merge(a, merge(b, c))", () => { fc.assert( fc.property(logArbitrary, logArbitrary, logArbitrary, (a, b, c) => { const mergeAB_C = mergeGenomeLogs(mergeGenomeLogs(a, b), c); const mergeA_BC = mergeGenomeLogs(a, mergeGenomeLogs(b, c)); expect(sameEntries(mergeAB_C, mergeA_BC)).toBe(true); }), ); }); it("idempotency: merge(a, a) == a", () => { fc.assert( fc.property(logArbitrary, (a) => { const merged = mergeGenomeLogs(a, a); expect(sameEntries(merged, a)).toBe(true); }), ); }); });