import test from 'node:test'; import assert from 'node:assert/strict'; import {normalizeText, render, styles} from '../bitmap.js'; test('compact lettering renders a known phrase with correct spacing', () => { assert.equal(render('HI', 'compact'), [ '# # #####', '# # #', '# # #', '##### #', '# # #', '# # #', '# # #####', ].join('\n')); }); for (const style of styles) { test(`${style} renders digits, punctuation and multiline input`, () => { const first = render('Hello 123!', style); assert.equal(first.split('\n').length, 7); assert.match(first, /\S/); assert.equal(render('Hello 123!\r\nWorld?', style), `${first}\n\n${render('World?', style)}`); }); } for (const [text, expected] of [ ['çığöşü İ', 'CIGOSU I'], ['café', 'CAFE'], ['abc 123!?', 'ABC 123!?'], ]) { test(`normalizes ${text}`, () => assert.equal(normalizeText(text), expected)); } test('unsupported characters have a visible fallback', () => { assert.equal(render('🙂'), render('?')); }); test('all printable ASCII characters have distinct supported glyphs', () => { for (let code = 32; code <= 126; code++) { const char = String.fromCharCode(code); if (char === '?') continue; assert.notEqual(render(char), render('?'), `missing ${char}`); } }); test('banner uses the original normalized letter as ink', () => { assert.match(render('a', 'banner'), /^ AAA\n/); assert.doesNotMatch(render('a', 'banner'), /#/); }); test('rejects invalid styles and overlong text', () => { assert.throws(() => render('hello', 'unknown'), /Unknown/); assert.throws(() => render('x'.repeat(501)), /too long/); assert.doesNotThrow(() => render('x'.repeat(500))); });