testPageConflictWithImporter

tcmts.cli.test.e2e.merge.testPageConflictWithImporter · #go3amaqo · term

Both sides edit a page that code imports. Edits apart are merged as text, and the code follows the merged page; edits that overlap are a conflict, and resolving it re-derives the code against the page kept.

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 testPageConflictWithImporter = () => {
  const dir = tempDir("merge page");
  const tcm = (...args: string[]) => okIn(dir, ...args);
  const page = (text: string) => {
    fs.writeFileSync(path.join(dir, "notes.md"), text);
    tcm("update", "notes.md", "--into", "docs");
  };
  tcm("init");
  fs.writeFileSync(path.join(dir, "notes.md"), "# Notes\n\n- one\n- two\n- three\n- four\n");
  tcm("add", "notes.md", "--into", "docs");
  fs.writeFileSync(
    path.join(dir, "scratch.ts"),
    `// tcm: namespace site\nimport { notes } from "#codebase/docs";\nexport const SOURCES = { notes };\n`,
  );
  tcm("add");
  tcm("branch", "b");
  tcm("branch", "c");
  tcm("branch", "m");
  tcm("switch", "m");

  // apart: merged as text
  page("# Notes\n\n- one, first\n- two\n- three\n- four\n");
  tcm("switch", "b");
  page("# Notes\n\n- one\n- two\n- three\n- four, last\n");
  tcm("switch", "m");
  const merged = tcmIn(dir, "merge", "b");
  assert.equal(merged.status, 0, merged.out);
  assert.match(merged.out, /merged as text docs\.notes/);
  assert.match(tcm("view", "docs.notes"), /one, first[\s\S]*four, last/);
  assert.doesNotMatch(tcm("todo"), /unnamed version|conflict/);

  // overlapping: a conflict, and resolving it re-derives the importer
  tcm("switch", "c");
  page("# Notes\n\n- one\n- two, from c\n- three\n- four\n");
  tcm("switch", "m");
  const conflicted = tcmIn(dir, "merge", "c");
  assert.equal(conflicted.status, 1, conflicted.out);
  const line =
    /conflict docs\.notes: (\S+) \((ours|theirs): (m|c)\) vs (\S+) \((ours|theirs): (m|c)\)/.exec(
      conflicted.out,
    );
  assert.ok(line, conflicted.out);
  const theirs = line[2] === "theirs" ? line[1]! : line[4]!;
  assert.doesNotMatch(tcm("todo"), /unnamed version/);
  tcm("resolve", "docs.notes", theirs);
  const todo = tcm("todo");
  assert.doesNotMatch(todo, /unnamed version/);
  assert.match(todo, /nothing to do/);
  assert.match(tcm("view", "docs.notes"), /two, from c/);
}

uses