mirror of
https://github.com/Ku6epXBOCTuK/easy-png-tools.git
synced 2026-11-13 17:08:20 +00:00
chore: update lint rules
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
||||
isDerived,
|
||||
} from "../token-audit/helpers.mjs";
|
||||
import { checkParity } from "../token-audit/parity.mjs";
|
||||
import { checkUnresolvedRefs } from "../token-audit/refs.mjs";
|
||||
import { checkUnused } from "../token-audit/unused.mjs";
|
||||
|
||||
function themes(css) {
|
||||
@@ -134,6 +135,75 @@ describe("checkUnused", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("checkUnresolvedRefs", () => {
|
||||
it("accepts references to tokens defined in the same file", () => {
|
||||
const { root } = themes(
|
||||
":root { --color-text: #111; .x { color: var(--color-text); } }",
|
||||
);
|
||||
|
||||
expect(checkUnresolvedRefs(root)).toEqual([]);
|
||||
});
|
||||
|
||||
it("accepts references defined in the other theme block", () => {
|
||||
const { root } = themes(
|
||||
[
|
||||
":root { --color-text: #111; }",
|
||||
'[data-theme="dark"] { --color-text: #eee; }',
|
||||
".x { color: var(--color-text); }",
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
expect(checkUnresolvedRefs(root)).toEqual([]);
|
||||
});
|
||||
|
||||
it("reports a typo in a token name with its location", () => {
|
||||
const { root } = themes(
|
||||
":root { --color-text: #111; .x { border-color: var(--color-bordr); } }",
|
||||
);
|
||||
|
||||
expect(checkUnresolvedRefs(root)).toEqual([
|
||||
" --color-bordr used in .x (border-color) is not defined in app.css",
|
||||
]);
|
||||
});
|
||||
|
||||
it("exempts a reference that provides a fallback value", () => {
|
||||
const { root } = themes(".x { color: var(--color-missing, #fff); }");
|
||||
|
||||
expect(checkUnresolvedRefs(root)).toEqual([]);
|
||||
});
|
||||
|
||||
it("reports an undefined reference without a fallback even once", () => {
|
||||
const { root } = themes(
|
||||
[
|
||||
":root { --a: 1px; --b: 1px; }",
|
||||
".x { border-color: var(--ghost); outline-color: var(--ghost); }",
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
expect(checkUnresolvedRefs(root)).toEqual([
|
||||
" --ghost used in .x (border-color) is not defined in app.css",
|
||||
]);
|
||||
});
|
||||
|
||||
it("checks references inside token definitions themselves", () => {
|
||||
const { root } = themes(
|
||||
":root { --color-text: hct(from var(--brand-typo) h c t); }",
|
||||
);
|
||||
|
||||
expect(checkUnresolvedRefs(root)).toEqual([
|
||||
" --brand-typo used in :root (--color-text) is not defined in app.css",
|
||||
]);
|
||||
});
|
||||
|
||||
it("ignores non-custom properties that use var()", () => {
|
||||
const { root } = themes(
|
||||
".x { --local: 1px; width: calc(var(--local) * 2); }",
|
||||
);
|
||||
|
||||
expect(checkUnresolvedRefs(root)).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("token predicates", () => {
|
||||
it("detects color values in every supported notation", () => {
|
||||
for (const value of [
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { FILE, parsePreview } from "./token-audit/helpers.mjs";
|
||||
import { checkParity } from "./token-audit/parity.mjs";
|
||||
import { checkColorAuthorship } from "./token-audit/colors.mjs";
|
||||
import { checkUnresolvedRefs } from "./token-audit/refs.mjs";
|
||||
import { checkUnused } from "./token-audit/unused.mjs";
|
||||
|
||||
async function main() {
|
||||
@@ -34,6 +35,16 @@ async function main() {
|
||||
console.log("All colors are authored as hct().");
|
||||
}
|
||||
|
||||
const unresolved = checkUnresolvedRefs(root);
|
||||
if (unresolved.length > 0) {
|
||||
console.log(
|
||||
`Unresolved var() references in ${FILE}:\n${unresolved.join("\n")}`,
|
||||
);
|
||||
failed = true;
|
||||
} else {
|
||||
console.log("All var() references in app.css resolve.");
|
||||
}
|
||||
|
||||
const unused = checkUnused(root);
|
||||
if (unused.length > 0) {
|
||||
console.log("\nUnused tokens (defined in app.css, never used):");
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Unresolved references: every var(--x) in app.css must point at a token the
|
||||
// same file defines. A typo here silently drops the declaration, so unlike the
|
||||
// unused-token dust it is a defect, not a style choice.
|
||||
//
|
||||
// `var(--x, fallback)` is legal without --x (CSS custom property fallback), so
|
||||
// those references are exempt.
|
||||
|
||||
const VAR_REF_RE = /var\(\s*(--[\w-]+)\s*([,)])/g;
|
||||
|
||||
export function checkUnresolvedRefs(root) {
|
||||
const defined = new Set();
|
||||
root.walkDecls((decl) => {
|
||||
if (decl.prop.startsWith("--")) defined.add(decl.prop);
|
||||
});
|
||||
|
||||
const errors = [];
|
||||
const seen = new Set();
|
||||
root.walkDecls((decl) => {
|
||||
for (const match of decl.value.matchAll(VAR_REF_RE)) {
|
||||
const [, token, terminator] = match;
|
||||
// terminator ")" after whitespace means no fallback argument
|
||||
if (defined.has(token)) continue;
|
||||
if (terminator === ",") continue;
|
||||
if (seen.has(token)) continue;
|
||||
seen.add(token);
|
||||
const where = decl.parent?.selector || decl.parent?.name || "";
|
||||
errors.push(
|
||||
` ${token} used in ${where} (${decl.prop}) is not defined in app.css`,
|
||||
);
|
||||
}
|
||||
});
|
||||
return errors;
|
||||
}
|
||||
Reference in New Issue
Block a user