import { readFileSync } from "node:fs"; import { join } from "node:path"; import { describe, expect, it } from "vitest"; const source = readFileSync( join(import.meta.dirname, "../src/tailwind.css"), "utf8", ); function block(selector: string): string { const at = source.indexOf(`\n${selector} {`); if (at === -1) return ""; const open = source.indexOf("{", at); const close = source.indexOf("\n}", open); return source.slice(open, close); } describe("theme aliases", () => { const OBSIDIAN_VARS = [ "--background-primary", "--background-secondary", "--background-modifier-border", "--text-normal", "--text-muted", "--color-accent", "--text-on-accent", "--text-error", ]; it("are declared on .bcal-root, not :root", () => { const root = block(".bcal-root"); expect(root).not.toBe(""); for (const name of OBSIDIAN_VARS) { expect(root, `${name} must be aliased on .bcal-root`).toContain(name); } }); it("never reference Obsidian variables from :root", () => { const rootBlocks = [...source.matchAll(/(^|\n):root\s*\{([^}]*)\}/g)]; for (const [, , body] of rootBlocks) { for (const name of OBSIDIAN_VARS) { expect(body, `:root must not reference ${name}`).not.toContain(name); } } }); it("scopes the dark override under the view root", () => { expect(source).toContain(".theme-dark .bcal-root"); expect(source).not.toMatch(/\n\.theme-dark\s*\{/); }); }); describe("reset specificity", () => { it("does not use :where() for element resets", () => { expect(source).not.toMatch(/\.bcal-root\s+:where\(/); }); it("uses a doubled class to outrank app and theme styles", () => { expect(source).toContain(".bcal-root.bcal-root"); }); it("neutralises the native search affordance", () => { expect(source).toContain("-webkit-search-cancel-button"); }); }); describe("cascade against Obsidian", () => { it("marks utilities important so they outrank app.css", () => { expect(source).toMatch( /@import "tailwindcss\/utilities\.css"[^;]*\bimportant\b/, ); }); it("keeps the element reset out of a cascade layer", () => { const reset = source.indexOf(".bcal-root.bcal-root :is(button"); expect(reset).toBeGreaterThan(-1); const before = source.slice(0, reset); const opens = (before.match(/@layer[^;{]*\{/g) ?? []).length; const closes = (before.match(/\n\}/g) ?? []).length; expect(opens, "reset must be unlayered").toBeLessThanOrEqual(closes); }); }); describe("preflight stays out", () => { it("imports only the theme and utility layers", () => { expect(source).toContain('@import "tailwindcss/theme.css"'); expect(source).toContain('@import "tailwindcss/utilities.css"'); expect(source).not.toMatch(/@import "tailwindcss"\s*[;l]/); expect(source).not.toMatch(/@import\s+"tailwindcss\/preflight/); }); });