Ctrl K
ComunidadGuías…

tests/themeTokens.test.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
// The custom theme builder's token list (shared/customTheme.ts) against the
// two things it has to agree with: the surface layer in tokens.css, and the
// dictionary. A token the builder offers without a `:root, [data-theme]`
// derivation would read as "#000000 inherited" in every row; a token without
// a label in both languages would print its raw name to an Arabic reader —
// the half-translation check-i18n exists to catch, one level up.
// Both dictionaries, installed: under Node there is no chunk to fetch
// (client/i18n.ts loads one language at a time in a page).
import "../client/i18n/both.ts";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { describe, it } from "node:test";
import { fileURLToPath } from "node:url";
import { SURFACE_PAIRS } from "../shared/contrast.ts";
import { SURFACE_TOKENS, THEME_TOKENS, TOKEN_GROUPS, tokenSpec } from "../shared/customTheme.ts";
import { setLang, t } from "../client/i18n.ts";

const css = readFileSync(fileURLToPath(new URL("../client/styles/tokens.css", import.meta.url)), "utf8");
const surfaceBlock = /:root,\s*\[data-theme\]\s*\{([^}]*)\}/.exec(css);

describe("the theme builder's tokens", () => {
  it("names every token once, in exactly one group the builder lays out", () => {
    const names = THEME_TOKENS.map((spec) => spec.name);
    assert.equal(new Set(names).size, names.length);
    for (const spec of THEME_TOKENS) {
      assert.ok(TOKEN_GROUPS.includes(spec.group), `${spec.name} sits in unknown group ${spec.group}`);
      assert.equal(tokenSpec(spec.name), spec);
    }
    assert.ok(THEME_TOKENS.length >= 110, "the widest customisation the owner asked for is at least the surfaces");
  });

  it("gives every surface token a derivation in tokens.css, spelled as the spec says", () => {
    assert.ok(surfaceBlock, "tokens.css carries the `:root, [data-theme]` surface layer");
    const block = surfaceBlock![1];
    for (const spec of SURFACE_TOKENS) {
      const m = new RegExp(`${spec.name.replace(/[-]/g, "\\-")}\\s*:\\s*([^;]+);`).exec(block);
      assert.ok(m, `${spec.name} has no default in the surface layer`);
      assert.equal(m![1].trim(), spec.derivedFrom, `${spec.name} derives from what the spec says`);
    }
    // And nothing in the layer that the builder does not offer: a token the
    // CSS reads but nobody can set is a setting that does not exist.
    for (const m of block.matchAll(/(--[\w-]+)\s*:/g)) {
      assert.ok(tokenSpec(m[1]), `${m[1]} is in the surface layer but not in THEME_TOKENS`);
    }
  });

  it("labels every token in both languages, with real Arabic", () => {
    for (const spec of THEME_TOKENS) {
      setLang("en");
      const en = t(spec.label as never);
      setLang("ar");
      const ar = t(spec.label as never);
      assert.notEqual(en, spec.label, `${spec.name} has no English label`);
      assert.ok(/[؀-ۿ]/.test(ar), `${spec.name}'s Arabic label carries no Arabic script: ${ar}`);
      assert.notEqual(en, ar, `${spec.name} has the same label in both languages`);
    }
    setLang("en");
  });

  it("measures only pairs the builder can set, and every surface ground it pairs is a plain colour", () => {
    for (const [token, against] of SURFACE_PAIRS) {
      assert.ok(tokenSpec(token), `${token} is measured but not offered`);
      assert.ok(tokenSpec(against), `${against} is measured but not offered`);
      assert.equal(tokenSpec(against)!.kind, "color", `${against} is a wash; a ratio against it is not a promise`);
    }
  });
});