import assert from "node:assert/strict"; import { readFileSync, readdirSync } from "node:fs"; import test from "node:test"; // Guards the defect class behind BUG-434 / BUG-435: a className the CSS never // defines renders as an unstyled element and silently breaks the layout, with // nothing in the build or the type checker to catch it. // // Scope: only the project's own class families. A token counts as ours when its // first segment already names a family in our CSS (`paywall-`, `message-`, // `dialog-`, `danger-`, ...), which keeps Tailwind utilities out without having // to enumerate them. const projectRoot = new URL("../", import.meta.url); const sourceRoot = new URL("src/", projectRoot); const walk = (dir: URL, ext: readonly string[]): string[] => readdirSync(dir, { recursive: true, encoding: "utf8" }) .filter((entry) => ext.some((suffix) => entry.endsWith(suffix))) .map((entry) => `src/${entry.split("\\").join("/")}`); const read = (path: string) => readFileSync(new URL(path, projectRoot), "utf8"); const styleSheets = walk(sourceRoot, [".css"]).map(read); const componentFiles = walk(sourceRoot, [".tsx", ".ts"]); // Boundary pages under the root layout carry their rules in an inline