testImportTestsCachedByHash

tcmts.cli.test.e2e.import.testImportTestsCachedByHash · #66me547w · term

--tests imports tests written as definitions; tcm test runs them, cached by hash

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 testImportTestsCachedByHash = () => {
  const dir = tempDir("import");
  const tcm = (...args: string[]) => okIn(dir, ...args);
  const project = tempDir("import tests");
  const put = (file: string, text: string) => {
    fs.mkdirSync(path.dirname(path.join(project, file)), { recursive: true });
    fs.writeFileSync(path.join(project, file), text);
  };
  put("package.json", JSON.stringify({ type: "module" }));
  put(
    "src/math.ts",
    `export const double = (x: number): number => x * 2;\nexport const half = (x: number): number => x / 2;\n`,
  );
  // a helper next to the tests is a plain definition; only `test…` names are tests
  put(
    "test/math.ts",
    `import assert from "node:assert/strict";\nimport { double, half } from "../src/math.ts";\nexport const sample = 21;\nexport const testDouble = () => assert.equal(double(sample), 42);\nexport const testHalf = () => assert.equal(half(42), sample);\n`,
  );
  // a framework's test file (top-level test() calls) stays skipped
  put("test/math.test.ts", `import { test } from "node:test";\ntest("x", () => {});\n`);
  tcm("init");
  tcm("import", project, "--into", "calc");
  // (what import names it says only with --verbose: what's in the codebase says it)
  const imported = tcm("ls", "calc");
  assert.match(imported, /calc\.math\.double/);
  assert.doesNotMatch(imported, /testDouble/, "without --tests, tests stay out");
  assert.match(
    tcm("import", project, "--into", "calc", "--tests", "--update", "--verbose"),
    /calc\.test\.math\.testDouble/,
  );
  assert.match(tcm("test", "calc"), /2 passed, 0 failed\n/);
  assert.match(tcm("test", "calc"), /2 passed, 0 failed \(2 cached\)/);
  // a change reaches the tests that use it, and only those
  put(
    "src/math.ts",
    `export const double = (x: number): number => x + x;\nexport const half = (x: number): number => x / 2;\n`,
  );
  tcm("import", project, "--into", "calc", "--tests", "--update");
  assert.match(tcm("test", "calc"), /2 passed, 0 failed \(1 cached\)/);
}

uses