Spaces:
Running
Running
| // Parity pins between engine/wire.ts and /schema/event.schema.json — the | |
| // cross-language contract. If these fail, one side of the wire drifted. | |
| import { readFileSync } from "node:fs"; | |
| import { join } from "node:path"; | |
| import { describe, expect, it } from "vitest"; | |
| import { EVENTS } from "./events"; | |
| import { | |
| isWireEvent, | |
| TEMPLATES, | |
| toEventDef, | |
| WIRE_OPTIONAL, | |
| WIRE_REQUIRED, | |
| WIRE_SOURCES, | |
| type WireEvent, | |
| } from "./wire"; | |
| const schema = JSON.parse(readFileSync(join(__dirname, "../../../schema/event.schema.json"), "utf8")); | |
| describe("schema parity", () => { | |
| it("required fields match the JSON schema", () => { | |
| expect([...WIRE_REQUIRED].sort()).toEqual([...schema.required].sort()); | |
| }); | |
| it("all schema properties are known to the TS side", () => { | |
| expect(Object.keys(schema.properties).sort()).toEqual([...WIRE_REQUIRED, ...WIRE_OPTIONAL].sort()); | |
| }); | |
| it("source enum matches the JSON schema", () => { | |
| expect([...WIRE_SOURCES].sort()).toEqual([...schema.properties.source.enum].sort()); | |
| }); | |
| }); | |
| describe("isWireEvent", () => { | |
| it("accepts a minimal valid event", () => { | |
| expect(isWireEvent({ source: "claude", type: "task_completed", title: "Done" })).toBe(true); | |
| }); | |
| it("rejects unknown sources, empty fields, and non-objects", () => { | |
| expect(isWireEvent({ source: "slack", type: "x", title: "y" })).toBe(false); | |
| expect(isWireEvent({ source: "claude", type: "", title: "y" })).toBe(false); | |
| expect(isWireEvent({ source: "claude", type: "x", title: "" })).toBe(false); | |
| expect(isWireEvent(null)).toBe(false); | |
| expect(isWireEvent("claude")).toBe(false); | |
| }); | |
| }); | |
| describe("TEMPLATES integrity", () => { | |
| it("every template id resolves to a deck event (renames can't silently fall through)", () => { | |
| const ids = new Set(EVENTS.map((e) => e.id)); | |
| for (const id of Object.values(TEMPLATES)) expect(ids).toContain(id); | |
| }); | |
| }); | |
| describe("toEventDef", () => { | |
| const claude: WireEvent = { | |
| source: "claude", | |
| type: "task_completed", | |
| title: "Implement wire schema", | |
| summary: "3 files changed", | |
| }; | |
| it("borrows the matching template's scoring", () => { | |
| const def = toEventDef(claude); | |
| const template = EVENTS.find((e) => e.id === "claude_done"); | |
| expect(def.base).toEqual(template?.base); | |
| expect(def.source).toBe("Claude"); | |
| expect(def.lines.plain).toBe("Implement wire schema — 3 files changed"); | |
| }); | |
| it("real events never mutate sim windows and have no flight target", () => { | |
| const def = toEventDef(claude); | |
| expect(def.effect).toBe("none"); | |
| expect(def.target).toBeNull(); | |
| }); | |
| it("unknown types get middling fallback scores (never an interrupt)", () => { | |
| const def = toEventDef({ source: "build", type: "linted", title: "Lint clean" }); | |
| expect(def.base.urgency).toBeLessThan(80); | |
| expect(def.lines.plain).toBe("Lint clean"); | |
| }); | |
| it("build failures map to the urgent template", () => { | |
| const def = toEventDef({ source: "build", type: "tests_failed", title: "2 failing" }); | |
| expect(def.base).toEqual(EVENTS.find((e) => e.id === "build_fail")?.base); | |
| }); | |
| }); | |