Files
AtreidesAssetsFree/tests/ui/charting.test.mjs
T

101 lines
4.4 KiB
JavaScript
Raw Normal View History

2026-10-29 11:57:29 +01:00
// Generated, do not edit. sha256:69f75542e06d5cb195d0f60e5c04a612f5f451eb2e372d74f50aab610eb7789a
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { installDom } from '../helpers/mini-dom.mjs';
const dom = installDom();
const { loadCharting, hexToRgb, tintSeries, readPalette } = await import('../../client/ui/charting.js');
describe('hexToRgb', () => {
it('reads the long and the short form, with or without a hash', () => {
assert.deepEqual(hexToRgb('#FF6B00'), { r: 255, g: 107, b: 0 });
assert.deepEqual(hexToRgb('#888'), { r: 136, g: 136, b: 136 });
assert.deepEqual(hexToRgb('a3a3a3'), { r: 163, g: 163, b: 163 });
});
it('gives null for nonsense instead of throwing: a theme is a place where anything can be typed', () => {
for (const odd of ['', null, undefined, '#12', 'rgb(1,2,3)', '#gggggg']) assert.equal(hexToRgb(odd), null, `input: ${odd}`);
});
});
describe('tintSeries', () => {
it('starts full and ends on the minimum', () => {
const r = tintSeries('#FF6B00', 5);
assert.equal(r.length, 5);
assert.equal(r[0], 'rgba(255,107,0,1)');
assert.equal(r[4], 'rgba(255,107,0,0.28)');
});
it('reaches the full range whatever the count', () => {
for (const n of [2, 3, 7, 20]) {
const r = tintSeries('#FF6B00', n);
assert.equal(r.length, n);
assert.match(r[0], /,1\)$/, `n=${n}: first is full`);
assert.match(r[n - 1], /,0\.28\)$/, `n=${n}: last is the minimum`);
}
});
it('one segment is the full colour, none is an empty series', () => {
assert.deepEqual(tintSeries('#FF6B00', 1), ['rgba(255,107,0,1)']);
assert.deepEqual(tintSeries('#FF6B00', 0), []);
});
it('falls back to grey when the colour is unreadable', () => {
assert.deepEqual(tintSeries('not-a-colour', 1), ['rgba(128,128,128,1)']);
});
it('takes the range as a parameter; the line ladder of the charts uses a higher floor', () => {
assert.deepEqual(tintSeries('#000000', 2, { min: 0.5, max: 0.9 }), ['rgba(0,0,0,0.9)', 'rgba(0,0,0,0.5)']);
assert.deepEqual(tintSeries('#FF6B00', 3, { min: 0.45 }), ['rgba(255,107,0,1)', 'rgba(255,107,0,0.725)', 'rgba(255,107,0,0.45)']);
});
});
describe('loadCharting', () => {
const LIBS = { CHARTJS: '/v/chart.js', HAMMER: '/v/hammer.js', ZOOM: '/v/zoom.js' };
const scripts = () => dom.document.head.querySelectorAll('script').map(s => s.getAttribute('src'));
const settle = () => new Promise(r => setImmediate(r));
it('adds the three scripts in order, once, and resolves to window.Chart', async () => {
dom.document.head.innerHTML = '';
delete window.Chart; delete window.Hammer;
const p = loadCharting(LIBS);
assert.equal(loadCharting(LIBS), p, 'one load per session');
for (const src of ['/v/chart.js', '/v/hammer.js', '/v/zoom.js']) {
await settle();
const s = dom.document.head.querySelectorAll('script').find(x => x.getAttribute('src') === src);
if (src === '/v/chart.js') window.Chart = { ok: true };
s.onload();
}
assert.deepEqual(await p, { ok: true });
assert.deepEqual(scripts(), ['/v/chart.js', '/v/hammer.js', '/v/zoom.js']);
});
it('a failed load rejects with the app\'s message, and the next call tries again', async () => {
const failing = { CHARTJS: '/x/chart.js', HAMMER: '/x/hammer.js', ZOOM: '/x/zoom.js' };
window.Chart = undefined;
dom.document.head.innerHTML = '';
const mod = await import(`../../client/ui/charting.js?fail=${Date.now()}`);
const p = mod.loadCharting(failing, { failed: src => `Kan ${src} niet laden.` });
await settle();
dom.document.head.querySelector('script').onerror();
await assert.rejects(p, /Kan \/x\/chart\.js niet laden\./);
await settle();
const again = mod.loadCharting(failing);
assert.notEqual(again, p, 'not the remembered failure');
again.catch(() => {});
});
});
describe('readPalette', () => {
it('reads the tokens of the theme, and series(n) tints the accent with the line floor', () => {
const root = dom.document.documentElement;
root.style.setProperty('--accent', '#FF6B00');
root.style.setProperty('--text-primary', '#111');
root.style.setProperty('--border', '#ccc');
const p = readPalette();
assert.equal(p.accent, '#FF6B00');
assert.equal(p.text, '#111');
assert.equal(p.grid, '#ccc');
assert.deepEqual(p.series(3), ['rgba(255,107,0,1)', 'rgba(255,107,0,0.725)', 'rgba(255,107,0,0.45)']);
});
});