import assert from "node:assert/strict"; import { test } from "node:test"; import { compileCapabilityResourceSource, compileCapabilitySource } from "../src/capability-language/parser.js"; import { formatQx } from "../src/capability-language/source.js"; import { compileExecutionPlan, compileKernelProgram } from "../src/execution-world/index.js"; const contract = `interface Item id "item" revision "item@1" { operation remove id "remove" : unit -> unit { call id "remove:call" execution transaction; } }`; const workspace = `workspace Lifecycle id "workspace:lifecycle" revision "workspace:lifecycle@1" commit "${"a".repeat(40)}" { import interface Item; atom Node id "node"; conform Node as Item id "node:item" { private edge Links id "links" { atom Node projection children id "children" many on-delete "cascade-other"; atom Node projection parent id "parent" optional-one on-delete "detach"; } bind remove.call to lifecycle.delete; } }`; function compile(ifaceSource = contract, workspaceSource = workspace) { const iface = compileCapabilityResourceSource(ifaceSource, { source: { repository: "https://example.test/lifecycle.git", commit: "a".repeat(40) }, }); assert.ok(iface.ok && iface.resource.kind === "interface", JSON.stringify(iface.diagnostics)); return compileCapabilitySource(workspaceSource, "workspace.qx", { interfaces: new Map([["Item", iface.resource.revision]]), }); } test("lifecycle binding and endpoint policies survive formatting and kernel compilation", () => { const result = compile(); assert.ok(result.ok, JSON.stringify(result.diagnostics)); const formatted = compile(formatQx(contract), formatQx(workspace)); assert.ok(formatted.ok, JSON.stringify(formatted.diagnostics)); const plan = compileExecutionPlan(result.workspace); assert.equal(compileExecutionPlan(formatted.workspace).digest, plan.digest); const kernel = compileKernelProgram(plan) as { operations: { binding: unknown }[]; model: { edges: { a: { onDelete: string }; b: { onDelete: string } }[] }; }; assert.deepEqual(kernel.operations[0]!.binding, { kind: "lifecycle", primitive: "delete" }); assert.equal(kernel.model.edges[0]!.a.onDelete, "cascade-other"); assert.equal(kernel.model.edges[0]!.b.onDelete, "detach"); }); test("deletion rejects browser, snapshot, remote, class, payload and unknown primitive promises", () => { for (const [iface, ws] of [ [contract.replace("execution transaction", "execution snapshot"), workspace], [contract.replace("execution transaction", "execution remote"), workspace], [contract.replace("execution transaction", ""), workspace], [contract.replace("operation remove", "static operation remove"), workspace], [contract.replace("unit -> unit", "string -> unit"), workspace], [contract.replace("unit -> unit", "unit -> string"), workspace], [contract, workspace.replace("lifecycle.delete", "lifecycle.resurrect")], ]) { const result = compile(iface, ws); assert.equal(result.ok, false, iface + ws); assert.ok( result.diagnostics.some((d) => ["invalid-execution-contract", "invalid-lifecycle-binding", "invalid-package-binding"].includes(d.code), ), JSON.stringify(result.diagnostics), ); } });