79 lines
3.6 KiB
JavaScript
79 lines
3.6 KiB
JavaScript
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 })
|
|
}
|
|
})
|