import { afterEach, describe, expect, test } from "bun:test"; import { mkdir, rm, writeFile } from "node:fs/promises"; import { join } from "node:path"; import { tmpdir } from "node:os"; import { explainBuildDecision } from "../src/explain.ts"; const roots: string[] = []; afterEach(async () => Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true }))), ); async function fixture(): Promise { const root = join(tmpdir(), `wrnexus-explain-${crypto.randomUUID()}`); roots.push(root); await mkdir(join(root, "dist"), { recursive: true }); await writeFile( join(root, "dist", "build-report.json"), JSON.stringify({ frameworkVersion: "0.8.0", adapter: "edge", measurements: { routeJsBytes: 12 }, budgetViolations: [], assets: [{ file: "server.js", bytes: 12 }], routes: [ { kind: "page", path: "/users/[id]", source: "app/pages/users/[id].wrn", execution: "authenticated-ssr", canPrerender: false, needsClientRuntime: true, needsServerRuntime: true, hydrationStrategy: "visible", reasons: ["client interactivity", "authentication required"], cachePolicy: { strategy: "stale-while-revalidate", ttl: "30s" }, requiredPermission: "users.read", }, ], }), ); return root; } describe("causal build explanations", () => { test("explains route execution and hydration from persisted compiler evidence", async () => { const root = await fixture(); const route = explainBuildDecision(root, "route", "/users/[id]"); expect(route.summary).toContain("authenticated-ssr"); expect(route.reasons).toContain("authentication required"); expect(explainBuildDecision(root, "hydration", "users/[id]").summary).toContain("visible"); }); test("explains build and bundle measurements", async () => { const root = await fixture(); expect(explainBuildDecision(root, "build").reasons).toContain( "all configured performance budgets pass", ); expect(explainBuildDecision(root, "bundle").reasons[0]).toBe("server.js: 12 bytes"); }); test("explains cache and permission decisions", async () => { const root = await fixture(); expect(explainBuildDecision(root, "cache", "/users/[id]").summary).toContain( "stale-while-revalidate", ); expect(explainBuildDecision(root, "permission", "users.read").reasons[0]).toContain( "security.permission", ); }); test("uses stable diagnostics for missing evidence", () => { expect(() => explainBuildDecision("missing", "build")).toThrow("WRN-EXPLAIN-NO-BUILD"); }); });