testSharedDependencyChangedOnBothSides
Both sides change a class their code shares (each adding a method), and one side's code uses its own method. The class is merged as text (the edits are apart), and the code taken from either side is re-derived against it, through what's between (each side had re-derived it for its own class): nothing is left using a version nothing names.
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 testSharedDependencyChangedOnBothSides = () => { const dir = tempDir("merge shared"); 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 store = (first: string, second: string) => `export class Store {\n a(): number {\n return 1;\n }\n${first}\n b(): number {\n return 2;\n }\n${second}}`; tcm("init"); update(store("", "")); update(`import { Store } from "#codebase/lib"; export class Codebase { store = new Store(); } export const render = (cb: Codebase) => cb.store.a(); export const main = () => render(new Codebase());`); tcm("branch", "b"); // main adds a method after a(); b adds one after b(), and code using it update(store("\n x(): number {\n return 10;\n }\n", "")); tcm("switch", "b"); update(store("", "\n y(): number {\n return 3;\n }\n")); update( `import { Codebase } from "#codebase/lib";\nexport const render = (cb: Codebase) => cb.store.a() + cb.store.y();`, ); tcm("switch", "main"); const merged = tcmIn(dir, "merge", "b"); assert.equal(merged.status, 0, merged.out); assert.match(merged.out, /merged as text lib\.Store/); assert.doesNotMatch(merged.out, /conflict|no longer typecheck/); assert.match(merged.out, /merged cleanly/); assert.equal(tcm("run", "lib.main").trim(), "4"); assert.match(tcm("view", "lib.Store"), /x\(\): number[\s\S]*y\(\): number/); const todo = tcm("todo"); assert.doesNotMatch(todo, /unnamed version/); assert.match(todo, /nothing to do/); }