testCycleUpdatedWhole

tcmts.cli.test.e2e.cycles.testCycleUpdatedWhole · #klsbyfws · term

A cycle is updated whole: changing one member saves the rest with it, so none uses an old one.

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 testCycleUpdatedWhole = () => {
  const dir = tempDir("cycles");
  const ok = (...args: string[]) => okIn(dir, ...args);
  ok("init");
  fs.writeFileSync(path.join(dir, "scratch.ts"), `// tcm: namespace lib\nexport function isEven(n: number): boolean { return n === 0 ? true : isOdd(n - 1); }\nexport function isOdd(n: number): boolean { const unused = 1; return n === 0 ? false : isEven(n - 1); }\n`);
  assert.match(ok("add"), /'unused' is declared but never used/);

  // a file changing one member, using the other from the codebase: the other is saved with it, as it is
  fs.writeFileSync(path.join(dir, "partial.ts"), `// tcm: namespace lib\nimport { isOdd } from "#codebase/lib";\nexport function isEven(n: number): boolean { console.log("even", n); return n === 0 ? true : isOdd(n - 1); }\n`);
  const partial = ok("update", "partial.ts");
  assert.match(partial, /with lib\.isOdd: in a cycle with what changed, so saved with it, as it is/);
  assert.match(partial, /~ update +lib\.isEven[\s\S]*~ update +lib\.isOdd/);
  // (only what changed is linted: isOdd is re-hashed with isEven, but its code is as it was)
  assert.doesNotMatch(partial, /unused/);
  assert.equal(ok("run", "lib.isOdd", "3"), "even 2\neven 0\ntrue\n", "isOdd runs the new isEven");

  // edit writes only what's asked for, and says what it's in a cycle with (scratch.ts holds the versions just
  // replaced, which aren't saved as they are: isEven is in it already, and --force starts it again)
  assert.match(tcmIn(dir, "edit", "lib.isEven").out, /lib\.isEven is in scratch\.ts already/);
  assert.match(ok("edit", "--force", "lib.isEven"), /in a cycle with lib\.isOdd: saving it saves that too, as it is/);
  const scratch = path.join(dir, "scratch.ts");
  assert.doesNotMatch(fs.readFileSync(scratch, "utf8"), /function isOdd/);
  fs.writeFileSync(scratch, fs.readFileSync(scratch, "utf8").replace(`console.log("even", n);`, `console.log("even:", n);`));
  assert.match(ok("check"), /with lib\.isOdd: in a cycle with what changed[\s\S]*~ update +lib\.isOdd/);
  assert.match(ok("update"), /~ update +lib\.isEven[\s\S]*~ update +lib\.isOdd/);
  assert.equal(ok("run", "lib.isOdd", "1"), "even: 0\ntrue\n");
}

uses