openpencil/tools/docs/tests/integrity.test.ts
Danila Poyarkov 3ef554ab2d docs: reorganize documentation and improve integrity
- Replace the ambiguous Guide section with explicit overview, reference, and development routes while preserving legacy URLs with redirects
- Route missing localized content to maintained canonical pages and emit SEO alternates only for real translations
- Add parser-backed documentation integrity checks and make the optimized local build the default while retaining a complete production build
2026-08-13 14:19:12 +03:00

93 lines
3.1 KiB
TypeScript

import { describe, expect, test } from 'bun:test'
import { mkdir, mkdtemp, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { checkDocsIntegrity } from '../src/integrity'
async function fixture() {
const docsRoot = await mkdtemp(join(tmpdir(), 'open-pencil-docs-integrity-'))
await mkdir(join(docsRoot, 'public'), { recursive: true })
return docsRoot
}
async function write(path: string, content = '# Page') {
await mkdir(join(path, '..'), { recursive: true })
await writeFile(path, content, 'utf8')
}
function check(docsRoot: string, sidebarLinks: string[] = []) {
return checkDocsIntegrity({
docsRoot,
localePrefixes: ['ru'],
redirectsPath: join(docsRoot, 'public/_redirects'),
sidebarLinks
})
}
describe('checkDocsIntegrity', () => {
test('accepts valid Markdown, sidebars, redirects, and incomplete locales', async () => {
const docsRoot = await fixture()
await write(join(docsRoot, 'index.md'), '[Page](/page)')
await write(join(docsRoot, 'page.md'))
await write(join(docsRoot, 'ru/index.md'))
await write(join(docsRoot, 'legacy.md'))
await writeFile(join(docsRoot, 'public/_redirects'), '/old /page 301\n', 'utf8')
const result = check(docsRoot, ['/page'])
expect(result.errors).toEqual([])
expect(result.localeMissingPages.ru).toEqual(['legacy.md', 'page.md'])
})
test('uses Markdown syntax instead of treating code parentheses as links', async () => {
const docsRoot = await fixture()
const markdown = [
'`call(not-a-link)`',
'',
'```ts',
'call(still-not-a-link)',
'```',
'',
'[Page][page]',
'',
'[page]: /page'
].join('\n')
await write(join(docsRoot, 'index.md'), markdown)
await write(join(docsRoot, 'page.md'))
await writeFile(join(docsRoot, 'public/_redirects'), '/old /page 301\n', 'utf8')
expect(check(docsRoot).errors).toEqual([])
})
test('reports missing Markdown and sidebar targets', async () => {
const docsRoot = await fixture()
await write(join(docsRoot, 'index.md'), '[Missing](./missing)')
await writeFile(join(docsRoot, 'public/_redirects'), '', 'utf8')
expect(check(docsRoot, ['/also-missing']).errors).toEqual([
"Sidebar links to missing page '/also-missing'.",
"index.md links to missing target './missing'."
])
})
test('reports invalid, duplicate, shadowing, and missing redirect targets', async () => {
const docsRoot = await fixture()
await write(join(docsRoot, 'old.md'))
await write(join(docsRoot, 'index.md'))
await writeFile(
join(docsRoot, 'public/_redirects'),
['/old /missing 301', '/old / 302', '/bad / 999'].join('\n'),
'utf8'
)
expect(check(docsRoot).errors).toEqual([
"Redirect '/bad' has unsupported status '999'.",
"Redirect '/old' is duplicated.",
"Redirect '/old' targets missing page '/missing'.",
"Redirect source '/old' still has a page and would shadow it.",
"Redirect source '/old' still has a page and would shadow it."
])
})
})