testCycleMatesKeepTheirFunctionNames
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/); }