import { describe, it } from "node:test"; import assert from "node:assert/strict"; import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { inlineBlobBytes, filePayload, whitespaceLiterals, subpixelArbitraries, customPropTokens, probeArtifacts, uncleanedListeners, tagHistogram, ariaHiddenFocusables, duplicateHelpers, svgPathDuplication, nearDuplicateComponents, componentNames, toLetter, scoreApp, type SrcFile, } from "../src/runner/qualityScore.js"; const srcFile = (rel: string, text: string): SrcFile => ({ path: rel, rel, ext: rel.slice(rel.lastIndexOf(".")), text, lines: text.split("\n").length, }); // --------------------------------------------------------------------------- // Metric extractors // --------------------------------------------------------------------------- describe("inlineBlobBytes", () => { it("counts base64 data-URI payload bytes", () => { const b64 = "A".repeat(500); const text = `const img = "data:image/png;base64,${b64}";`; assert.equal(inlineBlobBytes(text), 500); }); it("counts a long markup string handed in as a prop", () => { const html = "
" + "x".repeat(250) + "
"; const text = ``; assert.ok(inlineBlobBytes(text) > 1000, "flags HTML-as-string blob"); }); it("ignores ordinary short strings", () => { assert.equal(inlineBlobBytes(`const s = "hello world";`), 0); }); }); describe("filePayload", () => { it("reports a giant single line", () => { const giant = "x".repeat(200_000); const p = filePayload(srcFile("a.tsx", `const a = 1;\nconst b = "${giant}";\n`)); assert.ok(p.maxLine >= 200_000, "detects the giant line"); assert.ok(p.bytes >= 200_000, "counts the bytes"); }); it("a normal formatted file has a small max line", () => { const p = filePayload(srcFile("a.tsx", "const a = 1;\nconst b = 2;\nexport default a;\n")); assert.ok(p.maxLine < 40, "small max line"); }); }); describe("whitespaceLiterals", () => { it("counts {\" \"} capture-whitespace literals", () => { const text = `

Hi{" "}there{" "}world{' '}!

`; assert.equal(whitespaceLiterals(text), 3); }); it("does not flag meaningful expression literals", () => { assert.equal(whitespaceLiterals(`

{name}{count}

`), 0); }); }); describe("subpixelArbitraries", () => { it("flags non-integer px/rem arbitraries but not whole ones", () => { // 713.938px (frozen) + 12.5rem (=200px, whole) → only the first counts. const text = `
`; assert.equal(subpixelArbitraries(text), 1); }); }); describe("customPropTokens", () => { it("splits opaque --clr-N / hash tokens from named ones", () => { const css = `:root{ --clr-7:#fff; --c12:#000; --a1b2c3:#111; --brand-primary:#f00; --space-4:1rem; }`; const t = customPropTokens(css); assert.equal(t.total, 5); assert.equal(t.opaque, 3, "clr-7, c12, hash a1b2c3 are opaque; brand-primary/space-4 are named"); }); }); describe("probeArtifacts", () => { it("flags off-screen capture-probe scaffolding", () => { const text = `m`; assert.ok(probeArtifacts(text) >= 2); }); }); describe("uncleanedListeners", () => { it("counts addEventListener with no cleanup", () => { const text = `el.addEventListener("scroll", fn);\nwin.addEventListener("resize", fn);`; assert.equal(uncleanedListeners(text), 2); }); it("does not flag when a matching removeEventListener / teardown exists", () => { const text = `useEffect(() => { el.addEventListener("scroll", fn); return () => el.removeEventListener("scroll", fn); });`; assert.equal(uncleanedListeners(text), 0); }); }); describe("tagHistogram", () => { it("counts opening element tags by name", () => { const h = tagHistogram(`
x
`); assert.equal(h["div"], 2); assert.equal(h["span"], 1); assert.equal(h["button"], 1); }); }); describe("ariaHiddenFocusables", () => { it("flags aria-hidden on a focusable element", () => { const text = `y`; assert.equal(ariaHiddenFocusables(text), 2); }); it("ignores aria-hidden on a decorative div", () => { assert.equal(ariaHiddenFocusables(`