import { mkdtemp, mkdir, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { describe, expect, it } from "vitest"; import { failureCount, renderReport, runBaselineInventory } from "./verify-theme-error-state-baseline.mjs"; describe("Theme Error State baseline runner failure counting", () => { it("counts TypeScript diagnostics from error TS markers", () => { expect(failureCount("typecheck", "app/a.ts(1,1): error TS2322: nope\napp/b.ts(2,2): error TS7006: nope", "", 2)).toBe(2); }); it("counts ESLint errors from the summary problem line", () => { expect(failureCount("lint", "✖ 5 problems (3 errors, 2 warnings)", "", 1)).toBe(3); }); it("counts Vitest failed tests from the health/readiness summary", () => { expect(failureCount("vitest-health-readiness", "Tests 4 failed | 8 passed", "", 1)).toBe(4); }); it("counts CI baseline FAIL lines conservatively", () => { expect(failureCount("ci-baseline", "FAIL package.json: missing script\nFAIL .eslintrc: missing rule", "", 1)).toBe(2); }); it("returns zero for clean exits and read-only inventory gates", () => { expect(failureCount("typecheck", "", "", 0)).toBe(0); expect(failureCount("theme-error-inventory", "theme: 1", "", 1)).toBe(0); }); }); describe("Theme Error State theme/error inventory", () => { it("scans required existing roots and records missing roots without failing", async () => { const root = await mkdtemp(join(tmpdir(), "themeErrorState-baseline-inventory-")); await mkdir(join(root, "apps", "web", "app", "routes"), { recursive: true }); await mkdir(join(root, "apps", "web", "app", "components"), { recursive: true }); await mkdir(join(root, "apps", "web", "public"), { recursive: true }); await mkdir(join(root, "docs"), { recursive: true }); await writeFile( join(root, "apps", "web", "app", "routes", "sample.tsx"), [ "export const meta = () => [{ name: 'theme-color', content: '#000' }];", "throw new Response('not found', { status: 404 });", "throw new Response('feature disabled', { status: 403 });", "const required = 'plan-required';", ].join("\n"), "utf8" ); await writeFile(join(root, "apps", "web", "app", "components", "ThemeToggle.tsx"), "const mode = 'dark-mode';\n", "utf8"); await writeFile(join(root, "apps", "web", "public", "favicon-32x32.png"), "png", "utf8"); await writeFile(join(root, "docs", "ignored.tsx"), "serviceWorker theme-color 500 maintenance\n", "utf8"); const inventory = await runBaselineInventory(root); const allMatches = inventory.matches.join("\n"); expect(inventory.roots).toEqual(["apps/web/app/routes", "apps/web/app/components", "apps/web/public"]); expect(inventory.missingRoots).toEqual(["apps/web/app/root.tsx", "apps/web/app/application", "apps/web/vite.config.ts"]); expect(inventory.counts).toMatchObject({ theme: 1, "dark-mode": 1, "error-404": 2, "error-403": 1, "plan-required": 1, "feature-disabled": 1, }); expect(allMatches).toContain("apps/web/app/routes/sample.tsx"); expect(allMatches).toContain("apps/web/app/components/ThemeToggle.tsx"); expect(allMatches).not.toContain("docs/ignored.tsx"); }); }); describe("Theme Error State baseline report rendering", () => { it("renders gate identifiers, exit codes, failure counts, and fingerprints", () => { const report = renderReport([ { id: "typecheck", command: "pnpm run typecheck", exitCode: 2, durationMs: 1500, failureCount: 7, fingerprint: { hash: "abc123def456", excerpt: "error TS2322" } }, { id: "theme-error-inventory", command: "read-only theme/error surface inventory", exitCode: 0, durationMs: 42, failureCount: 0, fingerprint: { hash: "fed456abc123", excerpt: "theme: 1" } }, ]); expect(report).toContain("# Theme Error State Baseline Health"); expect(report).toContain("## typecheck"); expect(report).toContain("## theme-error-inventory"); expect(report).toContain("- Exitcode: 2"); expect(report).toContain("- Exitcode: 0"); expect(report).toContain("- Failure Count: 7"); expect(report).toContain("- Failure Count: 0"); expect(report).toContain("- Output Fingerprint: abc123def456"); expect(report).toContain("- Output Fingerprint: fed456abc123"); }); });