/** Tests for built-site fragment validation. */ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, describe, expect, it } from 'vitest' import { inspectSiteFragments } from './verify-doc-site-fragments.ts' const roots: string[] = [] afterEach(() => { for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true }) }) function fixture(): string { const root = mkdtempSync(join(tmpdir(), 'dsh-doc-fragments-')) roots.push(root) mkdirSync(join(root, 'guide'), { recursive: true }) writeFileSync(join(root, 'index.html'), 'start') writeFileSync(join(root, 'guide/start.html'), [ '

Ready

', '', 'same page', 'html alias', 'root', 'external', ].join('')) return root } describe('inspectSiteFragments', () => { it('rejects a directory with no built pages', () => { const root = mkdtempSync(join(tmpdir(), 'dsh-doc-fragments-empty-')) roots.push(root) expect(() => inspectSiteFragments(root)).toThrow('no HTML files found') }) it('resolves clean, encoded, and same-page routes', () => { const root = fixture() writeFileSync( join(root, 'guide/encoded.html'), '

Encoded

Literal

encodedliteral', ) expect(inspectSiteFragments(root)).toEqual({ checked: 6, broken: [] }) }) it('rejects ambiguous built routes', () => { const root = fixture() writeFileSync(join(root, 'guide.html'), '

Flat

') writeFileSync(join(root, 'guide/index.html'), '

Index

') expect(() => inspectSiteFragments(root)).toThrow('share route "/guide"') }) it('rejects malformed fragment hrefs', () => { const root = fixture() writeFileSync(join(root, 'guide/invalid.html'), 'invalid') expect(() => inspectSiteFragments(root)).toThrow( 'guide/invalid.html has invalid fragment href "http://[invalid]#fragment"', ) }) it('reports missing ids and missing built routes', () => { const root = fixture() writeFileSync(join(root, 'guide/broken.html'), [ 'id', 'route', ].join('')) expect(inspectSiteFragments(root).broken).toEqual([ { source: 'guide/broken.html', href: './start#missing', target: 'guide/start.html', fragment: 'missing', }, { source: 'guide/broken.html', href: './absent#missing', fragment: 'missing', }, ]) }) })