import assert from "node:assert/strict"; import { readdirSync, readFileSync } from "node:fs"; import { extname, join } from "node:path"; import test from "node:test"; import { fileURLToPath } from "node:url"; const layout = readFileSync(new URL("../src/app/layout.tsx", import.meta.url), "utf8"); const siteStyles = readFileSync(new URL("../src/app/site-styles.ts", import.meta.url), "utf8"); const adminLayout = readFileSync(new URL("../src/app/admin/layout.tsx", import.meta.url), "utf8"); const adminCss = readFileSync(new URL("../src/app/admin/admin.css", import.meta.url), "utf8"); const homePage = readFileSync(new URL("../src/app/page.tsx", import.meta.url), "utf8"); const loginPage = readFileSync(new URL("../src/app/login/page.tsx", import.meta.url), "utf8"); test("Inter is loaded through next/font and applied as a CSS variable", () => { assert.match(layout, /import localFont from "next\/font\/local"/); assert.doesNotMatch(layout, /from ["']next\/font\/google["']/); assert.match(layout, /src: "\.\/fonts\/InterVariable-latin\.woff2"/); assert.match(layout, /display: "swap"/); assert.match(layout, /variable: "--font-inter"/); assert.match(layout, /className=\{inter\.variable\}/); assert.match(readFileSync(new URL("../src/app/globals.css", import.meta.url), "utf8"), /var\(--font-inter, Inter\)/); assert.match( readFileSync(new URL("../src/components/admin/admin-app.tsx", import.meta.url), "utf8"), /var\(--font-inter, Inter\)/, ); }); test("Inter is vendored locally so production builds do not fetch Google Fonts", () => { const font = readFileSync(new URL("../src/app/fonts/InterVariable-latin.woff2", import.meta.url)); assert.equal(Buffer.from(font.subarray(0, 4)).toString(), "wOF2"); assert.ok(font.byteLength > 20_000); const srcRoot = fileURLToPath(new URL("../src/", import.meta.url)); const stack = [srcRoot]; while (stack.length > 0) { const dir = stack.pop()!; for (const entry of readdirSync(dir, { withFileTypes: true })) { const fullPath = join(dir, entry.name); if (entry.isDirectory()) { stack.push(fullPath); continue; } if (![".ts", ".tsx", ".js", ".jsx", ".css"].includes(extname(entry.name))) continue; const source = readFileSync(fullPath, "utf8"); assert.doesNotMatch( source, /from ["']next\/font\/google["']|fonts\.googleapis\.com/, `${fullPath} must not fetch Google Fonts at build time`, ); } } }); test("site chrome owns globals.css; admin does not import it", () => { assert.match(siteStyles, /import "\.\/globals\.css"/); assert.match(siteStyles, /import "\.\/birth-time-choice\.css"/); assert.doesNotMatch(layout, /globals\.css|birth-time-choice\.css|site-styles/); assert.match(homePage, /import "@\/app\/site-styles"/); assert.match(loginPage, /import "\.\.\/site-styles"/); assert.doesNotMatch(adminLayout, /globals\.css|site-styles/); assert.doesNotMatch( readFileSync(new URL("../src/app/error.tsx", import.meta.url), "utf8"), /site-styles|globals\.css/, ); assert.doesNotMatch( readFileSync(new URL("../src/app/not-found.tsx", import.meta.url), "utf8"), /site-styles|globals\.css/, ); assert.match(adminCss, /--font-body: StyreneB, var\(--font-inter, Inter\)/); }); test("root error and not-found pages do not depend on Tailwind utilities or Button", () => { const errorPage = readFileSync(new URL("../src/app/error.tsx", import.meta.url), "utf8"); const notFoundPage = readFileSync(new URL("../src/app/not-found.tsx", import.meta.url), "utf8"); for (const source of [errorPage, notFoundPage]) { assert.doesNotMatch(source, /className="flex/); assert.doesNotMatch(source, /min-h-svh/); assert.doesNotMatch(source, /text-muted-foreground/); assert.doesNotMatch(source, /@\/components\/ui\/button/); } });