testMergeSummary
tcmts.cli.mcp.testMergeSummary · #yjfjpvhk · term
import { mergeSummary } from "#codebase/tcmts/cli/mcp";
import assert from "node:assert/strict";
export const testMergeSummary = () => {
assert.equal(
mergeSummary("merged main into session/x\n no changes\n\n merged cleanly"),
"merged main into session/x\n no changes\n merged cleanly",
);
const out = [
"fast-forwarded main to session/x",
"",
" edited",
" ~ lib.square #aaaaaaaa → #bbbbbbbb",
" export const square = (x: number) =>",
" - x * x",
" + x ** 2",
"",
" updated because a dependency changed (code unchanged)",
" ~ lib.area #cccccccc → #dddddddd via lib.square",
" ~ lib.volume #eeeeeeee → #ffffffff via lib.square",
].join("\n");
assert.equal(
mergeSummary(out),
"fast-forwarded main to session/x\n edited: lib.square\n updated because a dependency changed (code unchanged): 2",
);
// a merge stopping on a conflict: what's conflicted by name, and the conflict lines (not every edit's code)
const conflicted = [
"merged main into session/x",
"",
" edited",
" ~ lib.render #aaaaaaaa → #bbbbbbbb",
" - export const render = () => 1",
" + export const render = () => 2",
"",
" conflicted",
" ! lib.Store #cccccccc, #dddddddd",
"",
" merged as text lib.Codebase (both sides edited it, apart: their edits are combined, and it typechecks)",
" conflict lib.Store: cccccccc (ours: session/x) vs dddddddd (theirs: main) tcm resolve lib.Store cccccccc keeps ours: session/x",
].join("\n");
const brief = mergeSummary(conflicted);
assert.match(brief, /^ {2}edited: lib\.render$/m);
assert.match(brief, /^ {2}conflicted: lib\.Store$/m);
assert.match(brief, /^ {2}merged as text lib\.Codebase/m);
assert.match(
brief,
/^ {2}conflict lib\.Store: cccccccc \(ours: session\/x\) vs dddddddd \(theirs: main\)/m,
);
assert.doesNotMatch(brief, /export const/);
}
uses