diff --git a/src/utils/queries/__tests__/index.test.mjs b/src/utils/queries/__tests__/index.test.mjs index 36f0b1a1..e04a5d5c 100644 --- a/src/utils/queries/__tests__/index.test.mjs +++ b/src/utils/queries/__tests__/index.test.mjs @@ -110,4 +110,114 @@ describe('createQueries', () => { }; queries.addStabilityMetadata(node, apiEntryMetadata); }); + + describe('UNIST', () => { + describe('isTypedList', () => { + it('returns false for non-list nodes', () => { + strictEqual( + createQueries.UNIST.isTypedList({ type: 'paragraph', children: [] }), + false + ); + }); + + it('returns false for empty lists', () => { + strictEqual( + createQueries.UNIST.isTypedList({ type: 'list', children: [] }), + false + ); + }); + + const cases = [ + { + name: 'typedListStarters pattern match', + node: { + type: 'list', + children: [ + { + children: [ + { + children: [{ type: 'text', value: 'Returns: foo' }], + }, + ], + }, + ], + }, + expected: true, + }, + { + name: 'direct type link pattern', + node: { + type: 'list', + children: [ + { + children: [ + { + children: [ + { + type: 'link', + children: [{ type: 'inlineCode', value: '' }], + }, + ], + }, + ], + }, + ], + }, + expected: true, + }, + { + name: 'inlineCode + space + type link pattern', + node: { + type: 'list', + children: [ + { + children: [ + { + children: [ + { type: 'inlineCode', value: 'foo' }, + { type: 'text', value: ' ' }, + { + type: 'link', + children: [{ type: 'text', value: '' }], + }, + ], + }, + ], + }, + ], + }, + expected: true, + }, + { + name: 'non-matching content', + node: { + type: 'list', + children: [ + { + children: [ + { + children: [ + { type: 'inlineCode', value: 'not a valid prop' }, + { type: 'text', value: ' ' }, + { + type: 'link', + children: [{ type: 'text', value: '' }], + }, + ], + }, + ], + }, + ], + }, + expected: false, + }, + ]; + + cases.forEach(({ name, node, expected }) => { + it(`returns ${expected} for ${name}`, () => { + strictEqual(createQueries.UNIST.isTypedList(node), expected); + }); + }); + }); + }); }); diff --git a/src/utils/queries/constants.mjs b/src/utils/queries/constants.mjs index 4e6a22b9..88537e2f 100644 --- a/src/utils/queries/constants.mjs +++ b/src/utils/queries/constants.mjs @@ -3,3 +3,5 @@ // This is the perma-link within the API docs that reference the Stability Index export const DOC_API_STABILITY_SECTION_REF_URL = 'documentation.html#stability-index'; + +export const VALID_JAVASCRIPT_PROPERTY = /^[.a-z0-9$_]+$/i; diff --git a/src/utils/queries/index.mjs b/src/utils/queries/index.mjs index 76810097..b6300d9a 100644 --- a/src/utils/queries/index.mjs +++ b/src/utils/queries/index.mjs @@ -3,7 +3,10 @@ import { u as createTree } from 'unist-builder'; import { SKIP } from 'unist-util-visit'; -import { DOC_API_STABILITY_SECTION_REF_URL } from './constants.mjs'; +import { + DOC_API_STABILITY_SECTION_REF_URL, + VALID_JAVASCRIPT_PROPERTY, +} from './constants.mjs'; import { extractYamlContent, parseHeadingIntoMetadata, @@ -278,15 +281,15 @@ createQueries.UNIST = { const [node, ...contentNodes] = list?.children?.[0]?.children?.[0]?.children ?? []; - // Exit if no content nodes + // Exit if no node if (!node) { return false; } + const possibleProperty = node?.value?.trimStart(); + // Check for other starters - if ( - node.value?.trimStart().match(createQueries.QUERIES.typedListStarters) - ) { + if (possibleProperty?.match(createQueries.QUERIES.typedListStarters)) { return true; } @@ -298,7 +301,8 @@ createQueries.UNIST = { // Check for inline code + space + type link pattern if ( node.type === 'inlineCode' && - contentNodes[0]?.value.trim() === '' && + possibleProperty?.match(VALID_JAVASCRIPT_PROPERTY) && + contentNodes[0]?.value?.trim() === '' && contentNodes[1]?.type === 'link' && contentNodes[1]?.children?.[0]?.value?.[0] === '<' ) {