css.test.ts
1.2 kB · typescript · 40 lines
1import { test } from "bun:test";2import { readdirSync, readFileSync } from "node:fs";3import { join } from "node:path";45/* SELECTORS */67const selectors = (css: string) => {8 const out: string[] = [];9 let depth = 0;10 let buf = "";11 for (const c of css.replace(/\/\*[\s\S]*?\*\//g, "")) {12 if (c === "{") {13 if (depth === 0) out.push(buf.trim().replace(/\s+/g, " "));14 depth++;15 buf = "";16 } else if (c === "}") {17 depth--;18 if (depth < 0) throw new Error("stray brace");19 buf = "";20 } else if (depth === 0) buf += c;21 }22 if (depth !== 0) throw new Error("unclosed brace");23 return out;24};2526/* CSS */2728test("the site css never repeats a top-level selector with another rule between", () => {29 const home = import.meta.dir;30 for (const name of readdirSync(home).filter((one) => one.endsWith(".css")).sort()) {31 const file = join(home, name);32 const list = selectors(readFileSync(file, "utf8"));33 const last = new Map<string, number>();34 list.forEach((sel, n) => {35 const was = last.get(sel);36 if (was !== undefined && list.slice(was + 1, n).some((other) => other !== sel)) throw new Error(`${file}: '${sel}' at ${was} and ${n}`);37 last.set(sel, n);38 });39 }40});