Refactor site generation into a modular content pipeline
Deploy website / deploy (push) Successful in 24s

This commit is contained in:
paul committed 2026-09-22 20:51:13 -04:00
1 parent 0f69028d4a
commit 146d516f24
20 files changed
+826 -427

No files matched your search

+78
View File
@@ -0,0 +1,78 @@
import assert from 'node:assert/strict'
import { mkdtemp, readFile, readdir, rm, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { test } from 'node:test'
import { createOutput, discardOutput, publishOutput } from '../output.js'
import { readPages } from '../content.js'
import { generatedRoot, siteUrl } from '../site.config.js'
test('headings have unique IDs and matching TOC links', async () => {
const html = await readFile(join(generatedRoot, 'notes', 'steam', 'index.html'), 'utf8')
const ids = [...html.matchAll(/<h[2-6] id="([^"]+)"/g)].map((match) => match[1])
const links = [...html.matchAll(/<a href="#([^"]+)">/g)].map((match) => match[1])
assert.ok(ids.length > 1)
assert.equal(new Set(ids).size, ids.length)
assert.deepEqual(links, ids)
})
test('sidenotes render Markdown with paired, unique controls', async () => {
const html = await readFile(join(generatedRoot, 'notes', 'lua', 'index.html'), 'utf8')
const controls = [...html.matchAll(/<input type="checkbox" id="(sidenote-\d+)"/g)].map((match) => match[1])
assert.deepEqual(controls, ['sidenote-1', 'sidenote-2'])
for (const id of controls) assert.ok(html.includes(`<label for="${id}"`))
assert.ok(html.includes('<strong>unstable</strong>'))
})
test('production excludes hidden draft pages and feed links resolve', async () => {
const pages = await readdir(join(generatedRoot, 'posts'))
assert.ok(!pages.includes('rendering-lab'))
const feed = await readFile(join(generatedRoot, 'feed.xml'), 'utf8')
assert.ok(!feed.includes('rendering-lab'))
for (const [, url] of feed.matchAll(/<guid isPermaLink="true">([^<]+)<\/guid>/g)) {
assert.ok(url.startsWith(`${siteUrl}/`))
const pathname = new URL(url).pathname
await readFile(join(generatedRoot, pathname, 'index.html'))
}
})
test('content discovery excludes drafts and prefers a published page with the same slug', async () => {
const directory = await mkdtemp(join(tmpdir(), 'www-pages-test-'))
try {
await writeFile(join(directory, '.draft.md'), '# Draft\n')
await writeFile(join(directory, '.same.md'), '# Old draft\n')
await writeFile(join(directory, 'same.md'), '# Published\n')
assert.deepEqual((await readPages(directory)).map(({ name }) => name), ['same'])
const pages = await readPages(directory, { includeDrafts: true })
assert.deepEqual(pages.map(({ name }) => name), ['draft', 'same'])
assert.equal(pages.find(({ name }) => name === 'same').title, 'Published')
} finally {
await rm(directory, { recursive: true, force: true })
}
})
test('publishing replaces output, while a discarded generation preserves it', async () => {
const parent = await mkdtemp(join(tmpdir(), 'www-output-test-'))
const destination = join(parent, '.generated')
try {
const first = await createOutput(destination)
await writeFile(join(first, 'index.html'), 'first')
await publishOutput(first, destination)
const failed = await createOutput(destination)
await writeFile(join(failed, 'index.html'), 'incomplete')
await discardOutput(failed)
assert.equal(await readFile(join(destination, 'index.html'), 'utf8'), 'first')
const missingStage = join(parent, 'missing-stage')
await assert.rejects(publishOutput(missingStage, destination))
assert.equal(await readFile(join(destination, 'index.html'), 'utf8'), 'first')
const second = await createOutput(destination)
await writeFile(join(second, 'index.html'), 'second')
await publishOutput(second, destination)
assert.equal(await readFile(join(destination, 'index.html'), 'utf8'), 'second')
} finally {
await rm(parent, { recursive: true, force: true })
}
})