Files
ridebus-board/test/presentation.test.mjs
Zakhar Timoshenko f4ea47f2ae feat: add verification layout themes documentation and new components
- Created `verification-layout-themes.md` to document layout and theme verification results.
- Introduced `AlertCard` component for displaying alerts with appropriate icons and metadata.
- Added `RouteCloud` component to manage and display route information dynamically.
- Implemented tests for QR code generation and decoding to ensure functionality across multiple city and platform links.
2026-10-09 02:43:42 +03:00

52 lines
3.2 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import test from 'node:test';
import assert from 'node:assert/strict';
import { colorScheme, colorSchemes, lightColorSchemes, departurePage, durationParts, numericFrame, stopDirection } from '../src/lib/presentation.mjs';
test('all accent schemes remain legible against black and with black route numbers', () => {
for (const scheme of colorSchemes) {
const rgb = scheme.color.slice(1).match(/../g).map(value => parseInt(value, 16) / 255);
const channels = rgb.map(value => value <= .04045 ? value / 12.92 : ((value + .055) / 1.055) ** 2.4);
const luminance = .2126 * channels[0] + .7152 * channels[1] + .0722 * channels[2];
assert.ok((luminance + .05) / .05 >= 7, scheme.id);
}
assert.equal(colorScheme('unknown').id, 'lime');
});
test('light accents have at least 7:1 contrast against white and retain a separate default', () => {
for (const scheme of lightColorSchemes) {
const rgb = scheme.color.slice(1).match(/../g).map(value => parseInt(value, 16) / 255);
const channels = rgb.map(value => value <= .04045 ? value / 12.92 : ((value + .055) / 1.055) ** 2.4);
const luminance = .2126 * channels[0] + .7152 * channels[1] + .0722 * channels[2];
assert.ok(1.05 / (luminance + .05) >= 7, scheme.id);
}
assert.equal(colorScheme('lime', 'light').id, 'blue');
assert.equal(colorScheme('cyan').id, 'cyan');
});
test('waiting time crosses hour boundaries without displaying hundreds of minutes', () => {
assert.deepEqual(durationParts(59), [{ value: 59, unit: 'мин' }]);
assert.deepEqual(durationParts(60), [{ value: 1, unit: 'ч' }]);
assert.deepEqual(durationParts(121), [{ value: 2, unit: 'ч' }, { value: 1, unit: 'мин' }]);
assert.deepEqual(durationParts(255), [{ value: 4, unit: 'ч' }, { value: 15, unit: 'мин' }]);
assert.deepEqual(durationParts(302), [{ value: 5, unit: 'ч' }, { value: 2, unit: 'мин' }]);
});
test('clock carry rolls changed positions while keeping separators and unchanged digits still', () => {
const frame = numericFrame('09:59', '10:00', 959, 1000);
assert.equal(frame.direction, 'up');
assert.deepEqual(frame.glyphs.filter(glyph => glyph.changed).map(glyph => glyph.position), [4, 3, 1, 0]);
assert.equal(frame.glyphs.find(glyph => glyph.character === ':').changed, false);
assert.equal(numericFrame('12', '11', 12, 11).direction, 'down');
assert.equal(numericFrame('10', '9', 10, 9).glyphs.at(-1).character, '9');
});
test('six departures fit in one page when space permits; short screens preserve all requested departures across balanced pages', () => {
const items = Array.from({ length: 8 }, (_, id) => ({ id }));
const full = departurePage(items, 6, 6, 0);
assert.equal(full.items.length, 6); assert.equal(full.pages, 1);
const first = departurePage(items, 6, 4, 0), second = departurePage(items, 6, 4, 1);
assert.deepEqual([...first.items, ...second.items].map(item => item.id), [0, 1, 2, 3, 4, 5]);
assert.equal(first.items.length, second.items.length);
});
test('direction comes from platform metadata without inventing one for the main platform', () => {
assert.equal(stopDirection({ direction: 'в Новополоцк' }), 'В Новополоцк');
assert.equal(stopDirection({ direction: 'основная' }), '');
assert.equal(stopDirection({ direction: '' }), '');
});