setUp
uses node:child_process
A new codebase with greet (a function with a doc, an interface, a main using a package) and ui (a component).
import { plainEnv, strip, tcmBin, tempDir } from "#codebase/tcmts/cli/test/e2e/harness"; import { spawnSync } from "node:child_process"; import fs from "node:fs"; import path from "node:path"; export function setUp() { const dir = tempDir("pack"); const env = plainEnv(); const spawn = (cmd: string, args: string[], cwd = dir) => { const r = spawnSync(cmd, args, { cwd, encoding: "utf8", env }); return { status: r.status, out: strip(r.stdout + r.stderr) }; }; const tcm = (...args: string[]) => { const r = spawn(process.execPath, [tcmBin(), ...args]); if (r.status !== 0) throw new Error(`tcm ${args.join(" ")} exited ${r.status}:\n${r.out}`); return r.out; }; const write = (file: string, text: string) => fs.writeFileSync(path.join(dir, file), text); const read = (file: string) => fs.readFileSync(path.join(dir, file), "utf8"); tcm("init"); fs.rmSync(path.join(dir, "scratch.ts")); write( "greet.ts", `// tcm: namespace greet import escape from "escape-string-regexp"; export interface Greeting { to: string; text: string; } /** A greeting, and a pattern that finds it. */ export function greet(to: string): Greeting { return { to, text: \`hello, \${to}\` }; } export const finder = (g: Greeting): RegExp => new RegExp(escape(g.text)); export function main(...names: string[]): number { for (const n of names) console.log(greet(n).text, finder(greet(n)).source); return names.length ? 0 : 2; } `, ); write("ui.tsx", `// tcm: namespace ui\nexport function Badge({ label }: { label: string }) {\n return <b>{label}</b>;\n}\n`); tcm("add", "greet.ts"); tcm("add", "ui.tsx"); write("README.md", "# greeter\n"); return { dir, spawn, tcm, write, read }; }
uses
- tcmts.cli.test.e2e.harness.plainEnv
- tcmts.cli.test.e2e.harness.strip
- tcmts.cli.test.e2e.harness.tcmBin
- tcmts.cli.test.e2e.harness.tempDir