|
| 1 | +import * as common from '../common/index.mjs'; |
| 2 | + |
| 3 | +import assert from 'assert'; |
| 4 | +import fs from 'fs'; |
| 5 | +import path from 'path'; |
| 6 | + |
| 7 | +if (common.isWindows) { |
| 8 | + common.skip('`make doc` does not run on Windows'); |
| 9 | +} |
| 10 | + |
| 11 | +// This tests that `make doc` generates the documentation properly. |
| 12 | +// Note that for this test to pass, `make doc` must be run first. |
| 13 | + |
| 14 | +const apiURL = new URL('../../out/doc/api/', import.meta.url); |
| 15 | +const mdURL = new URL('../../doc/api/', import.meta.url); |
| 16 | +const allMD = fs.readdirSync(mdURL); |
| 17 | +const allDocs = fs.readdirSync(apiURL); |
| 18 | +assert.ok(allDocs.includes('index.html')); |
| 19 | + |
| 20 | +const actualDocs = allDocs.filter( |
| 21 | + (name) => { |
| 22 | + const extension = path.extname(name); |
| 23 | + return extension === '.html' || extension === '.json'; |
| 24 | + }, |
| 25 | +); |
| 26 | + |
| 27 | +for (const name of actualDocs) { |
| 28 | + if (name.startsWith('all.') || name === 'apilinks.json') continue; |
| 29 | + |
| 30 | + assert.ok( |
| 31 | + allMD.includes(name.replace(/\.\w+$/, '.md')), |
| 32 | + `Unexpected output: out/doc/api/${name}, remove and rerun.`, |
| 33 | + ); |
| 34 | +} |
| 35 | + |
| 36 | +const toc = fs.readFileSync(new URL('./index.html', apiURL), 'utf8'); |
| 37 | +const re = /href=("([^/]+\.html)"|([^/]+\.html))/; |
| 38 | +const globalRe = new RegExp(re, 'g'); |
| 39 | +const links = toc.match(globalRe); |
| 40 | +assert.notStrictEqual(links, null); |
| 41 | + |
| 42 | +// Filter out duplicate links, leave just filenames, add expected JSON files. |
| 43 | +const linkedHtmls = [...new Set(links)].map((link) => link.match(re)[1]) |
| 44 | + .concat(['index.html']); |
| 45 | +const expectedJsons = linkedHtmls |
| 46 | + .map((name) => name.replace('.html', '.json')); |
| 47 | +const expectedDocs = linkedHtmls.concat(expectedJsons); |
| 48 | +const renamedDocs = ['policy.json', 'policy.html']; |
| 49 | +const skipedDocs = ['dtls.json', 'dtls.html', 'quic.json', 'quic.html']; |
| 50 | + |
| 51 | +// Test that all the relative links in the TOC match to the actual documents. |
| 52 | +for (const expectedDoc of expectedDocs) { |
| 53 | + if (skipedDocs.includes(expectedDoc)) continue; |
| 54 | + assert.ok(actualDocs.includes(expectedDoc), `${expectedDoc} does not exist`); |
| 55 | +} |
| 56 | + |
| 57 | +// Test that all the actual documents match to the relative links in the TOC |
| 58 | +// and that they are not empty files. |
| 59 | +for (const actualDoc of actualDocs) { |
| 60 | + // When renaming the documentation, the old url is lost |
| 61 | + // Unless the old file is still available pointing to the correct location |
| 62 | + // 301 redirects are not yet automated. So keeping the old URL is a |
| 63 | + // reasonable workaround. |
| 64 | + if (renamedDocs.includes(actualDoc) || skipedDocs.includes(actualDoc) || |
| 65 | + actualDoc === 'apilinks.json') continue; |
| 66 | + assert.ok( |
| 67 | + expectedDocs.includes(actualDoc), `${actualDoc} does not match TOC`); |
| 68 | + |
| 69 | + assert.notStrictEqual( |
| 70 | + fs.statSync(new URL(`./${actualDoc}`, apiURL)).size, |
| 71 | + 0, |
| 72 | + `${actualDoc} is empty`, |
| 73 | + ); |
| 74 | +} |
0 commit comments