testContributionMergesAsText
A contribution editing a definition its target changed too, apart, is previewed as the merge settles it: merged as text, not a conflict, and merged so. One whose edits are apart but don't typecheck merged is refused, and the target is left as it was (no conflict on it).
import { codebase } from "#codebase/tcmts/cli/test/e2e/contributions"; import { tempDir } from "#codebase/tcmts/cli/test/e2e/harness"; import assert from "node:assert/strict"; export const testContributionMergesAsText = () => { const root = tempDir("contributions as text"); const server = codebase(root, "server"); const k = (a: string, c: string) => `// tcm: namespace lib\nexport const k = (): number => {\n const a: number | string = ${a};\n const b = 2;\n const c = ${c};\n return Number(a) + b + c;\n};\n`; server.write(k("1", "3")); server.tcm("add"); const me = codebase(root, "me"); me.tcm("remote", "add", "origin", server.dir); me.tcm("pull"); const contribute = (branch: string, code: string) => { me.tcm("switch", branch); me.write(code); me.tcm("update"); me.tcm("contribute", "--title", branch); }; me.tcm("branch", "a"); me.tcm("branch", "b"); contribute("a", k("10", "3")); me.tcm("contribution", "merge", "1"); contribute("b", k("1", "30")); assert.match(me.tcm("contribution", "view", "2"), /✓ merges cleanly, lib\.k merged as text/); assert.match(me.tcm("contribution", "merge", "2"), /merged #2/); assert.equal(server.tcm("run", "lib.k").trim(), "42"); me.tcm("switch", "main"); me.tcm("pull"); me.tcm("branch", "x"); me.tcm("branch", "y"); contribute("x", k('"1"', "30")); me.tcm("contribution", "merge", "3"); contribute("y", k("10", "a.toFixed().length")); assert.match(me.tcm("contribution", "view", "4"), /lib\.k merged as text/); const refused = me.run("contribution", "merge", "4"); assert.notEqual(refused.status, 0); assert.match( refused.out, /#4 conflicts with main in lib\.k \(both edited apart, but merged it doesn't typecheck\)/, ); assert.match(server.tcm("todo"), /nothing to do/); assert.equal(server.tcm("run", "lib.k").trim(), "33"); }