testCycleMatesKeepTheirFunctionNames

tcmts.cli.test.e2e.editing.testCycleMatesKeepTheirFunctionNames · #qrq3i2gv · term

A change that puts a scratch file's definition in a cycle brings the cycle's other members along, written as they're stored (withCycle); a function's or class's name is part of its hash, so it isn't saved if one of them would have to be written with another name: two functions called find from two namespaces (one would be find_1), or a find the file itself declares. Nothing is saved then, and saying so names which and why, not the checker's errors of a file declaring find twice.

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 testCycleMatesKeepTheirFunctionNames = () => {
  const dir = tempDir("cycle mates keep names");
  const ok = (...args: string[]) => okIn(dir, ...args);
  ok("init");
  fs.rmSync(path.join(dir, "scratch.ts"), { force: true });
  const write = (f: string, text: string) => fs.writeFileSync(path.join(dir, f), text);
  write("lib.ts", `// tcm: namespace lib\nexport const run = (n: number): number => n;\n`);
  ok("add", "lib.ts");
  write(
    "b.ts",
    `// tcm: namespace b\nimport { run } from "#codebase/lib";\nexport function find(n: number): number {\n  return n <= 0 ? 1 : run(n - 1);\n}\n`,
  );
  ok("add", "b.ts");
  write(
    "a.ts",
    `// tcm: namespace a\nimport { find as findB } from "#codebase/b";\nexport function find(n: number): number {\n  return n <= 0 ? 0 : findB(n - 1);\n}\n`,
  );
  ok("add", "a.ts");
  const before = ok("view", "lib.run", "a.find", "b.find");
  // lib.run calling a.find makes a cycle of the three: a.find and b.find, written with it, would be declared alike
  write(
    "lib.ts",
    `// tcm: namespace lib\nimport { find } from "#codebase/a";\nexport const run = (n: number): number => find(n);\n`,
  );
  const alike = tcmIn(dir, "update", "lib.ts");
  assert.notEqual(alike.status, 0, alike.out);
  assert.match(
    alike.out,
    /[ab]\.find would be written as find_1 with the rest, and a function's or class's name is part of its hash/,
  );
  assert.doesNotMatch(alike.out, /TS2393|declared more than once/);
  // a find of the file's own, beside the one the cycle brings
  write(
    "lib.ts",
    `// tcm: namespace lib\nimport { find as findB } from "#codebase/b";\nexport const run = (n: number): number => findB(n);\nexport function find(): number {\n  return 0;\n}\n`,
  );
  const beside = tcmIn(dir, "update", "lib.ts");
  assert.notEqual(beside.status, 0, beside.out);
  assert.match(beside.out, /b\.find would be written beside the find the file declares/);
  assert.doesNotMatch(beside.out, /TS2393|declared more than once/);
  assert.equal(ok("view", "lib.run", "a.find", "b.find"), before);
  assert.doesNotMatch(ok("ls", "lib"), /lib\.find/);
}

uses