Files
wip-reference/site/tests/landing-glyphs.test.mjs

63 lines
2.7 KiB
JavaScript

import { test } from 'node:test';
import assert from 'node:assert/strict';
import { createHash } from 'node:crypto';
import { readFileSync } from 'node:fs';
import opentype from 'opentype.js';
import { glyphPath, trunkPath, cellWidth, rowHeight, stemWidth, branchY, branchThickness } from '../src/lib/landing-glyphs.mjs';
const box = (d) => opentype.Path.fromSVG(d, { flipY: false, decimalPlaces: 5 }).getBoundingBox();
const close = (actual, expected) => assert.ok(Math.abs(actual - expected) < .00002, `${actual} != ${expected}`);
test('pinned font binaries and upstream licenses match their integrity manifest', () => {
const lines = readFileSync('public/fonts/SHA256SUMS', 'utf8').trim().split('\n');
assert.ok(lines.length >= 8);
for (const line of lines) {
const [expected, name] = line.trim().split(/\s+/);
const bytes = readFileSync(`public/fonts/${name}`);
assert.equal(createHash('sha256').update(bytes).digest('hex'), expected, name);
}
});
test('Lyth Mono paths retain exact advance, row bounds and stroke dimensions', () => {
close(cellWidth, 8.456);
close(stemWidth, 1.064 * 1.25);
close(branchThickness, (68 / 1170) * 24 * 1.25);
close(branchY, rowHeight / 2);
const vertical = box(glyphPath('│'));
close(vertical.y1, 0);
close(vertical.y2, 24);
close((vertical.x1 + vertical.x2) / 2, cellWidth / 2);
close(vertical.x2 - vertical.x1, stemWidth);
const horizontal = box(glyphPath('─'));
close(horizontal.x1, 0);
close(horizontal.x2, cellWidth);
close(horizontal.y2 - horizontal.y1, branchThickness);
close((horizontal.y1 + horizontal.y2) / 2, branchY);
const tee = box(glyphPath('├'));
close(tee.x1, cellWidth / 2 - stemWidth / 2);
close(tee.x2, cellWidth);
close(tee.y1, 0);
close(tee.y2, rowHeight);
const elbow = box(glyphPath('└'));
close(elbow.x1, tee.x1);
close(elbow.x2, cellWidth);
close(elbow.y1, 0);
close(elbow.y2, branchY + branchThickness / 2);
const trunk = box(trunkPath);
close(trunk.x1 + trunk.x2, 0);
close(trunk.x2 - trunk.x1, stemWidth);
close(trunk.y1, 0);
close(trunk.y2, 1);
});
test('cell layout bypasses shaping, preserves spaces and fails for missing glyphs', () => {
close(box(glyphPath(' │')).x1, box(glyphPath('│')).x1 + 4 * cellWidth);
close(box(glyphPath('── ')).x2, 2 * cellWidth);
for (const prefix of ['├─ ', '│ ├─ ', '│ └─ ', ' └─ ', '├ ', '│ ├ ', '│ └ ', '│ └ ', ' └ ', '├── ', '│ ├── ', '│ └── ', '│ └── ', ' └── ']) {
const path = glyphPath(prefix);
assert.ok(path.length > 0);
assert.ok(!path.includes('NaN'));
}
assert.throws(() => glyphPath('日'), /Lyth Mono is missing/);
});