nodejs/tools/doc/deprecationCodes.mjs

93 lines
2.5 KiB
JavaScript

import fs from 'fs';
import { resolve } from 'path';
import assert from 'assert';
import { unified } from 'unified';
import remarkParse from 'remark-parse';
const source = resolve(process.argv[2]);
const skipDeprecationComment = /^<!-- md-lint skip-deprecation (DEP\d{4}) -->$/;
const generateDeprecationCode = (codeAsNumber) =>
`DEP${codeAsNumber.toString().padStart(4, '0')}`;
const addMarkdownPathToErrorStack = (error, node) => {
const { line, column } = node.position.start;
const [header, ...lines] = error.stack.split('\n');
error.stack =
header +
`\n at <anonymous> (${source}:${line}:${column})\n` +
lines.join('\n');
return error;
};
const testHeading = (headingNode, expectedDeprecationCode) => {
try {
assert.strictEqual(
headingNode?.children[0]?.value.substring(0, 9),
`${expectedDeprecationCode}: `,
'Ill-formed or out-of-order deprecation code.',
);
} catch (e) {
throw addMarkdownPathToErrorStack(e, headingNode);
}
};
const testYAMLComment = (commentNode) => {
try {
assert.match(
commentNode?.value?.substring(0, 21),
/^<!-- YAML\r?\nchanges:\r?\n/,
'Missing or ill-formed YAML comment.',
);
} catch (e) {
throw addMarkdownPathToErrorStack(e, commentNode);
}
};
const testDeprecationType = (paragraphNode) => {
try {
assert.strictEqual(
paragraphNode?.children[0]?.value?.substring(0, 6),
'Type: ',
'Missing deprecation type.',
);
} catch (e) {
throw addMarkdownPathToErrorStack(e, paragraphNode);
}
};
const tree = unified()
.use(remarkParse)
.parse(fs.readFileSync(source));
let expectedDeprecationCodeNumber = 0;
for (let i = 0; i < tree.children.length; i++) {
const node = tree.children[i];
if (node.type === 'html' && skipDeprecationComment.test(node.value)) {
const expectedDeprecationCode =
generateDeprecationCode(++expectedDeprecationCodeNumber);
const deprecationCodeAsText = node.value.match(skipDeprecationComment)[1];
try {
assert.strictEqual(
deprecationCodeAsText,
expectedDeprecationCode,
'Deprecation codes are not ordered correctly.',
);
} catch (e) {
throw addMarkdownPathToErrorStack(e, node);
}
}
if (node.type === 'heading' && node.depth === 3) {
const expectedDeprecationCode =
generateDeprecationCode(++expectedDeprecationCodeNumber);
testHeading(node, expectedDeprecationCode);
testYAMLComment(tree.children[i + 1]);
testDeprecationType(tree.children[i + 2]);
}
}