Skip to content

Commit bd97123

Browse files
Add fuzzed property tests
Closes GH-17.
1 parent 18bbf90 commit bd97123

File tree

4 files changed

+87
-3
lines changed

4 files changed

+87
-3
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@
3434
"convert.d.ts"
3535
],
3636
"types": "index.d.ts",
37-
"dependencies": {},
3837
"devDependencies": {
3938
"@types/mdast": "^3.0.0",
4039
"browserify": "^17.0.0",
4140
"dtslint": "^4.0.0",
41+
"fast-check": "^2.0.0",
42+
"lodash": "^4.0.0",
4243
"nyc": "^15.0.0",
4344
"prettier": "^2.0.0",
4445
"remark-cli": "^9.0.0",
@@ -54,7 +55,7 @@
5455
"build-mangle": "browserify . -s unistUtilIs -o unist-util-is.min.js -p tinyify",
5556
"build": "npm run build-bundle && npm run build-mangle",
5657
"test-api": "node test",
57-
"test-coverage": "nyc --reporter lcov tape test.js",
58+
"test-coverage": "nyc --reporter lcov tape test",
5859
"test-types": "dtslint .",
5960
"test": "npm run format && npm run build && npm run test-coverage && npm run test-types"
6061
},

test/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/* eslint-disable import/no-unassigned-import */
2+
require('./main')
3+
require('./property')

test.js renamed to test/main.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict'
22

33
var test = require('tape')
4-
var is = require('.')
4+
var is = require('..')
55

66
test('unist-util-is', function (t) {
77
var node = {type: 'strong'}

test/property.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
'use strict'
2+
3+
const test = require('tape')
4+
const fc = require('fast-check')
5+
const {isObject, isPlainObject, pick, cloneDeep} = require('lodash')
6+
const is = require('..')
7+
8+
test('unist-util-is properties', (t) => {
9+
t.plan(4)
10+
t.doesNotThrow(
11+
() =>
12+
fc.assert(
13+
fc.property(fc.record({type: fc.string({minLength: 1})}), (node) =>
14+
is(node)
15+
)
16+
),
17+
'should see any object w/ a non-empty `type` as a node'
18+
)
19+
20+
t.doesNotThrow(
21+
() =>
22+
fc.assert(
23+
fc.property(
24+
fc
25+
.unicodeJsonObject()
26+
.filter(
27+
(node) => !(isPlainObject(node) && typeof node.type === 'string')
28+
),
29+
(node) => !is(node)
30+
)
31+
),
32+
'should see any object w/o a `type` as a non-node'
33+
)
34+
35+
t.doesNotThrow(
36+
() =>
37+
fc.assert(
38+
fc.property(fc.record({type: fc.string({minLength: 1})}), (node) =>
39+
is(node, node.type)
40+
)
41+
),
42+
'should match types'
43+
)
44+
45+
t.doesNotThrow(
46+
() =>
47+
fc.assert(
48+
fc.property(
49+
fc
50+
.unicodeJsonObject()
51+
// Filter for JSON objects which unist can work with
52+
.filter(
53+
(node) =>
54+
isPlainObject(node) &&
55+
Object.keys(node).some((key) => !isObject(node[key]))
56+
)
57+
// Return node and a list with a random subset of its primitive value keys
58+
.chain((node) =>
59+
fc.tuple(
60+
fc.constant(node),
61+
fc.subarray(
62+
Object.keys(node).filter((key) => !isObject(node[key])),
63+
{minLength: 1}
64+
)
65+
)
66+
),
67+
fc.string({minLength: 1}),
68+
(nodeAndKeys, type) => {
69+
const nodeProperties = nodeAndKeys[0]
70+
const keys = nodeAndKeys[1]
71+
72+
const node = {...nodeProperties, type: type}
73+
const subsetOfNode = pick(cloneDeep(node), keys)
74+
return is(node, subsetOfNode)
75+
}
76+
)
77+
),
78+
'should match partially'
79+
)
80+
})

0 commit comments

Comments
 (0)