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); });