feat: Initial prototype

This commit is contained in:
abdus committed 2026-10-10 12:51:33 +02:00
commit 819f6a61cd
327 files changed
+252446

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import {readFile, readdir} from 'node:fs/promises';
import {fonts} from '../font-catalog.js';
import {render, registerFont, renderLoaded, resolveFont, FONT_CACHE} from '../renderer.js';
test('catalog includes every bundled FIGlet font', async () => {
const files = await readdir(new URL('../fonts/figlet/', import.meta.url));
assert.deepEqual(fonts, files.filter(file => file.endsWith('.flf')).map(file => file.slice(0, -4)).sort());
});
for (const font of fonts) {
test(`renders ${font} from its local font file`, async () => {
registerFont(font, await readFile(new URL(`../fonts/figlet/${font}.flf`, import.meta.url), 'utf8'));
const art = renderLoaded('Hello World! 123', font);
assert.equal(typeof art, 'string');
assert.match(art, /\S/);
});
}
test('Standard preserves lowercase lettering and the familiar FIGlet shape', () => {
assert.equal(renderLoaded('Hi', 'Standard'), [
' _ _ _ ', ' | | | (_)', ' | |_| | |', ' | _ | |', ' |_| |_|_|',
].join('\n'));
});
test('old lowercase font links resolve to their library names', () => {
for (const [name, expected] of [['standard', 'Standard'], ['slant', 'Slant'], ['block', 'Block'], ['banner', 'Banner'], ['compact', 'compact'], ['unknown', 'Standard']]) {
assert.equal(resolveFont(name), expected);
}
});
test('missing font requests can be retried', async () => {
const originalFetch = globalThis.fetch;
const data = await readFile(new URL('../fonts/figlet/Standard.flf', import.meta.url), 'utf8');
const figlet = (await import('../vendor/figlet.js')).default;
delete figlet.figFonts.Standard;
try {
globalThis.fetch = async () => new Response('', {status: 404});
await assert.rejects(render('Hi', 'Standard'), /Cannot load font/);
globalThis.fetch = async () => new Response(data);
assert.match(await render('Hi', 'Standard'), /\S/);
} finally {
globalThis.fetch = originalFetch;
}
});
test('caches only selected fonts and reuses them when offline', async () => {
const originalFetch = globalThis.fetch;
const originalCaches = globalThis.caches;
const entries = new Map();
const figlet = (await import('../vendor/figlet.js')).default;
for (const font of ['Standard', 'Slant', 'Small']) delete figlet.figFonts[font];
try {
globalThis.caches = {
async open(name) {
assert.equal(name, FONT_CACHE);
return {
async match(url) { return entries.get(url)?.clone(); },
async put(url, response) { entries.set(url, response.clone()); },
};
},
};
globalThis.fetch = async url => new Response(await readFile(new URL(url), 'utf8'));
await render('Hello', 'Standard');
await render('Hello', 'Slant');
assert.equal(entries.size, 2);
assert.ok([...entries.keys()].every(url => /\/(Standard|Slant)\.flf$/.test(url)));
delete figlet.figFonts.Standard;
globalThis.fetch = async () => { throw new Error('Offline'); };
assert.match(await render('Offline', 'Standard'), /\S/);
await assert.rejects(render('Offline', 'Small'), /Offline/);
assert.equal(entries.size, 2);
} finally {
globalThis.fetch = originalFetch;
if (originalCaches === undefined) delete globalThis.caches;
else globalThis.caches = originalCaches;
}
});
test('rejects unknown fonts and overlong input', async () => {
await assert.rejects(render('Hello', 'unknown'), /Unknown/);
await assert.rejects(render('x'.repeat(501)), /too long/);
});