Skip to content

Commit 64847d8

Browse files
authored
test: guard the API reference style conventions
Signed-off-by: Nazmul Hossain <bilashcse@gmail.com>
1 parent 54e2053 commit 64847d8

1 file changed

Lines changed: 73 additions & 0 deletions

File tree

tests/unit/api-docs-style.test.mjs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import assert from 'node:assert/strict';
2+
import { readFileSync, readdirSync } from 'node:fs';
3+
import { dirname, join, relative, resolve } from 'node:path';
4+
import { test } from 'node:test';
5+
import { fileURLToPath } from 'node:url';
6+
7+
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
8+
const API_ROOT = join(ROOT, 'src', 'content', 'api');
9+
const VERSIONS = ['4x', '5x'];
10+
11+
function collectMdx(dir) {
12+
return readdirSync(dir, { withFileTypes: true }).flatMap((entry) => {
13+
const full = join(dir, entry.name);
14+
if (entry.isDirectory()) return collectMdx(full);
15+
return entry.name.endsWith('.mdx') ? [full] : [];
16+
});
17+
}
18+
19+
function findOffendingLines(isOffending) {
20+
const offenders = [];
21+
for (const file of VERSIONS.flatMap((version) => collectMdx(join(API_ROOT, version)))) {
22+
readFileSync(file, 'utf8')
23+
.split('\n')
24+
.forEach((line, index) => {
25+
if (isOffending(line)) {
26+
offenders.push(`${relative(ROOT, file)}:${index + 1} ${line.trim()}`);
27+
}
28+
});
29+
}
30+
return offenders;
31+
}
32+
33+
test('result comments quote string values with single quotes', () => {
34+
const offenders = findOffendingLines(
35+
(line) => /^\s*\/\/\s*=>.*"/.test(line) && !line.includes('{')
36+
);
37+
assert.deepEqual(offenders, []);
38+
});
39+
40+
test('result comments do not end with stray punctuation', () => {
41+
const offenders = findOffendingLines((line) => /^\s*\/\/\s*=>.*[:;,]\s*$/.test(line));
42+
assert.deepEqual(offenders, []);
43+
});
44+
45+
test('req.host is documented before req.hostname', () => {
46+
for (const version of VERSIONS) {
47+
const file = join(API_ROOT, version, 'api', 'request', 'index.mdx');
48+
const content = readFileSync(file, 'utf8');
49+
const host = content.indexOf('### req.host\n');
50+
const hostname = content.indexOf('### req.hostname\n');
51+
assert.notEqual(host, -1, `req.host heading is missing in ${version}`);
52+
assert.notEqual(hostname, -1, `req.hostname heading is missing in ${version}`);
53+
assert.ok(host < hostname, `req.host should precede req.hostname in ${version}`);
54+
}
55+
});
56+
57+
test('request and response pages describe themselves as req and res', () => {
58+
const pages = [
59+
['request', 'req'],
60+
['response', 'res'],
61+
];
62+
for (const version of VERSIONS) {
63+
for (const [page, name] of pages) {
64+
const file = join(API_ROOT, version, 'api', page, 'index.mdx');
65+
const description = readFileSync(file, 'utf8').match(/^description: (.*)$/m);
66+
assert.ok(description, `${version}/${page} has no description`);
67+
assert.ok(
68+
description[1].startsWith(`The ${name} object represents`),
69+
`${version}/${page} description should start with 'The ${name} object represents'`
70+
);
71+
}
72+
}
73+
});

0 commit comments

Comments
 (0)