testSuitesAgainstPackedBuild
Suites run against another build of the command (a package packed from the codebase); what tcm runs gets the codebase's commands. A result is the code the suite ran's, whichever build ran it: it holds against the codebase's own build and any package with that code, though the bin moves with any change its entry reaches; a build without the code (one packed before a change) runs the suite.
import { okIn, 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 testSuitesAgainstPackedBuild = () => { const dir = tempDir("suites"); 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 greet = (name: string) => \`hello, \${name}\`; export const shout = (s: string) => s.toUpperCase(); export const main = (...args: string[]) => console.log(args[0] === "--shout" ? shout(greet("world")) : greet(args[0] ?? "world")); export const hasCommand = () => (process.env.GREET_BIN ? "yes" : "no"); 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"); // what tcm runs can run the codebase's commands assert.equal(ok("run", "greeter.hasCommand").trim(), "yes"); ok("pack", "greeter", "--out", "pkg"); const against = ["test", "--bin", "greet=pkg/bin/greet.js"]; assert.match(ok(...against), /✓ greeter\.e2e\.testGreets[\s\S]*suites: 1 passed, 0 failed\n/); assert.match(ok(...against), /suites: 1 passed, 0 failed \(1 cached\)/); // the codebase's own build runs the same code: the result holds assert.match(ok("test"), /suites: 1 passed, 0 failed \(1 cached\)/); // what the suite didn't run changed: main's hash moves, and the bin with it, but the result holds scratch("greeter", `export const shout = (s: string) => \`\${s.toUpperCase()}!\`;\n`); ok("update"); ok("pack", "greeter", "--out", "pkg"); assert.match(ok(...against), /suites: 1 passed, 0 failed \(1 cached\)/); // code it ran changed: packed again, it runs, and the codebase's own build has that result fs.cpSync(path.join(dir, "pkg"), path.join(dir, "before"), { recursive: true }); scratch("greeter", `export const greet = (name: string) => \`hello, \${name}\`.trim();\n`); ok("update"); ok("pack", "greeter", "--out", "pkg"); assert.match(ok(...against), /suites: 1 passed, 0 failed\n/); assert.match(ok("test"), /suites: 1 passed, 0 failed \(1 cached\)/); // the package from before the change hasn't that code: against it, the suite runs assert.match(ok("test", "--bin", "greet=before/bin/greet.js"), /suites: 1 passed, 0 failed\n/); }