@vendure-io/docs-provider 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/testing/index.d.ts +4 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/run-all-tests.d.ts +56 -0
- package/dist/testing/run-all-tests.d.ts.map +1 -0
- package/dist/testing/types.d.ts +161 -0
- package/dist/testing/types.d.ts.map +1 -1
- package/dist/testing/validate-admonitions.d.ts.map +1 -1
- package/dist/testing/validate-code-languages.d.ts +86 -0
- package/dist/testing/validate-code-languages.d.ts.map +1 -0
- package/dist/testing/validate-frontmatter.d.ts +40 -0
- package/dist/testing/validate-frontmatter.d.ts.map +1 -0
- package/dist/testing.cjs +13 -6
- package/dist/testing.js +775 -143
- package/docs/mdx-testing.md +553 -140
- package/package.json +1 -1
package/docs/mdx-testing.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Documentation Testing
|
|
2
2
|
|
|
3
|
-
`@vendure-io/docs-provider` includes a testing module that
|
|
3
|
+
`@vendure-io/docs-provider` includes a comprehensive testing module that validates your documentation **before publishing**. It catches errors early, reducing the feedback loop between publishing and discovering issues.
|
|
4
4
|
|
|
5
|
-
## Why Test
|
|
5
|
+
## Why Test Documentation?
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Documentation errors only surface when the website attempts to render your pages. Without pre-publish testing, this creates a slow feedback loop:
|
|
8
8
|
|
|
9
9
|
1. Write MDX content
|
|
10
10
|
2. Publish package to npm
|
|
@@ -15,9 +15,18 @@ MDX compilation errors only surface when the documentation website attempts to r
|
|
|
15
15
|
|
|
16
16
|
The testing module lets you catch errors at step 1, before any publishing occurs.
|
|
17
17
|
|
|
18
|
+
## What Gets Validated?
|
|
19
|
+
|
|
20
|
+
The testing module runs four validators in sequence:
|
|
21
|
+
|
|
22
|
+
1. **Frontmatter Validation** - Validates frontmatter against the DocPageMeta schema
|
|
23
|
+
2. **Admonition Validation** - Checks for correct admonition syntax (bracket notation)
|
|
24
|
+
3. **Code Language Validation** - Ensures code blocks use valid Shiki language identifiers
|
|
25
|
+
4. **MDX Compilation** - Full AST parsing to catch syntax errors
|
|
26
|
+
|
|
18
27
|
## Installation
|
|
19
28
|
|
|
20
|
-
The testing module is included in `@vendure-io/docs-provider`. No additional installation is required
|
|
29
|
+
The testing module is included in `@vendure-io/docs-provider`. No additional installation is required:
|
|
21
30
|
|
|
22
31
|
```bash
|
|
23
32
|
npm install @vendure-io/docs-provider
|
|
@@ -27,30 +36,30 @@ bun add @vendure-io/docs-provider
|
|
|
27
36
|
|
|
28
37
|
## Quick Start
|
|
29
38
|
|
|
30
|
-
###
|
|
39
|
+
### Using runAllTests (Recommended)
|
|
31
40
|
|
|
32
|
-
The simplest way to
|
|
41
|
+
The simplest way to validate all documentation in your package:
|
|
33
42
|
|
|
34
43
|
```typescript
|
|
35
|
-
|
|
36
|
-
import {
|
|
44
|
+
// scripts/test-docs.ts
|
|
45
|
+
import { manifest } from '../src/manifest'
|
|
46
|
+
import { runAllTests } from '@vendure-io/docs-provider/testing'
|
|
37
47
|
|
|
38
|
-
|
|
39
|
-
|
|
48
|
+
runAllTests(manifest)
|
|
49
|
+
```
|
|
40
50
|
|
|
41
|
-
|
|
42
|
-
process.exit(report.failed > 0 ? 1 : 0)
|
|
43
|
-
}
|
|
51
|
+
That's it! This single function call:
|
|
44
52
|
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
- Runs all 4 validators in sequence
|
|
54
|
+
- Prints a unified report to the console
|
|
55
|
+
- Exits with code 1 if any errors are found
|
|
47
56
|
|
|
48
|
-
Save this as `scripts/test-
|
|
57
|
+
Save this as `scripts/test-docs.ts` and run it:
|
|
49
58
|
|
|
50
59
|
```bash
|
|
51
|
-
npx tsx scripts/test-
|
|
60
|
+
npx tsx scripts/test-docs.ts
|
|
52
61
|
# or with bun
|
|
53
|
-
bun run scripts/test-
|
|
62
|
+
bun run scripts/test-docs.ts
|
|
54
63
|
```
|
|
55
64
|
|
|
56
65
|
### Adding to package.json
|
|
@@ -60,25 +69,25 @@ Add a script to your `package.json` for easy execution:
|
|
|
60
69
|
```json
|
|
61
70
|
{
|
|
62
71
|
"scripts": {
|
|
63
|
-
"test:
|
|
64
|
-
"prepublishOnly": "npm run test:
|
|
72
|
+
"test:docs": "tsx scripts/test-docs.ts",
|
|
73
|
+
"prepublishOnly": "npm run test:docs"
|
|
65
74
|
}
|
|
66
75
|
}
|
|
67
76
|
```
|
|
68
77
|
|
|
69
|
-
The `prepublishOnly` script ensures
|
|
78
|
+
The `prepublishOnly` script ensures validation runs before every npm publish.
|
|
70
79
|
|
|
71
|
-
##
|
|
80
|
+
## Unified Test Runner
|
|
72
81
|
|
|
73
|
-
###
|
|
82
|
+
### runAllTests
|
|
74
83
|
|
|
75
|
-
|
|
84
|
+
Runs all documentation validators on a manifest.
|
|
76
85
|
|
|
77
86
|
```typescript
|
|
78
|
-
async function
|
|
87
|
+
async function runAllTests(
|
|
79
88
|
manifest: DocsPackageManifest,
|
|
80
|
-
options?:
|
|
81
|
-
): Promise<
|
|
89
|
+
options?: TestRunnerOptions,
|
|
90
|
+
): Promise<TestRunnerReport>
|
|
82
91
|
```
|
|
83
92
|
|
|
84
93
|
**Parameters:**
|
|
@@ -88,6 +97,175 @@ async function testManifestMdx(
|
|
|
88
97
|
|
|
89
98
|
**Options:**
|
|
90
99
|
|
|
100
|
+
| Option | Type | Default | Description |
|
|
101
|
+
| --------------- | ----------------------------------------- | ------- | ---------------------------------------------------- |
|
|
102
|
+
| `verbose` | `boolean` | `false` | Show details for all files, not just failures |
|
|
103
|
+
| `failFast` | `boolean` | `false` | Stop on first error in any validator |
|
|
104
|
+
| `exit` | `boolean` | `true` | Auto-exit process with appropriate code |
|
|
105
|
+
| `silent` | `boolean` | `false` | Suppress all console output |
|
|
106
|
+
| `frontmatter` | `boolean \| ValidateFrontmatterOptions` | `true` | Frontmatter validation options, or `false` to skip |
|
|
107
|
+
| `admonitions` | `boolean \| ValidateAdmonitionsOptions` | `true` | Admonition validation options, or `false` to skip |
|
|
108
|
+
| `codeLanguages` | `boolean \| ValidateCodeLanguagesOptions` | `true` | Code language validation options, or `false` to skip |
|
|
109
|
+
| `mdx` | `boolean \| TestManifestOptions` | `true` | MDX compilation options, or `false` to skip |
|
|
110
|
+
|
|
111
|
+
**Example with options:**
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { manifest } from '../src/manifest'
|
|
115
|
+
import { runAllTests } from '@vendure-io/docs-provider/testing'
|
|
116
|
+
|
|
117
|
+
// Skip frontmatter validation, enable verbose output
|
|
118
|
+
runAllTests(manifest, {
|
|
119
|
+
verbose: true,
|
|
120
|
+
frontmatter: false,
|
|
121
|
+
})
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Example for programmatic use:**
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import { manifest } from '../src/manifest'
|
|
128
|
+
import { runAllTests } from '@vendure-io/docs-provider/testing'
|
|
129
|
+
|
|
130
|
+
async function main() {
|
|
131
|
+
const report = await runAllTests(manifest, {
|
|
132
|
+
exit: false, // Don't auto-exit, we want the report
|
|
133
|
+
silent: true, // Suppress default output
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
// Custom handling
|
|
137
|
+
if (!report.success) {
|
|
138
|
+
console.error(`Found ${report.totalErrors} errors`)
|
|
139
|
+
// Do something with report.frontmatter, report.admonitions, etc.
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
main()
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Example output:**
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
Documentation Test Report: my-plugin
|
|
150
|
+
============================================================
|
|
151
|
+
|
|
152
|
+
Summary
|
|
153
|
+
------------------------------------------------------------
|
|
154
|
+
✓ Frontmatter OK (25 files)
|
|
155
|
+
✓ Admonitions OK (25 files)
|
|
156
|
+
✗ Code Languages 2 errors (142 blocks)
|
|
157
|
+
✓ MDX Compilation 25/25 passed (25 files)
|
|
158
|
+
|
|
159
|
+
Total errors: 2
|
|
160
|
+
Total time: 156.32ms
|
|
161
|
+
|
|
162
|
+
Details
|
|
163
|
+
------------------------------------------------------------
|
|
164
|
+
|
|
165
|
+
Code Language Validation:
|
|
166
|
+
Language 'env' - Use 'dotenv' instead of 'env'
|
|
167
|
+
- docs/configuration.mdx:15
|
|
168
|
+
- docs/deployment.mdx:42
|
|
169
|
+
|
|
170
|
+
✗ 2 errors found.
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### TestRunnerReport
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
interface TestRunnerReport {
|
|
177
|
+
/** Package ID from the manifest */
|
|
178
|
+
packageId: string
|
|
179
|
+
/** Frontmatter validation report (if run) */
|
|
180
|
+
frontmatter?: FrontmatterValidationReport
|
|
181
|
+
/** Admonition validation report (if run) */
|
|
182
|
+
admonitions?: AdmonitionValidationReport
|
|
183
|
+
/** Code language validation report (if run) */
|
|
184
|
+
codeLanguages?: CodeLanguageValidationReport
|
|
185
|
+
/** MDX compilation report (if run) */
|
|
186
|
+
mdx?: MdxTestReport
|
|
187
|
+
/** Total number of errors across all validators */
|
|
188
|
+
totalErrors: number
|
|
189
|
+
/** Total time taken in milliseconds */
|
|
190
|
+
totalTime: number
|
|
191
|
+
/** Whether all validations passed */
|
|
192
|
+
success: boolean
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Individual Validators
|
|
199
|
+
|
|
200
|
+
For fine-grained control, you can run validators individually.
|
|
201
|
+
|
|
202
|
+
### Frontmatter Validation
|
|
203
|
+
|
|
204
|
+
Validates that all MDX files have valid frontmatter according to the DocPageMeta schema.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { manifest } from './src/manifest'
|
|
208
|
+
import { validateFrontmatter, formatFrontmatterReport } from '@vendure-io/docs-provider/testing'
|
|
209
|
+
|
|
210
|
+
const report = validateFrontmatter(manifest)
|
|
211
|
+
|
|
212
|
+
if (report.errors.length > 0) {
|
|
213
|
+
console.error(formatFrontmatterReport(report))
|
|
214
|
+
process.exit(1)
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
**Options:**
|
|
219
|
+
|
|
220
|
+
| Option | Type | Default | Description |
|
|
221
|
+
| ---------- | ---------- | ----------- | ----------------------------- |
|
|
222
|
+
| `failFast` | `boolean` | `false` | Stop on first error |
|
|
223
|
+
| `onError` | `Function` | `undefined` | Callback for each error found |
|
|
224
|
+
|
|
225
|
+
**Example output:**
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
Frontmatter Validation Report: my-plugin
|
|
229
|
+
==================================================
|
|
230
|
+
|
|
231
|
+
Files scanned: 25
|
|
232
|
+
Errors found: 2
|
|
233
|
+
Total time: 12.45ms
|
|
234
|
+
|
|
235
|
+
Errors:
|
|
236
|
+
--------------------------------------------------
|
|
237
|
+
|
|
238
|
+
docs/getting-started.mdx
|
|
239
|
+
- title: Page title is required
|
|
240
|
+
|
|
241
|
+
docs/advanced.mdx
|
|
242
|
+
- lastModified: Invalid datetime
|
|
243
|
+
|
|
244
|
+
Frontmatter requirements:
|
|
245
|
+
- title: Required, non-empty string
|
|
246
|
+
- description: Optional string
|
|
247
|
+
- keywords: Optional array of strings
|
|
248
|
+
- sidebarLabel: Optional string
|
|
249
|
+
- hidden: Optional boolean
|
|
250
|
+
- order: Optional integer
|
|
251
|
+
- lastModified: Optional ISO 8601 datetime
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### MDX Compilation Testing
|
|
255
|
+
|
|
256
|
+
#### testManifestMdx
|
|
257
|
+
|
|
258
|
+
Tests all MDX files referenced in a manifest's navigation tree.
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
async function testManifestMdx(
|
|
262
|
+
manifest: DocsPackageManifest,
|
|
263
|
+
options?: TestManifestOptions,
|
|
264
|
+
): Promise<MdxTestReport>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
**Options:**
|
|
268
|
+
|
|
91
269
|
| Option | Type | Default | Description |
|
|
92
270
|
| --------------- | --------------- | --------------- | --------------------- |
|
|
93
271
|
| `failFast` | `boolean` | `false` | Stop on first failure |
|
|
@@ -98,15 +276,19 @@ async function testManifestMdx(
|
|
|
98
276
|
**Example with progress reporting:**
|
|
99
277
|
|
|
100
278
|
```typescript
|
|
279
|
+
import { testManifestMdx, formatTestReport } from '@vendure-io/docs-provider/testing'
|
|
280
|
+
|
|
101
281
|
const report = await testManifestMdx(manifest, {
|
|
102
282
|
onProgress: (current, total, result) => {
|
|
103
283
|
const status = result.success ? '✓' : '✗'
|
|
104
284
|
console.log(`[${current}/${total}] ${status} ${result.filePath}`)
|
|
105
285
|
},
|
|
106
286
|
})
|
|
287
|
+
|
|
288
|
+
console.log(formatTestReport(report))
|
|
107
289
|
```
|
|
108
290
|
|
|
109
|
-
|
|
291
|
+
#### compileMdx
|
|
110
292
|
|
|
111
293
|
Compiles a single MDX string and returns the result.
|
|
112
294
|
|
|
@@ -142,106 +324,136 @@ if (result.success) {
|
|
|
142
324
|
}
|
|
143
325
|
```
|
|
144
326
|
|
|
145
|
-
|
|
327
|
+
#### createProgressReporter
|
|
146
328
|
|
|
147
|
-
|
|
329
|
+
Creates a simple progress reporter for console output.
|
|
148
330
|
|
|
149
331
|
```typescript
|
|
150
|
-
|
|
332
|
+
import { testManifestMdx, createProgressReporter } from '@vendure-io/docs-provider/testing'
|
|
333
|
+
|
|
334
|
+
const report = await testManifestMdx(manifest, {
|
|
335
|
+
onProgress: createProgressReporter(),
|
|
336
|
+
})
|
|
151
337
|
```
|
|
152
338
|
|
|
153
|
-
|
|
339
|
+
#### getDefaultRemarkPlugins / getDefaultRehypePlugins
|
|
154
340
|
|
|
155
|
-
|
|
156
|
-
- `verbose` - If `true`, shows all results. If `false`, only shows failures.
|
|
341
|
+
Get the default plugins used for MDX compilation. Useful for extending the plugin list.
|
|
157
342
|
|
|
158
|
-
|
|
343
|
+
```typescript
|
|
344
|
+
import {
|
|
345
|
+
testManifestMdx,
|
|
346
|
+
getDefaultRemarkPlugins,
|
|
347
|
+
getDefaultRehypePlugins,
|
|
348
|
+
} from '@vendure-io/docs-provider/testing'
|
|
349
|
+
import myCustomPlugin from './my-plugin'
|
|
159
350
|
|
|
351
|
+
const report = await testManifestMdx(manifest, {
|
|
352
|
+
remarkPlugins: [...getDefaultRemarkPlugins(), myCustomPlugin],
|
|
353
|
+
rehypePlugins: getDefaultRehypePlugins(),
|
|
354
|
+
})
|
|
160
355
|
```
|
|
161
|
-
MDX Compilation Report: my-plugin
|
|
162
|
-
==================================================
|
|
163
356
|
|
|
164
|
-
|
|
165
|
-
Passed: 4 (80.0%)
|
|
166
|
-
Failed: 1
|
|
167
|
-
Total time: 156.32ms
|
|
357
|
+
---
|
|
168
358
|
|
|
169
|
-
|
|
170
|
-
--------------------------------------------------
|
|
171
|
-
[PASS] docs/getting-started.mdx (45.21ms)
|
|
172
|
-
[PASS] docs/installation.mdx (32.11ms)
|
|
173
|
-
[PASS] docs/configuration.mdx (28.54ms)
|
|
174
|
-
[PASS] docs/api-reference.mdx (35.67ms)
|
|
175
|
-
[FAIL] docs/advanced.mdx (14.79ms)
|
|
176
|
-
Error (line 42:15): Unexpected token
|
|
359
|
+
## Types Reference
|
|
177
360
|
|
|
178
|
-
|
|
179
|
-
```
|
|
361
|
+
### TestRunnerReport
|
|
180
362
|
|
|
181
|
-
|
|
363
|
+
```typescript
|
|
364
|
+
interface TestRunnerReport {
|
|
365
|
+
packageId: string
|
|
366
|
+
frontmatter?: FrontmatterValidationReport
|
|
367
|
+
admonitions?: AdmonitionValidationReport
|
|
368
|
+
codeLanguages?: CodeLanguageValidationReport
|
|
369
|
+
mdx?: MdxTestReport
|
|
370
|
+
totalErrors: number
|
|
371
|
+
totalTime: number
|
|
372
|
+
success: boolean
|
|
373
|
+
}
|
|
374
|
+
```
|
|
182
375
|
|
|
183
|
-
|
|
376
|
+
### FrontmatterError
|
|
184
377
|
|
|
185
378
|
```typescript
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
379
|
+
interface FrontmatterError {
|
|
380
|
+
file: string
|
|
381
|
+
absolutePath: string
|
|
382
|
+
issues: string[] // Zod validation issues
|
|
383
|
+
}
|
|
191
384
|
```
|
|
192
385
|
|
|
193
|
-
|
|
386
|
+
### FrontmatterValidationReport
|
|
194
387
|
|
|
195
388
|
```typescript
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
389
|
+
interface FrontmatterValidationReport {
|
|
390
|
+
packageId: string
|
|
391
|
+
filesScanned: number
|
|
392
|
+
errors: FrontmatterError[]
|
|
393
|
+
totalTime: number
|
|
394
|
+
}
|
|
201
395
|
```
|
|
202
396
|
|
|
203
|
-
###
|
|
204
|
-
|
|
205
|
-
Get the default plugins used for MDX compilation. Useful for extending the plugin list.
|
|
397
|
+
### AdmonitionError
|
|
206
398
|
|
|
207
399
|
```typescript
|
|
208
|
-
|
|
209
|
-
|
|
400
|
+
interface AdmonitionError {
|
|
401
|
+
file: string
|
|
402
|
+
absolutePath: string
|
|
403
|
+
line: number
|
|
404
|
+
column: number
|
|
405
|
+
content: string
|
|
406
|
+
admonitionType: string
|
|
407
|
+
label: string
|
|
408
|
+
suggestion: string
|
|
409
|
+
}
|
|
210
410
|
```
|
|
211
411
|
|
|
212
|
-
|
|
412
|
+
### AdmonitionValidationReport
|
|
213
413
|
|
|
214
414
|
```typescript
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
415
|
+
interface AdmonitionValidationReport {
|
|
416
|
+
packageId: string
|
|
417
|
+
filesScanned: number
|
|
418
|
+
errors: AdmonitionError[]
|
|
419
|
+
totalTime: number
|
|
420
|
+
}
|
|
421
|
+
```
|
|
221
422
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
423
|
+
### CodeLanguageError
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
interface CodeLanguageError {
|
|
427
|
+
file: string
|
|
428
|
+
absolutePath: string
|
|
429
|
+
line: number
|
|
430
|
+
language: string
|
|
431
|
+
content: string
|
|
432
|
+
suggestion?: string
|
|
433
|
+
}
|
|
226
434
|
```
|
|
227
435
|
|
|
228
|
-
|
|
436
|
+
### CodeLanguageValidationReport
|
|
437
|
+
|
|
438
|
+
```typescript
|
|
439
|
+
interface CodeLanguageValidationReport {
|
|
440
|
+
packageId: string
|
|
441
|
+
filesScanned: number
|
|
442
|
+
codeBlocksFound: number
|
|
443
|
+
errors: CodeLanguageError[]
|
|
444
|
+
totalTime: number
|
|
445
|
+
}
|
|
446
|
+
```
|
|
229
447
|
|
|
230
448
|
### MdxCompilationResult
|
|
231
449
|
|
|
232
450
|
```typescript
|
|
233
451
|
interface MdxCompilationResult {
|
|
234
|
-
/** Path to the MDX file that was compiled */
|
|
235
452
|
filePath: string
|
|
236
|
-
/** Whether compilation was successful */
|
|
237
453
|
success: boolean
|
|
238
|
-
/** Error message if compilation failed */
|
|
239
454
|
error?: string
|
|
240
|
-
/** Line number where the error occurred */
|
|
241
455
|
line?: number
|
|
242
|
-
/** Column number where the error occurred */
|
|
243
456
|
column?: number
|
|
244
|
-
/** Time taken to compile in milliseconds */
|
|
245
457
|
compilationTime: number
|
|
246
458
|
}
|
|
247
459
|
```
|
|
@@ -250,40 +462,74 @@ interface MdxCompilationResult {
|
|
|
250
462
|
|
|
251
463
|
```typescript
|
|
252
464
|
interface MdxTestReport {
|
|
253
|
-
/** Package ID from the manifest */
|
|
254
465
|
packageId: string
|
|
255
|
-
/** Total number of MDX files tested */
|
|
256
466
|
totalFiles: number
|
|
257
|
-
/** Number of files that compiled successfully */
|
|
258
467
|
passed: number
|
|
259
|
-
/** Number of files that failed to compile */
|
|
260
468
|
failed: number
|
|
261
|
-
/** Individual results for each file */
|
|
262
469
|
results: MdxCompilationResult[]
|
|
263
|
-
/** Total time taken in milliseconds */
|
|
264
470
|
totalTime: number
|
|
265
471
|
}
|
|
266
472
|
```
|
|
267
473
|
|
|
474
|
+
---
|
|
475
|
+
|
|
268
476
|
## Integration with Vitest
|
|
269
477
|
|
|
270
|
-
You can integrate
|
|
478
|
+
You can integrate documentation testing into your existing test suite:
|
|
271
479
|
|
|
272
480
|
```typescript
|
|
273
|
-
// tests/
|
|
481
|
+
// tests/docs-validation.test.ts
|
|
274
482
|
import { describe, it, expect } from 'vitest'
|
|
275
483
|
import { manifest } from '../src/manifest'
|
|
276
|
-
import {
|
|
484
|
+
import { runAllTests } from '@vendure-io/docs-provider/testing'
|
|
277
485
|
|
|
278
|
-
describe('
|
|
279
|
-
it('should
|
|
280
|
-
const report = await
|
|
486
|
+
describe('Documentation Validation', () => {
|
|
487
|
+
it('should pass all documentation tests', async () => {
|
|
488
|
+
const report = await runAllTests(manifest, {
|
|
489
|
+
exit: false,
|
|
490
|
+
silent: true,
|
|
491
|
+
})
|
|
281
492
|
|
|
282
|
-
expect(report.
|
|
493
|
+
expect(report.success).toBe(true)
|
|
283
494
|
}, 30000) // Increase timeout for large doc sets
|
|
284
495
|
})
|
|
285
496
|
```
|
|
286
497
|
|
|
498
|
+
Or test individual validators:
|
|
499
|
+
|
|
500
|
+
```typescript
|
|
501
|
+
import { describe, it, expect } from 'vitest'
|
|
502
|
+
import { manifest } from '../src/manifest'
|
|
503
|
+
import {
|
|
504
|
+
validateFrontmatter,
|
|
505
|
+
validateAdmonitions,
|
|
506
|
+
validateCodeLanguages,
|
|
507
|
+
testManifestMdx,
|
|
508
|
+
} from '@vendure-io/docs-provider/testing'
|
|
509
|
+
|
|
510
|
+
describe('Documentation Validation', () => {
|
|
511
|
+
it('should have valid frontmatter', () => {
|
|
512
|
+
const report = validateFrontmatter(manifest)
|
|
513
|
+
expect(report.errors).toHaveLength(0)
|
|
514
|
+
})
|
|
515
|
+
|
|
516
|
+
it('should use correct admonition syntax', () => {
|
|
517
|
+
const report = validateAdmonitions(manifest)
|
|
518
|
+
expect(report.errors).toHaveLength(0)
|
|
519
|
+
})
|
|
520
|
+
|
|
521
|
+
it('should use valid code languages', () => {
|
|
522
|
+
const report = validateCodeLanguages(manifest)
|
|
523
|
+
expect(report.errors).toHaveLength(0)
|
|
524
|
+
})
|
|
525
|
+
|
|
526
|
+
it('should compile all MDX files', async () => {
|
|
527
|
+
const report = await testManifestMdx(manifest)
|
|
528
|
+
expect(report.failed).toBe(0)
|
|
529
|
+
}, 30000)
|
|
530
|
+
})
|
|
531
|
+
```
|
|
532
|
+
|
|
287
533
|
## Supported MDX Features
|
|
288
534
|
|
|
289
535
|
The testing module uses the same remark/rehype plugins as the Vendure documentation website:
|
|
@@ -295,7 +541,7 @@ The testing module uses the same remark/rehype plugins as the Vendure documentat
|
|
|
295
541
|
This is an info callout.
|
|
296
542
|
:::
|
|
297
543
|
|
|
298
|
-
:::warning
|
|
544
|
+
:::warning[Custom Title]
|
|
299
545
|
This is a warning with a custom title.
|
|
300
546
|
:::
|
|
301
547
|
```
|
|
@@ -329,8 +575,148 @@ export function example() {
|
|
|
329
575
|
</Callout>
|
|
330
576
|
````
|
|
331
577
|
|
|
578
|
+
### Admonition Validation
|
|
579
|
+
|
|
580
|
+
Validates that admonitions use the correct bracket syntax required by remark-directive v4+.
|
|
581
|
+
|
|
582
|
+
```typescript
|
|
583
|
+
import { manifest } from './src/manifest'
|
|
584
|
+
import { validateAdmonitions, formatAdmonitionReport } from '@vendure-io/docs-provider/testing'
|
|
585
|
+
|
|
586
|
+
const report = validateAdmonitions(manifest)
|
|
587
|
+
|
|
588
|
+
if (report.errors.length > 0) {
|
|
589
|
+
console.error(formatAdmonitionReport(report))
|
|
590
|
+
process.exit(1)
|
|
591
|
+
}
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
**Valid syntax:**
|
|
595
|
+
|
|
596
|
+
```mdx
|
|
597
|
+
:::warning[Deprecated]
|
|
598
|
+
This feature is deprecated.
|
|
599
|
+
:::
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
**Invalid syntax (caught by validator):**
|
|
603
|
+
|
|
604
|
+
```mdx
|
|
605
|
+
:::warning Deprecated
|
|
606
|
+
This feature is deprecated.
|
|
607
|
+
:::
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
### Code Language Validation
|
|
611
|
+
|
|
612
|
+
Validates that code blocks use supported Shiki language identifiers.
|
|
613
|
+
|
|
614
|
+
```typescript
|
|
615
|
+
import { manifest } from './src/manifest'
|
|
616
|
+
import { validateCodeLanguages, formatCodeLanguageReport } from '@vendure-io/docs-provider/testing'
|
|
617
|
+
|
|
618
|
+
const report = validateCodeLanguages(manifest)
|
|
619
|
+
|
|
620
|
+
if (report.errors.length > 0) {
|
|
621
|
+
console.error(formatCodeLanguageReport(report))
|
|
622
|
+
process.exit(1)
|
|
623
|
+
}
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
**Options:**
|
|
627
|
+
|
|
628
|
+
| Option | Type | Default | Description |
|
|
629
|
+
| --------------------- | ------------------------ | ----------- | --------------------------------- |
|
|
630
|
+
| `failFast` | `boolean` | `false` | Stop on first error |
|
|
631
|
+
| `onError` | `Function` | `undefined` | Callback for each error found |
|
|
632
|
+
| `additionalAliases` | `Record<string, string>` | `{}` | Extra aliases to consider valid |
|
|
633
|
+
| `additionalLanguages` | `string[]` | `[]` | Extra languages to consider valid |
|
|
634
|
+
|
|
635
|
+
#### Utility Functions
|
|
636
|
+
|
|
637
|
+
**isValidCodeLanguage** - Check if a language identifier is valid:
|
|
638
|
+
|
|
639
|
+
```typescript
|
|
640
|
+
import { isValidCodeLanguage } from '@vendure-io/docs-provider/testing'
|
|
641
|
+
|
|
642
|
+
isValidCodeLanguage('typescript') // true
|
|
643
|
+
isValidCodeLanguage('ts') // true (alias)
|
|
644
|
+
isValidCodeLanguage('env') // true (maps to 'dotenv')
|
|
645
|
+
isValidCodeLanguage('foobar') // false
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
**getCanonicalLanguage** - Get the canonical Shiki language name:
|
|
649
|
+
|
|
650
|
+
```typescript
|
|
651
|
+
import { getCanonicalLanguage } from '@vendure-io/docs-provider/testing'
|
|
652
|
+
|
|
653
|
+
getCanonicalLanguage('env') // 'dotenv'
|
|
654
|
+
getCanonicalLanguage('text') // 'ini'
|
|
655
|
+
getCanonicalLanguage('terminal') // 'shellscript'
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
#### Common Language Issues
|
|
659
|
+
|
|
660
|
+
| Invalid | Use Instead | Notes |
|
|
661
|
+
| ----------- | ----------- | ---------------------------- |
|
|
662
|
+
| `env` | `dotenv` | For `.env` files |
|
|
663
|
+
| `text` | (none) | Remove language or use `ini` |
|
|
664
|
+
| `plaintext` | (none) | Remove language or use `ini` |
|
|
665
|
+
| `terminal` | `bash` | Or `shell`, `sh`, `zsh` |
|
|
666
|
+
|
|
667
|
+
#### Supported Languages
|
|
668
|
+
|
|
669
|
+
The validator includes all 328 languages bundled with Shiki v3.22+. Common languages include:
|
|
670
|
+
|
|
671
|
+
- **Web**: `html`, `css`, `javascript`, `typescript`, `jsx`, `tsx`, `json`, `yaml`
|
|
672
|
+
- **Backend**: `python`, `ruby`, `php`, `java`, `go`, `rust`, `csharp`
|
|
673
|
+
- **Shell**: `bash`, `shell`, `sh`, `zsh`, `powershell`
|
|
674
|
+
- **Config**: `ini`, `toml`, `dotenv`, `nginx`, `docker`
|
|
675
|
+
- **Data**: `sql`, `graphql`, `xml`, `csv`
|
|
676
|
+
- **Markup**: `markdown`, `mdx`, `latex`
|
|
677
|
+
|
|
678
|
+
See the full list at [shiki.style/languages](https://shiki.style/languages)
|
|
679
|
+
|
|
680
|
+
---
|
|
681
|
+
|
|
332
682
|
## Common Errors
|
|
333
683
|
|
|
684
|
+
### Missing or Invalid Frontmatter
|
|
685
|
+
|
|
686
|
+
The frontmatter validator catches:
|
|
687
|
+
|
|
688
|
+
- Missing `title` field (required)
|
|
689
|
+
- Invalid `lastModified` format (must be ISO 8601)
|
|
690
|
+
- Wrong types (e.g., `keywords` as string instead of array)
|
|
691
|
+
|
|
692
|
+
```mdx
|
|
693
|
+
---
|
|
694
|
+
title: My Page Title
|
|
695
|
+
description: Optional description
|
|
696
|
+
keywords:
|
|
697
|
+
- keyword1
|
|
698
|
+
- keyword2
|
|
699
|
+
---
|
|
700
|
+
|
|
701
|
+
# Content
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
### Invalid Admonition Syntax
|
|
705
|
+
|
|
706
|
+
```
|
|
707
|
+
:::warning Deprecated
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
Must use bracket syntax:
|
|
711
|
+
|
|
712
|
+
```
|
|
713
|
+
:::warning[Deprecated]
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
### Unsupported Code Language
|
|
717
|
+
|
|
718
|
+
Using `env` instead of `dotenv`, or `terminal` instead of `bash`.
|
|
719
|
+
|
|
334
720
|
### Unclosed JSX Tags
|
|
335
721
|
|
|
336
722
|
```
|
|
@@ -362,56 +748,46 @@ Check for:
|
|
|
362
748
|
- Unescaped special characters (`<`, `>`, `{`, `}`)
|
|
363
749
|
- JavaScript expressions not wrapped in curly braces
|
|
364
750
|
|
|
365
|
-
### Missing Frontmatter
|
|
366
|
-
|
|
367
|
-
While the MDX compiler doesn't require frontmatter, the docs website does. Ensure all files have at least a `title`:
|
|
368
|
-
|
|
369
|
-
```mdx
|
|
370
|
-
---
|
|
371
|
-
title: My Page Title
|
|
372
751
|
---
|
|
373
752
|
|
|
374
|
-
# Content
|
|
375
|
-
```
|
|
376
|
-
|
|
377
753
|
## Best Practices
|
|
378
754
|
|
|
379
|
-
1. **
|
|
380
|
-
2. **
|
|
381
|
-
3. **
|
|
382
|
-
4. **
|
|
755
|
+
1. **Use `runAllTests()` as your default** - It runs all validators and handles exit codes automatically
|
|
756
|
+
2. **Run tests before commits** - Add documentation testing to your pre-commit hooks
|
|
757
|
+
3. **Use CI/CD** - Include documentation testing in your continuous integration pipeline
|
|
758
|
+
4. **Test incrementally** - Use `failFast: true` during development for faster feedback
|
|
759
|
+
5. **Verbose output for debugging** - Use `verbose: true` when troubleshooting
|
|
383
760
|
|
|
384
|
-
|
|
761
|
+
---
|
|
385
762
|
|
|
386
|
-
|
|
763
|
+
## Complete Examples
|
|
764
|
+
|
|
765
|
+
### Minimal Test Script (Recommended)
|
|
387
766
|
|
|
388
767
|
```typescript
|
|
389
|
-
// scripts/test-
|
|
768
|
+
// scripts/test-docs.ts
|
|
390
769
|
import { manifest } from '../src/manifest'
|
|
391
|
-
import {
|
|
392
|
-
testManifestMdx,
|
|
393
|
-
formatTestReport,
|
|
394
|
-
createProgressReporter,
|
|
395
|
-
} from '@vendure-io/docs-provider/testing'
|
|
770
|
+
import { runAllTests } from '@vendure-io/docs-provider/testing'
|
|
396
771
|
|
|
397
|
-
|
|
398
|
-
|
|
772
|
+
runAllTests(manifest)
|
|
773
|
+
```
|
|
399
774
|
|
|
400
|
-
|
|
401
|
-
onProgress: createProgressReporter(),
|
|
402
|
-
})
|
|
775
|
+
Run with:
|
|
403
776
|
|
|
404
|
-
|
|
405
|
-
|
|
777
|
+
```bash
|
|
778
|
+
bun run scripts/test-docs.ts
|
|
779
|
+
```
|
|
406
780
|
|
|
407
|
-
|
|
408
|
-
process.exit(1)
|
|
409
|
-
}
|
|
410
|
-
}
|
|
781
|
+
### With Options
|
|
411
782
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
783
|
+
```typescript
|
|
784
|
+
// scripts/test-docs.ts
|
|
785
|
+
import { manifest } from '../src/manifest'
|
|
786
|
+
import { runAllTests } from '@vendure-io/docs-provider/testing'
|
|
787
|
+
|
|
788
|
+
runAllTests(manifest, {
|
|
789
|
+
verbose: process.argv.includes('--verbose'),
|
|
790
|
+
failFast: process.argv.includes('--fail-fast'),
|
|
415
791
|
})
|
|
416
792
|
```
|
|
417
793
|
|
|
@@ -419,8 +795,45 @@ Run with:
|
|
|
419
795
|
|
|
420
796
|
```bash
|
|
421
797
|
# Standard output
|
|
422
|
-
bun run scripts/test-
|
|
798
|
+
bun run scripts/test-docs.ts
|
|
423
799
|
|
|
424
800
|
# Verbose output showing all results
|
|
425
|
-
bun run scripts/test-
|
|
801
|
+
bun run scripts/test-docs.ts --verbose
|
|
802
|
+
|
|
803
|
+
# Stop on first error
|
|
804
|
+
bun run scripts/test-docs.ts --fail-fast
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
### Programmatic Usage
|
|
808
|
+
|
|
809
|
+
```typescript
|
|
810
|
+
// scripts/test-docs.ts
|
|
811
|
+
import { manifest } from '../src/manifest'
|
|
812
|
+
import { runAllTests, formatTestRunnerReport } from '@vendure-io/docs-provider/testing'
|
|
813
|
+
|
|
814
|
+
async function main() {
|
|
815
|
+
const report = await runAllTests(manifest, {
|
|
816
|
+
exit: false,
|
|
817
|
+
silent: true,
|
|
818
|
+
})
|
|
819
|
+
|
|
820
|
+
// Custom output
|
|
821
|
+
console.log(formatTestRunnerReport(report, true))
|
|
822
|
+
|
|
823
|
+
// Custom error handling
|
|
824
|
+
if (!report.success) {
|
|
825
|
+
console.error(`\nFailed with ${report.totalErrors} errors`)
|
|
826
|
+
|
|
827
|
+
if (report.frontmatter?.errors.length) {
|
|
828
|
+
console.error(`- ${report.frontmatter.errors.length} frontmatter errors`)
|
|
829
|
+
}
|
|
830
|
+
if (report.mdx?.failed) {
|
|
831
|
+
console.error(`- ${report.mdx.failed} MDX compilation errors`)
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
process.exit(1)
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
main()
|
|
426
839
|
```
|