testConflictUsingAnotherConflict
A conflict whose sides merge cleanly but that uses another conflicted name can't typecheck until that's settled:
tcm edit says so (not that it "didn't typecheck"), as tcm check does, and editing both puts them in one file,
where they check together; saving it resolves both, named so in history.
import { okIn, tcmIn, tempDir } from "#codebase/tcmts/cli/test/e2e/harness"; import assert from "node:assert/strict"; import fs from "node:fs"; import path from "node:path"; export const testConflictUsingAnotherConflict = () => { const dir = tempDir("merge uses conflict"); const tcm = (...args: string[]) => okIn(dir, ...args); const update = (code: string) => { fs.writeFileSync(path.join(dir, "scratch.ts"), `// tcm: namespace lib\n${code}\n`); tcm("update"); }; const k = (a: number) => `export const k = (): number => {\n const a = ${a};\n return a;\n};`; const m = (x: string, r: string) => `export const m = (): number => {\n const x = ${x};\n const y = 1;\n return ${r};\n};`; tcm("init"); update(`${k(1)}\n${m("k()", "x + y")}`); tcm("branch", "s"); tcm("switch", "s"); update(`${k(10)}\n${m("k() * 2", "x + y")}`); tcm("switch", "main"); update(`${k(100)}\n${m("k()", "x + y + 1")}`); tcm("switch", "s"); assert.equal(tcmIn(dir, "merge", "main").status, 1); const todo = tcm("todo"); assert.match(todo, /conflict lib\.k/); assert.match(todo, /conflict lib\.m/); const alone = tcm("edit", "lib.m"); assert.match(alone, /^wrote lib\.m to lib\.m\.ts$/m); assert.match( alone, /no lines both changed, but it can't typecheck yet: uses lib\.k, which is still conflicted: settle that first .*or edit both together: `tcm edit lib\.m lib\.k`/, ); assert.doesNotMatch(alone, /didn't typecheck/); const checked = tcmIn(dir, "check", "lib.m.ts"); assert.notEqual(checked.status, 0); assert.match(checked.out, /lib\.m\.ts uses lib\.k, which is still conflicted/); // both, in one file (the one written for lib.m alone, untouched, is replaced) assert.match(tcm("edit", "lib.m", "lib.k"), /^wrote lib\.m, lib\.k to lib\.m\.ts$/m); const file = path.join(dir, "lib.m.ts"); const text = fs.readFileSync(file, "utf8"); assert.doesNotMatch(text, /import \{ k \}/, "what it holds isn't imported"); assert.match(text, /const x = k\(\) \* 2;[\s\S]*return x \+ y \+ 1;/, "both sides of lib.m"); fs.writeFileSync( file, text.replace(/<<<<<<< [\s\S]*>>>>>>> theirs \(main\)\n/, " const a = 1000;\n"), ); assert.match(tcm("check", "lib.m.ts"), /resolves +lib\.m[\s\S]*resolves +lib\.k/); tcm("update", "lib.m.ts"); assert.doesNotMatch(tcm("todo"), /conflict/); assert.equal(tcm("run", "lib.m").trim(), String(1000 * 2 + 1 + 1)); assert.match(tcm("history"), /resolve lib\.m \(merged\), lib\.k \(merged\)/); }