|
1 | | -import config from './src/ngmd.config.ts'; |
| 1 | +import {mkdirSync, mkdtempSync, rmSync, writeFileSync} from 'node:fs'; |
| 2 | +import {tmpdir} from 'node:os'; |
| 3 | +import {join} from 'node:path'; |
| 4 | +import type {NgmdConfig} from './src/ngmd.config.ts'; |
| 5 | +import siteConfig from './src/ngmd.config.ts'; |
2 | 6 | import {buildLlmsTxt} from './llms-txt.plugin.ts'; |
3 | 7 |
|
4 | | -const {index, full} = buildLlmsTxt(import.meta.dirname, config); |
| 8 | +const config: NgmdConfig = { |
| 9 | + site: { |
| 10 | + name: 'Fixture Docs', |
| 11 | + description: 'A fixture site.', |
| 12 | + url: 'https://docs.example/', |
| 13 | + githubUrl: 'https://github.com/example/docs', |
| 14 | + }, |
| 15 | + nav: [ |
| 16 | + { |
| 17 | + label: 'Start', |
| 18 | + items: [ |
| 19 | + {label: 'Second', href: '/start/second'}, |
| 20 | + {label: 'First', href: '/start/first'}, |
| 21 | + {label: 'Hidden', href: '/start/hidden'}, |
| 22 | + ], |
| 23 | + }, |
| 24 | + ], |
| 25 | +}; |
| 26 | + |
| 27 | +const page = (title: string, description: string, body: string, extra = '') => |
| 28 | + `---\ntitle: ${title}\ndescription: ${description}\n${extra}---\n\n# ${title}\n\n${body}\n`; |
| 29 | + |
| 30 | +let root: string; |
| 31 | +let index: string; |
| 32 | +let full: string; |
| 33 | + |
| 34 | +beforeAll(() => { |
| 35 | + root = mkdtempSync(join(tmpdir(), 'llms-txt-')); |
| 36 | + mkdirSync(join(root, 'src/content/start'), {recursive: true}); |
| 37 | + writeFileSync(join(root, 'src/content/start/first.md'), page('First', 'The first page.', 'One.')); |
| 38 | + writeFileSync( |
| 39 | + join(root, 'src/content/start/second.md'), |
| 40 | + page('Second', 'The second page.', 'Two.'), |
| 41 | + ); |
| 42 | + writeFileSync( |
| 43 | + join(root, 'src/content/start/hidden.md'), |
| 44 | + page('Hidden', 'Not indexed.', 'Secret.', 'noIndex: true\n'), |
| 45 | + ); |
| 46 | + writeFileSync(join(root, 'src/content/extra.md'), page('Extra', 'Not in the sidebar.', 'Three.')); |
| 47 | + ({index, full} = buildLlmsTxt(root, config)); |
| 48 | +}); |
| 49 | + |
| 50 | +afterAll(() => rmSync(root, {recursive: true, force: true})); |
5 | 51 |
|
6 | 52 | describe('llms.txt', () => { |
7 | 53 | it('starts with the site name and summary', () => { |
8 | | - expect(index.startsWith(`# ${config.site.name}\n\n> ${config.site.description}\n`)).toBe(true); |
9 | | - expect(full.startsWith(`# ${config.site.name}\n`)).toBe(true); |
| 54 | + expect(index.startsWith('# Fixture Docs\n\n> A fixture site.\n')).toBe(true); |
| 55 | + expect(full.startsWith('# Fixture Docs\n')).toBe(true); |
10 | 56 | }); |
11 | 57 |
|
12 | 58 | it('links each sidebar page to its markdown route with its description, in sidebar order', () => { |
13 | | - const first = config.nav[0]; |
14 | | - expect(index).toContain(`## ${first.label}`); |
15 | | - expect(index).toMatch( |
16 | | - /- \[Quick start\]\(https:\/\/pangular-inspector\.dev\/getting-started\/quick-start\.md\): \S/, |
| 59 | + const second = index.indexOf( |
| 60 | + '- [Second](https://docs.example/start/second.md): The second page.', |
17 | 61 | ); |
18 | | - const positions = first.items |
19 | | - .map((item) => index.indexOf(`${config.site.url}${item.href}.md`)) |
20 | | - .filter((at) => at >= 0); |
21 | | - expect(positions).toEqual([...positions].sort((a, b) => a - b)); |
| 62 | + const first = index.indexOf('- [First](https://docs.example/start/first.md): The first page.'); |
| 63 | + expect(index).toContain('## Start'); |
| 64 | + expect(second).toBeGreaterThan(-1); |
| 65 | + expect(first).toBeGreaterThan(second); |
| 66 | + }); |
| 67 | + |
| 68 | + it('lists content pages missing from the sidebar under Optional', () => { |
| 69 | + expect(index).toMatch(/## Optional\n\n- \[Extra\]\(https:\/\/docs\.example\/extra\.md\)/); |
22 | 70 | }); |
23 | 71 |
|
24 | 72 | it('leaves out noIndex pages and keeps page bodies without frontmatter', () => { |
25 | | - expect(index).not.toContain('/contributing/kitchen-sink.md'); |
26 | | - expect(full).not.toContain('<!-- https://pangular-inspector.dev/contributing/kitchen-sink -->'); |
27 | | - expect(full).toContain( |
28 | | - '<!-- https://pangular-inspector.dev/getting-started/troubleshooting -->', |
29 | | - ); |
30 | | - expect(full).not.toContain('title: Troubleshooting\n'); |
31 | | - expect(full).toContain('\n\n# Troubleshooting\n'); |
| 73 | + expect(index).not.toContain('hidden'); |
| 74 | + expect(full).not.toContain('Secret.'); |
| 75 | + expect(full).toContain('<!-- https://docs.example/start/first -->\n\n# First\n\nOne.'); |
| 76 | + expect(full).not.toContain('description: The first page.'); |
| 77 | + }); |
| 78 | + |
| 79 | + it('builds the real site without errors', () => { |
| 80 | + const site = buildLlmsTxt(import.meta.dirname, siteConfig); |
| 81 | + expect(site.index.startsWith(`# ${siteConfig.site.name}\n`)).toBe(true); |
| 82 | + expect(site.index).toContain(`## ${siteConfig.nav[0].label}`); |
32 | 83 | }); |
33 | 84 | }); |
0 commit comments