diff --git a/package.json b/package.json index 6d2c16d..87d1eae 100644 --- a/package.json +++ b/package.json @@ -34,11 +34,12 @@ "convert.d.ts" ], "types": "index.d.ts", - "dependencies": {}, "devDependencies": { "@types/mdast": "^3.0.0", "browserify": "^17.0.0", "dtslint": "^4.0.0", + "fast-check": "^2.0.0", + "lodash": "^4.0.0", "nyc": "^15.0.0", "prettier": "^2.0.0", "remark-cli": "^9.0.0", @@ -54,7 +55,7 @@ "build-mangle": "browserify . -s unistUtilIs -o unist-util-is.min.js -p tinyify", "build": "npm run build-bundle && npm run build-mangle", "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", + "test-coverage": "nyc --reporter lcov tape test", "test-types": "dtslint .", "test": "npm run format && npm run build && npm run test-coverage && npm run test-types" }, diff --git a/test/index.js b/test/index.js new file mode 100644 index 0000000..e68ff32 --- /dev/null +++ b/test/index.js @@ -0,0 +1,3 @@ +/* eslint-disable import/no-unassigned-import */ +require('./main') +require('./property') diff --git a/test.js b/test/main.js similarity index 99% rename from test.js rename to test/main.js index ab6b275..d23baf4 100644 --- a/test.js +++ b/test/main.js @@ -1,7 +1,7 @@ 'use strict' var test = require('tape') -var is = require('.') +var is = require('..') test('unist-util-is', function (t) { var node = {type: 'strong'} diff --git a/test/property.js b/test/property.js new file mode 100644 index 0000000..c1bc69a --- /dev/null +++ b/test/property.js @@ -0,0 +1,80 @@ +'use strict' + +const test = require('tape') +const fc = require('fast-check') +const {isObject, isPlainObject, pick, cloneDeep} = require('lodash') +const is = require('..') + +test('unist-util-is properties', (t) => { + t.plan(4) + t.doesNotThrow( + () => + fc.assert( + fc.property(fc.record({type: fc.string({minLength: 1})}), (node) => + is(node) + ) + ), + 'should see any object w/ a non-empty `type` as a node' + ) + + t.doesNotThrow( + () => + fc.assert( + fc.property( + fc + .unicodeJsonObject() + .filter( + (node) => !(isPlainObject(node) && typeof node.type === 'string') + ), + (node) => !is(node) + ) + ), + 'should see any object w/o a `type` as a non-node' + ) + + t.doesNotThrow( + () => + fc.assert( + fc.property(fc.record({type: fc.string({minLength: 1})}), (node) => + is(node, node.type) + ) + ), + 'should match types' + ) + + t.doesNotThrow( + () => + fc.assert( + fc.property( + fc + .unicodeJsonObject() + // Filter for JSON objects which unist can work with + .filter( + (node) => + isPlainObject(node) && + Object.keys(node).some((key) => !isObject(node[key])) + ) + // Return node and a list with a random subset of its primitive value keys + .chain((node) => + fc.tuple( + fc.constant(node), + fc.subarray( + Object.keys(node).filter((key) => !isObject(node[key])), + {minLength: 1} + ) + ) + ), + fc.string({minLength: 1}), + (nodeAndKeys, type) => { + const nodeProperties = nodeAndKeys[0] + const keys = nodeAndKeys[1] + + const node = {...nodeProperties, type: type} + const subsetOfNode = pick(cloneDeep(node), keys) + return is(node, subsetOfNode) + } + ) + ), + 'should match partially' + ) +})