testSuitesAgainstPackedBuild

tcmts.cli.test.e2e.suites.testSuitesAgainstPackedBuild · #wokc7nkn · term

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

uses