11/**
22 * @typedef {import('unist').Node } Node
33 * @typedef {import('unist').Parent } Parent
4- * @typedef {string } Type
4+ */
5+
6+ /**
57 * @typedef {Record<string, unknown> } Props
6- * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array<Type|Props|TestFunctionAnything> } Test
8+ * @typedef {null | undefined | string | Props | TestFunctionAnything | Array<string | Props | TestFunctionAnything> } Test
9+ * Check for an arbitrary node, unaware of TypeScript inferral.
710 *
811 * @callback TestFunctionAnything
9- * Arbitrary function to define whether a node passes .
12+ * Check if a node passes a test, unaware of TypeScript inferral .
1013 * @param {unknown } this
11- * The to `is` given ` context`
14+ * The given context.
1215 * @param {Node } node
13- * Node to check.
14- * @param {number|null|undefined } [index]
15- * Index of `node` in `parent`.
16- * @param {Parent|null|undefined } [parent]
17- * Parent of `node`.
18- * @returns {boolean|void }
19- * Whether `node` matches.
20- *
21- * @callback AssertAnything
22- * Check if a node is an element and passes a certain node test.
23- * @param {unknown } [node]
24- * Thing to check and check that it’s a node.
25- * @param {number|null|undefined } [index]
26- * Index of `node` in `parent`.
27- * @param {Parent|null|undefined } [parent]
28- * Parent of `node`.
29- * @returns {boolean }
30- * Whether `node` matches.
16+ * A node.
17+ * @param {number | null | undefined } [index]
18+ * The node’s position in its parent.
19+ * @param {Parent | null | undefined } [parent]
20+ * The node’s parent.
21+ * @returns {boolean | void }
22+ * Whether this node passes the test.
3123 */
3224
3325/**
3426 * @template {Node} Kind
27+ * Node type.
28+ * @typedef {Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind> | Array<Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind>> } PredicateTest
29+ * Check for a node that can be inferred by TypeScript.
30+ */
31+
32+ /**
33+ * Check if a node passes a certain test.
34+ *
35+ * @template {Node} Kind
36+ * Node type.
3537 * @callback TestFunctionPredicate
36- * Arbitrary function to define whether a node passes, using a TypeScript type
37- * predicate.
38+ * Complex test function for a node that can be inferred by TypeScript.
3839 * @param {Node } node
39- * Node to check .
40- * @param {number| null| undefined } [index]
41- * Index of ` node` in ` parent` .
42- * @param {Parent| null| undefined } [parent]
43- * Parent of ` node` .
40+ * A node .
41+ * @param {number | null | undefined } [index]
42+ * The node’s position in its parent.
43+ * @param {Parent | null | undefined } [parent]
44+ * The node’s parent .
4445 * @returns {node is Kind }
45- * Whether `node` matches.
46+ * Whether this node passes the test.
47+ */
48+
49+ /**
50+ * @callback AssertAnything
51+ * Check that an arbitrary value is a node, unaware of TypeScript inferral.
52+ * @param {unknown } [node]
53+ * Anything (typically a node).
54+ * @param {number | null | undefined } [index]
55+ * The node’s position in its parent.
56+ * @param {Parent | null | undefined } [parent]
57+ * The node’s parent.
58+ * @returns {boolean }
59+ * Whether this is a node and passes a test.
4660 */
4761
4862/**
63+ * Check if a node is a node and passes a certain node test.
64+ *
4965 * @template {Node} Kind
66+ * Node type.
5067 * @callback AssertPredicate
51- * Check if a node is an element and passes a certain node test, using a
52- * TypeScript type predicate.
68+ * Check that an arbitrary value is a specific node, aware of TypeScript.
5369 * @param {unknown } [node]
54- * Thing to check and check that it’s a node.
55- * @param {number| null| undefined } [index]
56- * Index of ` node` in ` parent` .
57- * @param {Parent| null| undefined } [parent]
58- * Parent of ` node` .
70+ * Anything (typically a node) .
71+ * @param {number | null | undefined } [index]
72+ * The node’s position in its parent.
73+ * @param {Parent | null | undefined } [parent]
74+ * The node’s parent .
5975 * @returns {node is Kind }
60- * Whether ` node` matches .
76+ * Whether this is a node and passes a test .
6177 */
6278
6379/**
64- * Check if `node` passes a test.
65- * When a `parent` node is given the `index` of node should also be given.
80+ * Check if `node` is a `Node` and whether it passes the given test.
6681 *
6782 * @param node
68- * Node to check, can be anything .
83+ * Thing to check, typically `Node` .
6984 * @param test
70- * * when nullish, checks if `node` is a `Node`.
71- * * when `string`, works like passing `(node) => node.type === test`.
72- * * when `array`, checks any one of the subtests pass.
73- * * when `object`, checks that all keys in test are in node, and that they have (strictly) equal values.
74- * * when `function` checks if function passed the node is true.
85+ * A check for a specific node.
7586 * @param index
76- * Position of ` node` in `parent`, must be a number if ` parent` is also given .
87+ * The node’s position in its parent.
7788 * @param parent
78- * Parent of `node`, must be given if `index` is also given.
79- * @param context
80- * Context object to call `test` with
89+ * The node’s parent.
8190 * @returns
82- * Whether test passed and `node` is a `Node` (object with `type` set to
83- * non-empty `string`).
91+ * Whether `node` is a node and passes a test.
8492 */
8593export const is =
8694 /**
8795 * @type {(
88- * (<Kind extends Node>(node: unknown, test: Kind['type']|Partial<Kind>|TestFunctionPredicate<Kind>|Array<Kind['type']|Partial<Kind>|TestFunctionPredicate<Kind>>, index: number, parent: Parent, context?: unknown) => node is Kind) &
89- * (<Kind extends Node>(node: unknown, test: Kind['type']|Partial<Kind>|TestFunctionPredicate<Kind>|Array<Kind['type']|Partial<Kind>|TestFunctionPredicate<Kind>>, index?: null|undefined, parent?: null|undefined, context?: unknown) => node is Kind) &
96+ * (() => false) &
97+ * (<Kind extends Node = Node>(node: unknown, test: PredicateTest<Kind>, index: number, parent: Parent, context?: unknown) => node is Kind) &
98+ * (<Kind extends Node = Node>(node: unknown, test: PredicateTest<Kind>, index?: null | undefined, parent?: null | undefined, context?: unknown) => node is Kind) &
9099 * ((node: unknown, test: Test, index: number, parent: Parent, context?: unknown) => boolean) &
91- * ((node? : unknown, test?: Test, index?: null| undefined, parent?: null| undefined, context?: unknown) => boolean)
100+ * ((node: unknown, test?: Test, index?: null | undefined, parent?: null | undefined, context?: unknown) => boolean)
92101 * )}
93102 */
94103 (
95104 /**
96105 * @param {unknown } [node]
97106 * @param {Test } [test]
98- * @param {number| null| undefined } [index]
99- * @param {Parent| null| undefined } [parent]
107+ * @param {number | null | undefined } [index]
108+ * @param {Parent | null | undefined } [parent]
100109 * @param {unknown } [context]
101110 * @returns {boolean }
102111 */
@@ -137,28 +146,27 @@ export const is =
137146 )
138147
139148/**
140- * Create a test function from `test` that can later be called with a `node`,
141- * `index`, and `parent`.
149+ * Generate an assertion from a test.
150+ *
142151 * Useful if you’re going to test many nodes, for example when creating a
143- * utility where something else passes an is- compatible test.
152+ * utility where something else passes a compatible test.
144153 *
145- * The created function is slightly faster that using `is` because it expects
146- * valid input only.
147- * Therefore, passing invalid input yields unexpected results.
154+ * The created function is a bit faster because it expects valid input only:
155+ * a `node`, `index`, and `parent`.
148156 *
149157 * @param test
150158 * * when nullish, checks if `node` is a `Node`.
151159 * * when `string`, works like passing `(node) => node.type === test`.
152- * * when `array`, checks any one of the subtests pass.
153- * * when `object`, checks that all keys in test are in node, and that they have (strictly) equal values.
154160 * * when `function` checks if function passed the node is true.
161+ * * when `object`, checks that all keys in test are in node, and that they have (strictly) equal values.
162+ * * when `array`, checks if any one of the subtests pass.
155163 * @returns
156- * Check function that can be called as `check(node, index, parent)` .
164+ * An assertion .
157165 */
158166export const convert =
159167 /**
160168 * @type {(
161- * (<Kind extends Node>(test: Kind['type']|Partial<Kind>|TestFunctionPredicate <Kind>) => AssertPredicate<Kind>) &
169+ * (<Kind extends Node>(test: PredicateTest <Kind>) => AssertPredicate<Kind>) &
162170 * ((test?: Test) => AssertAnything)
163171 * )}
164172 */
@@ -189,7 +197,7 @@ export const convert =
189197 )
190198
191199/**
192- * @param {Array<Type| Props| TestFunctionAnything> } tests
200+ * @param {Array<string | Props | TestFunctionAnything> } tests
193201 * @returns {AssertAnything }
194202 */
195203function anyFactory ( tests ) {
@@ -220,8 +228,7 @@ function anyFactory(tests) {
220228}
221229
222230/**
223- * Assert each field in `test` is present in `node` and each values are strictly
224- * equal.
231+ * Turn an object into a test for a node with a certain fields.
225232 *
226233 * @param {Props } check
227234 * @returns {AssertAnything }
@@ -247,10 +254,9 @@ function propsFactory(check) {
247254}
248255
249256/**
250- * Convert a string into a function which checks a given node’s type
251- * for said string.
257+ * Turn a string into a test for a node with a certain type.
252258 *
253- * @param {Type } check
259+ * @param {string } check
254260 * @returns {AssertAnything }
255261 */
256262function typeFactory ( check ) {
@@ -265,8 +271,7 @@ function typeFactory(check) {
265271}
266272
267273/**
268- * Convert a string into a function which checks a given node’s type
269- * for said string.
274+ * Turn a custom test into a test for a node that passes that test.
270275 *
271276 * @param {TestFunctionAnything } check
272277 * @returns {AssertAnything }
@@ -276,12 +281,18 @@ function castFactory(check) {
276281
277282 /**
278283 * @this {unknown}
284+ * @param {unknown } node
279285 * @param {Array<unknown> } parameters
280286 * @returns {boolean }
281287 */
282- function assertion ( ...parameters ) {
283- // @ts -expect-error: spreading is fine.
284- return Boolean ( check . call ( this , ...parameters ) )
288+ function assertion ( node , ...parameters ) {
289+ return Boolean (
290+ node &&
291+ typeof node === 'object' &&
292+ 'type' in node &&
293+ // @ts -expect-error: fine.
294+ Boolean ( check . call ( this , node , ...parameters ) )
295+ )
285296 }
286297}
287298
0 commit comments