import test from "node:test"; import assert from "node:assert/strict"; import { editStructure, scaffoldResourceSource, instantiateWorkspaceIdentity, } from "../src/capability-language/structural-edits.js"; test("template identity binding changes only the workspace header and is idempotent", () => { const source = '// workspace fake id "do-not-touch"\nworkspace Todo id "workspace:todo" revision "workspace:todo@1" commit "' + "a".repeat(40) + '" { atom Task id "atom:task"; }'; const id = "00000000-0000-0000-0000-000000000123"; const bound = instantiateWorkspaceIdentity(source, id); assert.match(bound, /atom Task id "atom:task"/); assert.ok(bound.startsWith('// workspace fake id "do-not-touch"')); assert.ok(bound.includes(`workspace Todo id "${id}"`)); assert.equal(instantiateWorkspaceIdentity(bound, id), bound); assert.throws(() => instantiateWorkspaceIdentity(source, "not-a-workspace"), /UUID/); }); test("package scaffolding and function edits preserve surrounding source and use exact selectors", () => { const source = `// 🧭 resource comment\n${scaffoldResourceSource("package", "Chess", "package:chess", "package:chess@1")}`; const functionSource = 'function evaluate id "export:evaluate" : string -> string;'; const appended = editStructure(source, { operation: "append", parent: { kind: "packageResourceDecl", id: "package:chess" }, source: functionSource, }); assert.ok(appended.startsWith("// 🧭 resource comment\n")); assert.ok(appended.includes(functionSource)); const replaced = editStructure(appended, { operation: "replace", target: { kind: "packageFunctionExport", id: "export:evaluate" }, source: 'function evaluate id "export:evaluate" : unit -> string;', }); assert.ok(replaced.includes(": unit -> string;")); assert.ok( !editStructure(replaced, { operation: "remove", target: { kind: "packageFunctionExport", id: "export:evaluate" }, }).includes("evaluate"), ); assert.throws( () => editStructure(source, { operation: "remove", target: { kind: "packageResourceDecl", id: "package:chess@1" } }), /exactly once/, ); assert.throws( () => editStructure(source, { operation: "append", parent: { kind: "packageResourceDecl" }, source: "not valid QX" }), /Invalid structural/, ); const prefixed = `import interface Board;\nexternal atom Game id "atom:game";\n${source}`; const replacedPackage = editStructure(prefixed, { operation: "replace", target: { kind: "packageResourceDecl", id: "package:chess" }, source: scaffoldResourceSource("package", "Chess", "package:chess", "package:chess@2"), }); assert.ok(replacedPackage.startsWith('import interface Board;\nexternal atom Game id "atom:game";')); }); test("dependency scaffolding validates exact sources and preserves unrelated lock comments", () => { const source = `// 🧭 lock\nquixos-lock version 1 {\n quixos source { repository "https://example.test/quixos.git"; commit "${"a".repeat(40)}"; }\n // retained comment\n}\n`; const dependency = { operation: "dependency" as const, kind: "package" as const, name: "Chess", source: { repository: "https://example.test/chess.git", commit: "b".repeat(40) }, }; const appended = editStructure(source, dependency); assert.ok(appended.includes("// retained comment")); assert.ok(appended.startsWith("// 🧭 lock\n")); assert.throws( () => editStructure(source, { ...dependency, source: { ...dependency.source, commit: "main" } }), /Invalid dependency/, ); const changed = editStructure(appended, { ...dependency, source: { ...dependency.source, commit: "c".repeat(40) } }); assert.ok(!changed.includes("b".repeat(40))); assert.ok(!editStructure(changed, { ...dependency, source: null }).includes("package Chess")); }); test("conformance enrollment, major edits, imports, and private attachment removal preserve valid structure", () => { const source = `fragment { conform Game as Playable { private state Board id "slot:board" on Game : string policy optimistic-register; } }`; const selector = { kind: "conformanceDecl", names: ["Game", "Playable"] }; const enrolled = editStructure(source, { operation: "conformance-id", target: selector, id: "conformance:playable" }); assert.ok(enrolled.includes('as Playable id "conformance:playable"')); const major = editStructure(enrolled, { operation: "semantic-major", target: { kind: "conformanceDecl", id: "conformance:playable" }, major: 2, }); assert.ok(major.includes("semantic-major 2")); assert.throws( () => editStructure(major, { operation: "conformance-id", target: selector, id: "different" }), /Cannot change/, ); const removed = editStructure(major, { operation: "remove", target: { kind: "stateDecl", id: "slot:board" } }); assert.ok(!removed.includes("private")); const imported = editStructure(removed, { operation: "import", kind: "interface", name: "Playable" }); assert.equal(editStructure(imported, { operation: "import", kind: "interface", name: "Playable" }), imported); });