- Route copied English MCP, CLI, technical reference, shortcut, and useNumberField pages to their canonical English sources - Repair remaining mixed-language user-guide and SDK labels - Detect cross-locale placeholder copies and substantial English content in localized Markdown during documentation integrity checks
139 lines
5 KiB
TypeScript
139 lines
5 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('rejects pages copied identically into every locale', async () => {
|
|
const docsRoot = await fixture()
|
|
await write(join(docsRoot, 'index.md'), '# English')
|
|
await write(join(docsRoot, 'ru/index.md'), '# Русский')
|
|
await write(join(docsRoot, 'fr/index.md'), '# Français')
|
|
await write(join(docsRoot, 'page.md'), '# Canonical page')
|
|
await write(join(docsRoot, 'ru/page.md'), '# English placeholder')
|
|
await write(join(docsRoot, 'fr/page.md'), '# English placeholder')
|
|
await writeFile(join(docsRoot, 'public/_redirects'), '', 'utf8')
|
|
|
|
const result = checkDocsIntegrity({
|
|
docsRoot,
|
|
localePrefixes: ['ru', 'fr'],
|
|
redirectsPath: join(docsRoot, 'public/_redirects'),
|
|
sidebarLinks: []
|
|
})
|
|
|
|
expect(result.localePlaceholderPages).toEqual({ ru: ['page.md'], fr: ['page.md'] })
|
|
expect(result.errors).toEqual([
|
|
'fr/page.md is identical across every locale and must use the canonical English page instead.',
|
|
'ru/page.md is identical across every locale and must use the canonical English page instead.'
|
|
])
|
|
})
|
|
|
|
test('rejects substantial localized pages detected as English', async () => {
|
|
const docsRoot = await fixture()
|
|
const english = Array.from(
|
|
{ length: 20 },
|
|
() => 'This localized page contains English documentation that should not be published here.'
|
|
).join(' ')
|
|
await write(join(docsRoot, 'index.md'), '# English')
|
|
await write(
|
|
join(docsRoot, 'ru/index.md'),
|
|
`# Русский\n\n${'Это русская документация. '.repeat(80)}`
|
|
)
|
|
await write(join(docsRoot, 'ru/page.md'), english)
|
|
await writeFile(join(docsRoot, 'public/_redirects'), '', 'utf8')
|
|
|
|
const result = check(docsRoot)
|
|
|
|
expect(result.localeSuspectPages.ru).toEqual(['page.md'])
|
|
expect(result.errors).toEqual([
|
|
'ru/page.md is detected as English and must be translated or use the canonical English page.'
|
|
])
|
|
})
|
|
|
|
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."
|
|
])
|
|
})
|
|
})
|