testSuitesFollowMethodsAndConstantsTheyRead
What a suite ran, finer than definitions where a definition is big: a class by the methods it used (a change to another of its methods keeps the result), and a written-out constant only when code that ran reads it (one that was only loaded keeps it).
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 testSuitesFollowMethodsAndConstantsTheyRead = () => { const dir = tempDir("suites finer"); const ok = (...args: string[]) => okIn(dir, ...args); const scratch = (ns: string, text: string) => fs.writeFileSync(path.join(dir, "scratch.ts"), `// tcm: namespace ${ns}\n${text}`); ok("init"); scratch( "greeter", `export const SUFFIX = ""; export const BANNER = "== greeter =="; export const banner = () => BANNER; export class Greeter { hello(name: string) { return \`hello, \${name}\${SUFFIX}\`; } shout(s: string) { return s.toUpperCase(); } } export const main = (...args: string[]) => console.log(args[0] === "--banner" ? banner() : new Greeter().hello(args[0] ?? "world")); export const manifest = { name: "greeter", bin: { greet: "main" }, suites: { greet: ["e2e"] } }; `, ); ok("add"); scratch( "greeter.e2e", `import assert from "node:assert/strict"; import { spawnSync } from "node:child_process"; export const testGreets = () => { const r = spawnSync(process.execPath, [process.env.GREET_BIN!, "tcm"], { encoding: "utf8" }); assert.equal(r.stdout, "hello, tcm\\n"); }; `, ); ok("add"); assert.match(ok("test"), /suites: 1 passed, 0 failed\n/); const cached = /suites: 1 passed, 0 failed \(1 cached\)/; const ranAgain = /suites: 1 passed, 0 failed\n/; // a method of the class it didn't call scratch( "greeter", `export class Greeter { hello(name: string) { return \`hello, \${name}\${SUFFIX}\`; } shout(s: string) { return s.toUpperCase() + "!"; } } `, ); ok("update"); assert.match(ok("test"), cached, "shout didn't run"); // a constant loaded (banner's module imports it) but read by nothing that ran scratch("greeter", `export const BANNER = "~~ greeter ~~";\n`); ok("update"); assert.match(ok("test"), cached, "BANNER was only loaded"); // the method it called, the same output written another way scratch( "greeter", `export class Greeter { hello(name: string) { return "hello, " + name + SUFFIX; } shout(s: string) { return s.toUpperCase() + "!"; } } `, ); ok("update"); assert.match(ok("test"), ranAgain, "hello ran"); // a constant that method reads: run again, so it fails scratch("greeter", `export const SUFFIX = "!";\n`); ok("update"); const failed = tcmIn(dir, "test"); assert.match( failed.out, /✗ greeter\.e2e\.testGreets[\s\S]*suites: 0 passed, 1 failed\n/, "hello reads SUFFIX", ); }