Luigit
repositories / dotfiles

dotfiles

bugabingas dorkfiles

owned by admin

quickshell/nuguland/contrast.test.js

Raw
'use strict';

const assert = require('assert');
const fs = require('fs');

const theme = fs.readFileSync('Theme.qml', 'utf8');
function token(name, occurrence = 0) {
    const matches = [...theme.matchAll(new RegExp(`"${name}": "(#[0-9a-fA-F]{6})"`, 'g'))];
    assert(matches[occurrence], `missing theme token: ${name}[${occurrence}]`);
    return matches[occurrence][1];
}
function rgb(hex) {
    return [1, 3, 5].map(i => parseInt(hex.slice(i, i + 2), 16) / 255);
}
function composite(fg, bg, alpha) {
    const a = rgb(fg);
    const b = rgb(bg);
    return a.map((v, i) => v * alpha + b[i] * (1 - alpha));
}
function luminance(color) {
    const values = typeof color === 'string' ? rgb(color) : color;
    const linear = values.map(v => v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4);
    return linear[0] * 0.2126 + linear[1] * 0.7152 + linear[2] * 0.0722;
}
function contrast(a, b) {
    const x = luminance(a);
    const y = luminance(b);
    return (Math.max(x, y) + 0.05) / (Math.min(x, y) + 0.05);
}

const normal = token('normal', 0);
const backdrop = token('backdrop', 1);
const accent = token('accent', 1);
const worstInteractiveFill = composite(accent, backdrop, 0.38);
assert(contrast(normal, worstInteractiveFill) >= 4.5, 'normal text meets WCAG AA on strongest interactive fill');

const button = fs.readFileSync('PopupButton.qml', 'utf8');
const badge = fs.readFileSync('PopupBadge.qml', 'utf8');
const text = fs.readFileSync('NuguText.qml', 'utf8');
assert(!/selected:\s*root\.checked \|\| root\.primary/.test(button), 'buttons never select dark text on dark translucent fills');
assert(/color:\s*root\.theme\.content\.normal/.test(badge), 'badge text uses readable content color');
assert(!/selected \? theme\.content\.backdrop/.test(text), 'selected text stays readable on translucent dark controls');

console.log('contrast.test.js: ALL PASS');