74 lines
2.6 KiB
JavaScript
74 lines
2.6 KiB
JavaScript
const { test } = require("node:test");
|
|
const assert = require("node:assert");
|
|
const { compileTheme, emitOverlayCss, robustnessGuard, contentHash, deriveRgb } = require("../lib/compile");
|
|
const { normalizeTokens } = require("../lib/themeSchema");
|
|
|
|
|
|
function bracesBalanced(css) {
|
|
let depth = 0;
|
|
for (const ch of css) {
|
|
if (ch === "{") depth += 1;
|
|
else if (ch === "}") { depth -= 1; if (depth < 0) return false; }
|
|
}
|
|
return depth === 0;
|
|
}
|
|
|
|
|
|
test("compileTheme emits --bs-* overlay with derived rgb companion", () => {
|
|
const out = compileTheme(normalizeTokens({ colors: { primary: "#ff0000" } }));
|
|
assert.match(out.css, /--bs-primary: #ff0000;/);
|
|
assert.match(out.css, /--bs-primary-rgb: 255, 0, 0;/);
|
|
assert.equal(out.engine, "overlay");
|
|
assert.ok(bracesBalanced(out.css));
|
|
});
|
|
|
|
|
|
test("compileTheme NEVER throws and is balanced even for a brace-injecting token", () => {
|
|
// A value containing "}" would close :root{} early -> it must be DROPPED.
|
|
const out = compileTheme(normalizeTokens({ colors: { primary: "#fff} body{display:none" } }));
|
|
assert.ok(bracesBalanced(out.css), "braces stay balanced");
|
|
assert.doesNotMatch(out.css, /display:none/);
|
|
assert.ok(out.warnings.length >= 1);
|
|
});
|
|
|
|
|
|
test("targeted rule tokens emit their own block", () => {
|
|
const out = emitOverlayCss(normalizeTokens({ components: { navbarBg: "#101010" } }));
|
|
assert.match(out.css, /\.navbar\{--bs-navbar-bg: #101010;\}/);
|
|
assert.ok(bracesBalanced(out.css));
|
|
});
|
|
|
|
|
|
test("empty/default theme compiles to valid non-white-screen CSS", () => {
|
|
const out = compileTheme(normalizeTokens({}));
|
|
assert.ok(bracesBalanced(out.css));
|
|
assert.match(out.css, /:root\{/);
|
|
});
|
|
|
|
|
|
test("custom raw vars pass through, malformed keys are skipped", () => {
|
|
const out = emitOverlayCss(normalizeTokens({ custom: { "--my-var": "10px", "bad key": "x" } }));
|
|
assert.match(out.css, /--my-var: 10px;/);
|
|
assert.doesNotMatch(out.css, /bad key/);
|
|
});
|
|
|
|
|
|
test("deriveRgb handles #rgb, #rrggbb, and rejects non-hex", () => {
|
|
assert.equal(deriveRgb("#fff"), "255, 255, 255");
|
|
assert.equal(deriveRgb("#0d6efd"), "13, 110, 253");
|
|
assert.equal(deriveRgb("rebeccapurple"), null);
|
|
});
|
|
|
|
|
|
test("robustnessGuard collapses unbalanced CSS to an empty sentinel", () => {
|
|
const g = robustnessGuard(":root{--x: 1;", []);
|
|
assert.match(g.css, /empty \(invalid\)/);
|
|
});
|
|
|
|
|
|
test("contentHash is stable and 8 hex chars", () => {
|
|
const a = contentHash(":root{--bs-primary: #000;}");
|
|
const b = contentHash(":root{--bs-primary: #000;}");
|
|
assert.equal(a, b);
|
|
assert.match(a, /^[0-9a-f]{8}$/);
|
|
});
|