emoji-rendering.test.tsβ’4.82 kB
import assert from 'node:assert/strict';
import { createWriteStream, existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
import { before, describe, test } from 'node:test';
import PDFDocument from 'pdfkit';
import { needsUnicodeFont, setupFonts } from '../src/lib/fonts.ts';
import { cleanTmpDir, getTmpSubdir } from './test-helpers.ts';
let testOutputDir: string;
before(async () => {
await cleanTmpDir();
testOutputDir = await getTmpSubdir('emoji-tests');
});
async function createTestPDF(filename: string, text: string, fontSpec?: string): Promise<string> {
const outputPath = join(testOutputDir, filename);
const doc = new PDFDocument();
const stream = createWriteStream(outputPath);
doc.pipe(stream);
// Setup fonts
const fonts = await setupFonts(doc, fontSpec);
doc.font(fonts.regular).fontSize(24).text(text);
doc.end();
await new Promise<void>((resolve, reject) => {
stream.on('finish', () => resolve());
stream.on('error', reject);
});
return outputPath;
}
describe('Emoji and Unicode Rendering', (): void => {
test('detects emoji as needing Unicode font', (): void => {
assert.strictEqual(needsUnicodeFont('Hello π'), true);
assert.strictEqual(needsUnicodeFont('π π π'), true);
assert.strictEqual(needsUnicodeFont('Test β
β'), true);
});
test('creates PDF with emoji using default font', async (): Promise<void> => {
const text = 'Hello World π π π';
const path = await createTestPDF('emoji-default.pdf', text);
assert.ok(existsSync(path), 'PDF should be created');
const stats = readFileSync(path);
assert.ok(stats.length > 0, 'PDF should have content');
console.log(` π Created: ${path} (${stats.length} bytes)`);
});
test('creates PDF with emoji using auto-detect font', async (): Promise<void> => {
const text = 'Hello World π π π';
const path = await createTestPDF('emoji-auto.pdf', text, 'auto');
assert.ok(existsSync(path), 'PDF should be created');
const stats = readFileSync(path);
assert.ok(stats.length > 0, 'PDF should have content');
console.log(` π Created: ${path} (${stats.length} bytes)`);
});
test('creates PDF with various emoji categories', async (): Promise<void> => {
const emojiTests = [
{ category: 'Smileys', text: 'π π π π π π
π€£ π' },
{ category: 'Gestures', text: 'π π€ π β π π π€' },
{ category: 'Symbols', text: 'β€οΈ π π― β
β β π₯' },
{ category: 'Objects', text: 'π± π» β¨οΈ π₯ π¨ π π§' },
];
for (const { category, text } of emojiTests) {
const filename = `emoji-${category.toLowerCase()}.pdf`;
const path = await createTestPDF(filename, `${category}: ${text}`, 'auto');
assert.ok(existsSync(path), `${category} PDF should be created`);
const stats = readFileSync(path);
console.log(` π ${category}: ${path} (${stats.length} bytes)`);
}
});
test('creates PDF with CJK characters', async (): Promise<void> => {
const text = 'δ½ ε₯½δΈη γγγ«γ‘γ―δΈη μλ
νμΈμ μΈκ³';
const path = await createTestPDF('unicode-cjk.pdf', text, 'auto');
assert.ok(existsSync(path), 'CJK PDF should be created');
const stats = readFileSync(path);
assert.ok(stats.length > 0, 'PDF should have content');
console.log(` π Created: ${path} (${stats.length} bytes)`);
});
test('creates PDF with mixed ASCII and emoji', async (): Promise<void> => {
const text = `
Technical Skills:
β’ TypeScript π
β’ Node.js β‘
β’ React βοΈ
β’ Testing β
Achievements:
π First place in hackathon
π― 100% test coverage
π Launched 5 products
`;
const path = await createTestPDF('mixed-content.pdf', text, 'auto');
assert.ok(existsSync(path), 'Mixed content PDF should be created');
const stats = readFileSync(path);
console.log(` π Created: ${path} (${stats.length} bytes)`);
});
test('creates PDF with font from URL', async (): Promise<void> => {
// Noto Sans has good Unicode coverage
const fontUrl = 'https://cdn.jsdelivr.net/npm/@fontsource/noto-sans@5.0.0/files/noto-sans-latin-400-normal.woff2';
const text = 'Hello World π Testing with downloaded font';
const path = await createTestPDF('emoji-url-font.pdf', text, fontUrl);
assert.ok(existsSync(path), 'PDF with URL font should be created');
const stats = readFileSync(path);
console.log(` π Created: ${path} (${stats.length} bytes)`);
});
});
// Print summary at the end
test('print test output directory', (): void => {
console.log(`\nπ Test PDFs generated in: ${testOutputDir}`);
console.log(' Open these files to visually verify emoji rendering\n');
});