runTestsWithVitest
uses node:child_process
Run test definitions with Vitest: in Node, or in a browser for tests that need one.
import type { Codebase } from "#codebase/tcmts/cli/codebase"; import { prepareTestRun } from "#codebase/tcmts/cli/vitest"; import type { DefSource, TestRun } from "#codebase/tcmts/loader"; import { spawnSync } from "node:child_process"; import fs from "node:fs"; export function runTestsWithVitest( cb: Codebase, tests: { hash: string; componentHash: string }[], src: DefSource, ): TestRun[] { if (!tests.length) return []; const { requestFile, results } = prepareTestRun(cb, tests, src); const r = spawnSync(process.execPath, [process.argv[1]!, "internal-vitest", requestFile], { cwd: cb.lay.root, encoding: "utf8", timeout: 10 * 60_000, env: { ...process.env, NO_COLOR: "1" }, // (fd 3: where it says it's waiting for a slot, `vitestChild`: this one's stderr, not stdout, which an MCP server // running this speaks on) stdio: ["ignore", "pipe", "pipe", 2], }); // TCM_KEEP_TEST_RUN=1 leaves the request in .tcm/test, to run the child by hand (`tcm internal-vitest <it>`) if (!process.env.TCM_KEEP_TEST_RUN) fs.rmSync(requestFile, { force: true }); let done: TestRun[] = []; try { done = JSON.parse(fs.readFileSync(results, "utf8")) as TestRun[]; } catch { // no results: the runner itself failed } fs.rmSync(results, { force: true }); const why = (r.stderr || r.stdout || "").trim().split("\n").slice(-8).join("\n"); return tests.map( (t) => done.find((d) => d.hash === t.hash) ?? { hash: t.hash, ok: false, message: `no result: the test runner failed${why ? `\n${why}` : ""}`, output: "", ms: 0, infrastructure: true, }, ); }
uses
- tcmts.cli.codebase.Codebase
- tcmts.cli.vitest.prepareTestRun
- tcmts.loader.DefSource
- tcmts.loader.TestRun