diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 13be4219488c04..329d1f3f9915df 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -3534,13 +3534,13 @@ changes: calculations with them. --> +> Stability: 0 - Deprecated: Use [`buf.subarray`][] instead. + * `start` {integer} Where the new `Buffer` will start. **Default:** `0`. * `end` {integer} Where the new `Buffer` will end (not inclusive). **Default:** [`buf.length`][]. * Returns: {Buffer} -> Stability: 0 - Deprecated: Use [`buf.subarray`][] instead. - Returns a new `Buffer` that references the same memory as the original, but offset and cropped by the `start` and `end` indexes. diff --git a/doc/api/environment_variables.md b/doc/api/environment_variables.md index 114287251f91a2..6e114c1b9dcce7 100644 --- a/doc/api/environment_variables.md +++ b/doc/api/environment_variables.md @@ -18,10 +18,10 @@ For more details refer to the [`process.env` documentation][]. ## DotEnv -Set of utilities for dealing with additional environment variables defined in `.env` files. - > Stability: 2 - Stable +Set of utilities for dealing with additional environment variables defined in `.env` files. + ### .env files `.env` files (also known as dotenv files) are files that define environment variables, diff --git a/test/doctool/test-stability-block-position.mjs b/test/doctool/test-stability-block-position.mjs new file mode 100644 index 00000000000000..d1bd509cd2bd93 --- /dev/null +++ b/test/doctool/test-stability-block-position.mjs @@ -0,0 +1,52 @@ +import '../common/index.mjs'; + +import fs from 'fs'; +import assert from 'assert'; + +import { + remarkParse, + unified, +} from '../../tools/doc/deps.mjs'; + +const ignore = ['deprecations.md', 'documentation.md']; + +const docURL = new URL('../../doc/api/', import.meta.url); +const docList = fs.readdirSync(docURL).filter((filename) => !ignore.includes(filename)); + +const re = /^Stability: \d/; + +for (const file of docList) { + const fileURL = new URL(file, docURL); + const tree = unified() + .use(remarkParse) + .parse(fs.readFileSync(fileURL)); + + // Traverse first-level nodes, ignoring comment blocks + const nodes = tree.children.filter((node) => node.type !== 'html'); + + for (let i = 0; i < nodes.length; i++) { + const { [i]: node, [i - 1]: previousNode } = nodes; + if (node.type !== 'blockquote' || !node.children.length) continue; + + const paragraph = node.children[0]; + if (paragraph.type !== 'paragraph' || !paragraph.children.length) continue; + + const text = paragraph.children[0]; + if (text.type !== 'text' || !re.exec(text.value)) continue; + + // Check that previous node type (excluding comment blocks) is one of: + // * 'heading' + // * 'paragraph' with a leading 'strong' node (pseudo-heading, eg. assert.equal) + try { + assert(previousNode.type === 'heading' || + (previousNode.type === 'paragraph' && previousNode.children[0]?.type === 'strong'), + 'Stability block must be the first content element under heading'); + } catch (error) { + const { line, column } = node.position.start; + error.stack = error.stack.split('\n') + .toSpliced(1, 0, ` at ${fileURL}:${line}:${column}`) + .join('\n'); + throw error; + } + } +}