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/); });