Skip to content

Commit c3801b3

Browse files
authored
Add is.convert to convert a test to a function
Useful for reuse. Closes GH-5. Closes GH-7.
1 parent fc7a034 commit c3801b3

File tree

4 files changed

+128
-85
lines changed

4 files changed

+128
-85
lines changed

convert.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
'use strict'
2+
3+
module.exports = convert
4+
5+
function convert(test) {
6+
if (typeof test === 'string') {
7+
return typeFactory(test)
8+
}
9+
10+
if (test === null || test === undefined) {
11+
return ok
12+
}
13+
14+
if (typeof test === 'object') {
15+
return ('length' in test ? anyFactory : matchesFactory)(test)
16+
}
17+
18+
if (typeof test === 'function') {
19+
return test
20+
}
21+
22+
throw new Error('Expected function, string, or object as test')
23+
}
24+
25+
function convertAll(tests) {
26+
var results = []
27+
var length = tests.length
28+
var index = -1
29+
30+
while (++index < length) {
31+
results[index] = convert(tests[index])
32+
}
33+
34+
return results
35+
}
36+
37+
// Utility assert each property in `test` is represented in `node`, and each
38+
// values are strictly equal.
39+
function matchesFactory(test) {
40+
return matches
41+
42+
function matches(node) {
43+
var key
44+
45+
for (key in test) {
46+
if (node[key] !== test[key]) {
47+
return false
48+
}
49+
}
50+
51+
return true
52+
}
53+
}
54+
55+
function anyFactory(tests) {
56+
var checks = convertAll(tests)
57+
var length = checks.length
58+
59+
return matches
60+
61+
function matches() {
62+
var index = -1
63+
64+
while (++index < length) {
65+
if (checks[index].apply(this, arguments)) {
66+
return true
67+
}
68+
}
69+
70+
return false
71+
}
72+
}
73+
74+
// Utility to convert a string into a function which checks a given node’s type
75+
// for said string.
76+
function typeFactory(test) {
77+
return type
78+
79+
function type(node) {
80+
return Boolean(node && node.type === test)
81+
}
82+
}
83+
84+
// Utility to return true.
85+
function ok() {
86+
return true
87+
}

index.js

Lines changed: 4 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
'use strict'
22

3+
var convert = require('./convert')
4+
35
module.exports = is
46

7+
is.convert = convert
8+
59
// Assert if `test` passes for `node`. When a `parent` node is known the
610
// `index` of node.
711
// eslint-disable-next-line max-params
@@ -31,87 +35,3 @@ function is(test, node, index, parent, context) {
3135

3236
return Boolean(check.call(context, node, index, parent))
3337
}
34-
35-
function convert(test) {
36-
if (typeof test === 'string') {
37-
return typeFactory(test)
38-
}
39-
40-
if (test === null || test === undefined) {
41-
return ok
42-
}
43-
44-
if (typeof test === 'object') {
45-
return ('length' in test ? anyFactory : matchesFactory)(test)
46-
}
47-
48-
if (typeof test === 'function') {
49-
return test
50-
}
51-
52-
throw new Error('Expected function, string, or object as test')
53-
}
54-
55-
function convertAll(tests) {
56-
var results = []
57-
var length = tests.length
58-
var index = -1
59-
60-
while (++index < length) {
61-
results[index] = convert(tests[index])
62-
}
63-
64-
return results
65-
}
66-
67-
// Utility assert each property in `test` is represented in `node`, and each
68-
// values are strictly equal.
69-
function matchesFactory(test) {
70-
return matches
71-
72-
function matches(node) {
73-
var key
74-
75-
for (key in test) {
76-
if (node[key] !== test[key]) {
77-
return false
78-
}
79-
}
80-
81-
return true
82-
}
83-
}
84-
85-
function anyFactory(tests) {
86-
var checks = convertAll(tests)
87-
var length = checks.length
88-
89-
return matches
90-
91-
function matches() {
92-
var index = -1
93-
94-
while (++index < length) {
95-
if (checks[index].apply(this, arguments)) {
96-
return true
97-
}
98-
}
99-
100-
return false
101-
}
102-
}
103-
104-
// Utility to convert a string into a function which checks a given node’s type
105-
// for said string.
106-
function typeFactory(test) {
107-
return type
108-
109-
function type(node) {
110-
return Boolean(node && node.type === test)
111-
}
112-
}
113-
114-
// Utility to return true.
115-
function ok() {
116-
return true
117-
}

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
2121
],
2222
"files": [
23-
"index.js"
23+
"index.js",
24+
"convert.js"
2425
],
2526
"dependencies": {},
2627
"devDependencies": {

readme.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,41 @@ with `type` set to a non-empty `string`).
8383

8484
`boolean?` — Whether `node` matches.
8585

86+
### `is.convert(test)`
87+
88+
Create a test function from `test`, that can later be called with a `node`,
89+
`index`, and `parent`.
90+
Useful if you’re going to test many nodes, for example when creating a utility
91+
where something else passes an is-compatible test.
92+
93+
Can also be accessed with `require('unist-util-is/convert')`.
94+
95+
For example:
96+
97+
```js
98+
var u = require('unist-builder')
99+
var convert = require('unist-util-is/convert')
100+
101+
var test = convert('leaf')
102+
103+
var tree = u('tree', [
104+
u('node', [u('leaf', '1')]),
105+
u('leaf', '2'),
106+
u('node', [u('leaf', '3'), u('leaf', '4')]),
107+
u('leaf', '5')
108+
])
109+
110+
var leafs = tree.children.filter((child, index) => test(child, index, tree))
111+
112+
console.log(leafs)
113+
```
114+
115+
Yields:
116+
117+
```js
118+
[({type: 'leaf', value: '2'}, {type: 'leaf', value: '5'})]
119+
```
120+
86121
## Related
87122

88123
* [`unist-util-find-after`](https://github.com/syntax-tree/unist-util-find-after)

0 commit comments

Comments
 (0)