mirror of
https://github.com/def-peter/obsidian-aera-theme.git
synced 2026-07-22 05:00:27 +00:00
fix: harden contrast test tooling
This commit is contained in:
parent
7f3c846955
commit
95c5289f0e
4 changed files with 61 additions and 5 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { pathToFileURL } from "node:url";
|
||||
import { realpathSync } from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const HEX_COLOR = /^#[0-9a-f]{6}$/i;
|
||||
|
||||
|
|
@ -58,6 +59,10 @@ export function runContrastCli(
|
|||
if (failed) process.exitCode = 1;
|
||||
}
|
||||
|
||||
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
||||
const isDirectRun =
|
||||
process.argv[1] !== undefined &&
|
||||
realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1]);
|
||||
|
||||
if (isDirectRun) {
|
||||
runContrastCli();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import assert from "node:assert/strict";
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { mkdtempSync, rmSync, symlinkSync } from "node:fs";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import test from "node:test";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
|
|
@ -116,6 +119,14 @@ test("six core foreground/background pairs meet WCAG AA contrast", () => {
|
|||
}
|
||||
});
|
||||
|
||||
test("core contrast ratios match the WCAG calculations", () => {
|
||||
const expectedRatios = ["12.72", "4.53", "5.23", "13.32", "6.57", "7.38"];
|
||||
|
||||
for (const [index, [, foreground, background]] of CORE_CONTRAST_PAIRS.entries()) {
|
||||
assert.equal(contrastRatio(foreground, background).toFixed(2), expectedRatios[index]);
|
||||
}
|
||||
});
|
||||
|
||||
test("contrast calculation matches WCAG reference endpoints", () => {
|
||||
assert.equal(contrastRatio("#000000", "#ffffff"), 21);
|
||||
assert.equal(contrastRatio("#68756d", "#68756d"), 1);
|
||||
|
|
@ -136,6 +147,28 @@ test("contrast CLI prints all six pairs", () => {
|
|||
}
|
||||
});
|
||||
|
||||
test("contrast CLI runs when invoked through a symbolic link", (t) => {
|
||||
const directory = mkdtempSync(join(tmpdir(), "aera-contrast-cli-"));
|
||||
const symlinkPath = join(directory, "contrast.mjs");
|
||||
const cliPath = fileURLToPath(new URL("../scripts/contrast.mjs", import.meta.url));
|
||||
t.after(() => rmSync(directory, { recursive: true, force: true }));
|
||||
|
||||
try {
|
||||
symlinkSync(cliPath, symlinkPath);
|
||||
} catch (error) {
|
||||
if (["EACCES", "EPERM"].includes(error.code)) {
|
||||
t.skip("creating symbolic links is not permitted in this environment");
|
||||
return;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
const result = spawnSync(process.execPath, [symlinkPath], { encoding: "utf8" });
|
||||
|
||||
assert.equal(result.status, 0, result.stderr);
|
||||
assert.match(result.stdout, /PASS light text:/);
|
||||
});
|
||||
|
||||
test("contrast CLI marks a failing pair and requests exit code 1", () => {
|
||||
const originalExitCode = process.exitCode;
|
||||
const output = [];
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ export function declarationsFor(css, selector) {
|
|||
root.walkRules((rule) => {
|
||||
if (rule.selector !== selector) return;
|
||||
|
||||
rule.walkDecls((declaration) => {
|
||||
declarations.set(declaration.prop, declaration.value);
|
||||
});
|
||||
for (const node of rule.nodes ?? []) {
|
||||
if (node.type === "decl") declarations.set(node.prop, node.value);
|
||||
}
|
||||
});
|
||||
|
||||
return declarations;
|
||||
|
|
|
|||
18
tests/helpers/css.test.mjs
Normal file
18
tests/helpers/css.test.mjs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import { declarationsFor } from "./css.mjs";
|
||||
|
||||
test("declarationsFor ignores declarations in nested child rules", () => {
|
||||
const css = `
|
||||
body {
|
||||
--font-text-theme: parent;
|
||||
|
||||
.child {
|
||||
--font-text-theme: child;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
assert.equal(declarationsFor(css, "body").get("--font-text-theme"), "parent");
|
||||
});
|
||||
Loading…
Reference in a new issue