Files
Ken e100119e3b feat: download and self-host Google Fonts woff2 files
- Created scripts/download-fonts.py: downloads Google Fonts woff2 files (latin subset only) using urllib.request with Chrome User-Agent header
- Parses CSS response for latin @font-face blocks, extracts family/weight/style/URL metadata
- Downloads to src/fonts/ with naming convention {family}-{weight}{-italic}.woff2
- Created src/styles/fonts.css: 8 @font-face declarations for:
  * Source Serif 4 (400, 600, 400-italic) — prose voice
  * Inter (400, 500, 600, 700) — structure voice
  * JetBrains Mono (400) — evidence voice
- All fonts use format('woff2'), font-display: swap, and relative URLs
- Fonts placed in src/fonts/ for Vite processing at build time

Generated with Amplifier

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
2026-05-26 22:39:10 +00:00

172 lines
5.7 KiB
JavaScript

/**
* Verification test for Self-Hosted Fonts (Task 3)
*
* Checks that:
* 1. 8 woff2 font files exist in src/fonts/
* 2. src/styles/fonts.css exists with 8 @font-face declarations
* 3. Each @font-face has correct font-family, weight, style, src, font-display
* 4. src URLs use relative paths to ../fonts/
*/
import { readFileSync, existsSync, statSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const root = join(__dirname, '..');
let passed = 0;
let failed = 0;
function assert(condition, message) {
if (condition) {
console.log(`${message}`);
passed++;
} else {
console.error(`${message}`);
failed++;
}
}
// === 1. Font files exist in src/fonts/ ===
console.log('\n1. Font files exist in src/fonts/');
const expectedFonts = [
'source-serif-4-400.woff2',
'source-serif-4-600.woff2',
'source-serif-4-400-italic.woff2',
'inter-400.woff2',
'inter-500.woff2',
'inter-600.woff2',
'inter-700.woff2',
'jetbrains-mono-400.woff2',
];
for (const font of expectedFonts) {
const fontPath = join(root, 'src/fonts', font);
const exists = existsSync(fontPath);
assert(exists, `src/fonts/${font} exists`);
if (exists) {
const stat = statSync(fontPath);
assert(stat.size > 1000, `src/fonts/${font} is a real font file (${stat.size} bytes)`);
}
}
// === 2. fonts.css exists ===
console.log('\n2. fonts.css exists');
const fontsCssPath = join(root, 'src/styles/fonts.css');
assert(existsSync(fontsCssPath), 'src/styles/fonts.css exists');
if (!existsSync(fontsCssPath)) {
console.log('\nfonts.css not found, skipping remaining tests.');
console.log(`\n${'='.repeat(40)}`);
console.log(`Results: ${passed} passed, ${failed} failed out of ${passed + failed}`);
process.exit(1);
}
const css = readFileSync(fontsCssPath, 'utf8');
// === 3. Has 8 @font-face declarations ===
console.log('\n3. @font-face count');
const fontFaceBlocks = css.match(/@font-face\s*\{[^}]+\}/g);
const fontFaceCount = fontFaceBlocks ? fontFaceBlocks.length : 0;
assert(fontFaceCount === 8, `has exactly 8 @font-face declarations (found ${fontFaceCount})`);
// === 4. Source Serif 4 declarations (prose voice) ===
console.log('\n4. Source Serif 4 declarations (prose voice)');
// Regular 400
assert(
css.includes("font-family: 'Source Serif 4'") || css.includes('font-family: "Source Serif 4"'),
"has font-family: 'Source Serif 4'"
);
// Check for 400 normal
const ss4_400_block = fontFaceBlocks?.find(
(b) =>
(b.includes("'Source Serif 4'") || b.includes('"Source Serif 4"')) &&
b.includes('font-weight: 400') &&
b.includes('font-style: normal')
);
assert(!!ss4_400_block, 'Source Serif 4 400 normal declaration exists');
// Check for 600 normal
const ss4_600_block = fontFaceBlocks?.find(
(b) =>
(b.includes("'Source Serif 4'") || b.includes('"Source Serif 4"')) &&
b.includes('font-weight: 600') &&
b.includes('font-style: normal')
);
assert(!!ss4_600_block, 'Source Serif 4 600 normal declaration exists');
// Check for 400 italic
const ss4_400i_block = fontFaceBlocks?.find(
(b) =>
(b.includes("'Source Serif 4'") || b.includes('"Source Serif 4"')) &&
b.includes('font-weight: 400') &&
b.includes('font-style: italic')
);
assert(!!ss4_400i_block, 'Source Serif 4 400 italic declaration exists');
// === 5. Inter declarations (structure voice) ===
console.log('\n5. Inter declarations (structure voice)');
const interWeights = [400, 500, 600, 700];
for (const weight of interWeights) {
const interBlock = fontFaceBlocks?.find(
(b) =>
(b.includes("'Inter'") || b.includes('"Inter"')) &&
b.includes(`font-weight: ${weight}`) &&
b.includes('font-style: normal')
);
assert(!!interBlock, `Inter ${weight} normal declaration exists`);
}
// === 6. JetBrains Mono declaration (evidence voice) ===
console.log('\n6. JetBrains Mono declaration (evidence voice)');
const jbBlock = fontFaceBlocks?.find(
(b) =>
(b.includes("'JetBrains Mono'") || b.includes('"JetBrains Mono"')) &&
b.includes('font-weight: 400') &&
b.includes('font-style: normal')
);
assert(!!jbBlock, 'JetBrains Mono 400 normal declaration exists');
// === 7. All declarations use format('woff2') ===
console.log("\n7. All use format('woff2')");
if (fontFaceBlocks) {
for (const block of fontFaceBlocks) {
assert(block.includes("format('woff2')"), `@font-face block uses format('woff2')`);
}
}
// === 8. All declarations use font-display: swap ===
console.log('\n8. All use font-display: swap');
if (fontFaceBlocks) {
for (const block of fontFaceBlocks) {
assert(block.includes('font-display: swap'), '@font-face block uses font-display: swap');
}
}
// === 9. All src URLs use relative paths to ../fonts/ ===
console.log('\n9. src URLs use relative ../fonts/ paths');
if (fontFaceBlocks) {
for (const block of fontFaceBlocks) {
assert(block.includes("url('../fonts/"), "@font-face src uses url('../fonts/...')");
}
}
// === 10. download-fonts.py script exists ===
console.log('\n10. download-fonts.py script exists');
const scriptPath = join(root, 'scripts/download-fonts.py');
assert(existsSync(scriptPath), 'scripts/download-fonts.py exists');
if (existsSync(scriptPath)) {
const script = readFileSync(scriptPath, 'utf8');
assert(script.includes('urllib.request'), 'script uses urllib.request');
assert(script.includes('User-Agent') || script.includes('user-agent'), 'script sets User-Agent header');
assert(script.includes('woff2'), 'script references woff2 format');
}
// === Summary ===
console.log(`\n${'='.repeat(40)}`);
console.log(`Results: ${passed} passed, ${failed} failed out of ${passed + failed}`);
if (failed > 0) {
process.exit(1);
} else {
console.log('All font verification tests passed!');
}