diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ee318ca..fb63387 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -17,5 +17,5 @@ jobs: strategy: matrix: node: - - lts/hydrogen + - lts/gallium - node diff --git a/.npmrc b/.npmrc index 9951b11..3757b30 100644 --- a/.npmrc +++ b/.npmrc @@ -1,2 +1,2 @@ -package-lock=false ignore-scripts=true +package-lock=false diff --git a/index.test-d.ts b/index.test-d.ts index e1b4525..6f606cd 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,6 +1,6 @@ -import {expectType, expectNotType} from 'tsd' +import {expectNotType, expectType} from 'tsd' import type {Node, Parent} from 'unist' -import {assert, parent} from './index.js' +import {assert, parent} from 'unist-util-assert' const emptyNode = {type: 'a'} const literalNode = {type: 'b', value: 'c'} diff --git a/lib/index.js b/lib/index.js index dbdcd71..fcf3cee 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,12 +1,22 @@ /** - * @typedef {import('assert').AssertionError} AssertionError - * Assertion error from `node:assert`. + * @typedef {import('node:assert').AssertionError} AssertionError * + * @typedef {import('unist').Literal} Literal * @typedef {import('unist').Node} Node * @typedef {import('unist').Parent} Parent - * @typedef {import('unist').Literal} Literal - * @typedef {import('unist').Position} Position * @typedef {import('unist').Point} Point + * @typedef {import('unist').Position} Position + */ + +/** + * @template T + * @callback CustomAssertion + * @param {any} [node] + * @param {Parent | null | undefined} [parent] + * @returns {asserts node is T} + */ + +/** * @typedef {Node & {children: never, value: never}} _Void * * @typedef SeenErrorFields @@ -16,7 +26,7 @@ */ import nodeAssert from 'node:assert' -import {inspect} from './inspect.js' +import {inspect} from 'unist-util-assert/do-not-use-conditional-inspect' const own = {}.hasOwnProperty @@ -100,9 +110,9 @@ const defined = new Set(['type', 'value', 'children', 'position']) * * @template {Node} T * Node type. - * @param {(node?: any, parent?: Parent | null | undefined) => asserts node is T} fn + * @param {CustomAssertion} fn * Custom assertion. - * @returns {(node?: any, parent?: Parent | null | undefined) => asserts node is T} + * @returns {CustomAssertion} * Assertion. */ export function wrap(fn) { @@ -115,7 +125,7 @@ export function wrap(fn) { * Optional, valid parent. * @throws {AssertionError} * Whether `node` is a node but neither parent nor literal. - * @returns {void} + * @returns {undefined} * Nothing. */ function wrapped(node, parent) { @@ -153,28 +163,24 @@ function assertNode(node) { node && typeof node === 'object' && !Array.isArray(node), 'node should be an object' ) + indexable(node) nodeAssert.ok(own.call(node, 'type'), 'node should have a type') nodeAssert.strictEqual( - // @ts-expect-error Looks like an indexed object. typeof node.type, 'string', '`type` should be a string' ) - // @ts-expect-error Looks like an indexed object. nodeAssert.notStrictEqual(node.type, '', '`type` should not be empty') - // @ts-expect-error Looks like an indexed object. if (node.value !== null && node.value !== undefined) { nodeAssert.strictEqual( - // @ts-expect-error Looks like an indexed object. typeof node.value, 'string', '`value` should be a string' ) } - // @ts-expect-error Looks like an indexed object. position(node.position) /** @type {string} */ @@ -182,14 +188,11 @@ function assertNode(node) { for (key in node) { if (!defined.has(key)) { - /** @type {unknown} */ - // @ts-expect-error: hush. const value = node[key] vanilla(key, value) } } - // @ts-expect-error Looks like an indexed object. if (node.children !== null && node.children !== undefined) { /** @type {Parent} */ // @ts-expect-error Looks like parent. @@ -324,9 +327,8 @@ function position(position) { '`position` should be an object' ) - // @ts-expect-error: indexable. + indexable(position) point(position.start, 'position.start') - // @ts-expect-error: indexable. point(position.end, 'position.end') } } @@ -374,3 +376,22 @@ function point(point, label) { } } } + +/** + * TypeScript helper to check if something is indexable (any object is + * indexable in JavaScript). + * + * @param {unknown} value + * Thing to check. + * @returns {asserts value is Record} + * Nothing. + * @throws {Error} + * When `value` is not an object. + */ +function indexable(value) { + // Always called when something is an object, this is just for TS. + /* c8 ignore next 3 */ + if (!value || typeof value !== 'object') { + throw new Error('Expected object') + } +} diff --git a/lib/inspect.browser.js b/lib/inspect.default.js similarity index 100% rename from lib/inspect.browser.js rename to lib/inspect.default.js diff --git a/lib/inspect.js b/lib/inspect.node.js similarity index 100% rename from lib/inspect.js rename to lib/inspect.node.js diff --git a/package.json b/package.json index 9ecb287..6e7b325 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "unist-util-assert", - "version": "3.0.2", + "version": "4.0.0", "description": "unist utility to assert nodes", "license": "MIT", "keywords": [ @@ -24,65 +24,74 @@ ], "sideEffects": false, "type": "module", - "main": "index.js", - "browser": { - "./lib/inspect.js": "./lib/inspect.browser.js" + "exports": { + ".": "./index.js", + "./do-not-use-conditional-inspect": { + "node": "./lib/inspect.node.js", + "default": "./lib/inspect.default.js" + } }, - "react-native": { - "./lib/inspect.js": "./lib/inspect.browser.js" - }, - "types": "index.d.ts", "files": [ "lib/", "index.d.ts", "index.js" ], "dependencies": { - "@types/unist": "^2.0.0" + "@types/unist": "^3.0.0" }, "devDependencies": { - "@types/node": "^18.0.0", - "c8": "^7.0.0", + "@types/node": "^20.0.0", + "c8": "^8.0.0", "prettier": "^2.0.0", "remark-cli": "^11.0.0", "remark-preset-wooorm": "^9.0.0", - "tsd": "^0.25.0", + "tsd": "^0.28.0", "type-coverage": "^2.0.0", - "typescript": "^4.0.0", - "xo": "^0.53.0" + "typescript": "^5.0.0", + "xo": "^0.54.0" }, "scripts": { "prepack": "npm run build && npm run format", "build": "tsc --build --clean && tsc --build && tsd && type-coverage", "format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", "test-api": "node --conditions development test/index.js", - "test-coverage": "c8 --check-coverage --100 --reporter lcov npm run test-api", + "test-coverage": "c8 --100 --reporter lcov npm run test-api", "test": "npm run build && npm run format && npm run test-coverage" }, "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, "bracketSpacing": false, "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "none", + "useTabs": false }, "remarkConfig": { "plugins": [ - "preset-wooorm" + "remark-preset-wooorm" ] }, "typeCoverage": { "atLeast": 100, "detail": true, - "strict": true, "ignoreCatch": true, - "#": "Couple of needed any’s", + "#": "Couple of needed any’s", "ignoreFiles": [ "lib/index.d.ts" - ] + ], + "strict": true + }, + "xo": { + "overrides": [ + { + "files": [ + "test/**/*.js" + ], + "rules": { + "import/no-unassigned-import": "off" + } + } + ], + "prettier": true } } diff --git a/readme.md b/readme.md index 384f48b..50c4b55 100644 --- a/readme.md +++ b/readme.md @@ -46,7 +46,7 @@ do the same but for mdast, hast, and nlcst nodes, respectively. ## Install This package is [ESM only][esm]. -In Node.js (version 14.14+ and 16.0+), install with [npm][]: +In Node.js (version 16+), install with [npm][]: ```sh npm install unist-util-assert @@ -55,21 +55,21 @@ npm install unist-util-assert In Deno with [`esm.sh`][esmsh]: ```js -import {assert} from 'https://esm.sh/unist-util-assert@3' +import {assert} from 'https://esm.sh/unist-util-assert@4' ``` In browsers with [`esm.sh`][esmsh]: ```html ``` ## Use ```js -import {assert, parent, _void} from 'unist-util-assert' +import {_void, assert, parent} from 'unist-util-assert' assert({type: 'root', children: []}) assert({type: 'break'}) @@ -218,10 +218,13 @@ It exports the additional type [`AssertionError`][assertionerror]. ## Compatibility -Projects maintained by the unified collective are compatible with all maintained +Projects maintained by the unified collective are compatible with maintained versions of Node.js. -As of now, that is Node.js 14.14+ and 16.0+. -Our projects sometimes work with older versions, but this is not guaranteed. + +When we cut a new major release, we drop support for unmaintained versions of +Node. +This means we try to keep the current release line, `unist-util-assert@^4`, +compatible with Node.js 16. ## Related @@ -260,9 +263,9 @@ abide by its terms. [downloads]: https://www.npmjs.com/package/unist-util-assert -[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-assert.svg +[size-badge]: https://img.shields.io/badge/dynamic/json?label=minzipped%20size&query=$.size.compressedSize&url=https://deno.bundlejs.com/?q=unist-util-assert -[size]: https://bundlephobia.com/result?p=unist-util-assert +[size]: https://bundlejs.com/?q=unist-util-assert [sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg diff --git a/test/children.js b/test/children.js index 6a8e27c..6068376 100644 --- a/test/children.js +++ b/test/children.js @@ -1,30 +1,34 @@ import nodeAssert from 'node:assert/strict' import test from 'node:test' -import {assert} from '../index.js' +import {assert} from 'unist-util-assert' -test('children', () => { - nodeAssert.throws( - () => { - assert({type: 'foo', children: {alpha: 'bravo'}}) - }, - /`children` should be an array: `{ type: 'foo', children: { alpha: 'bravo' } }`$/, - 'should throw if given a non-node child in children' +test('children', async function (t) { + await t.test( + 'should throw if given a non-node child in children', + async function () { + nodeAssert.throws(function () { + assert({type: 'foo', children: {alpha: 'bravo'}}) + }, /`children` should be an array: `{ type: 'foo', children: { alpha: 'bravo' } }`$/) + } ) - nodeAssert.throws( - () => { - assert({type: 'foo', children: ['one']}) - }, - /node should be an object: `'one'` in `{ type: 'foo', children: \[ 'one' ] }`$/, - 'should throw if given a non-node child in children' + await t.test( + 'should throw if given a non-node child in children', + async function () { + nodeAssert.throws(function () { + assert({type: 'foo', children: ['one']}) + }, /node should be an object: `'one'` in `{ type: 'foo', children: \[ 'one' ] }`$/) + } ) - nodeAssert.doesNotThrow(() => { - assert({type: 'parent', children: [{type: 'text', value: 'alpha'}]}) - }, 'should not throw on vald children') + await t.test('should not throw on vald children', async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'parent', children: [{type: 'text', value: 'alpha'}]}) + }) + }) - nodeAssert.throws( - () => { + await t.test('should throw on invalid descendants', async function () { + nodeAssert.throws(function () { assert({ type: 'foo', children: [ @@ -34,8 +38,6 @@ test('children', () => { } ] }) - }, - /node should be an object: `'one'` in `{ type: 'bar', children: \[ 'one' ] }`$/, - 'should throw on invalid descendants' - ) + }, /node should be an object: `'one'` in `{ type: 'bar', children: \[ 'one' ] }`$/) + }) }) diff --git a/test/core.js b/test/core.js new file mode 100644 index 0000000..62126ee --- /dev/null +++ b/test/core.js @@ -0,0 +1,14 @@ +import assert from 'node:assert/strict' +import test from 'node:test' + +test('assert', async function (t) { + await t.test('should expose the public api', async function () { + assert.deepEqual(Object.keys(await import('unist-util-assert')).sort(), [ + '_void', + 'assert', + 'literal', + 'parent', + 'wrap' + ]) + }) +}) diff --git a/test/index.js b/test/index.js index 4f863a5..c9ea1b8 100644 --- a/test/index.js +++ b/test/index.js @@ -1,23 +1,10 @@ -/* eslint-disable import/no-unassigned-import */ -import './node.js' -import './type.js' -import './value.js' import './children.js' -import './position.js' +import './core.js' +import './literal.js' +import './node.js' import './non-defined.js' import './parent.js' -import './literal.js' +import './position.js' +import './type.js' +import './value.js' import './void.js' -/* eslint-enable import/no-unassigned-import */ - -import assert from 'node:assert/strict' -import test from 'node:test' -import * as mod from '../index.js' - -test('assert', () => { - assert.deepEqual( - Object.keys(mod).sort(), - ['_void', 'assert', 'literal', 'parent', 'wrap'], - 'should expose the public api' - ) -}) diff --git a/test/literal.js b/test/literal.js index b0c11fd..c9d737d 100644 --- a/test/literal.js +++ b/test/literal.js @@ -1,33 +1,35 @@ import assert from 'node:assert/strict' import test from 'node:test' -import {literal} from '../index.js' +import {literal} from 'unist-util-assert' -test('literal()', () => { - assert.throws( - () => { +test('literal()', async function (t) { + await t.test('should throw the same errors as `assert()`', async function () { + assert.throws(function () { literal({}) - }, - /node should have a type: `{}`$/, - 'should throw the same errors as `assert()`' - ) + }, /node should have a type: `{}`$/) + }) - assert.throws( - () => { - literal({type: 'strong', children: []}) - }, - /literal should not have `children`: `{ type: 'strong', children: \[] }`$/, - 'should throw if the given node has `children`' + await t.test( + 'should throw if the given node has `children`', + async function () { + assert.throws(function () { + literal({type: 'strong', children: []}) + }, /literal should not have `children`: `{ type: 'strong', children: \[] }`$/) + } ) - assert.throws( - () => { - literal({type: 'break'}) - }, - /literal should have `value`: `{ type: 'break' }`$/, - 'should throw if the given node has no `value`' + await t.test( + 'should throw if the given node has no `value`', + async function () { + assert.throws(function () { + literal({type: 'break'}) + }, /literal should have `value`: `{ type: 'break' }`$/) + } ) - assert.doesNotThrow(() => { - literal({type: 'text', value: 'foo'}) - }, 'should not throw on valid text nodes') + await t.test('should not throw on valid text nodes', async function () { + assert.doesNotThrow(function () { + literal({type: 'text', value: 'foo'}) + }) + }) }) diff --git a/test/node.js b/test/node.js index f9da6d6..e9d9e84 100644 --- a/test/node.js +++ b/test/node.js @@ -1,37 +1,29 @@ import nodeAssert from 'node:assert/strict' import test from 'node:test' -import {assert} from '../index.js' +import {assert} from 'unist-util-assert' -test('node', () => { - nodeAssert.throws( - () => { +test('node', async function (t) { + await t.test('should throw if not given a node (#1)', async function () { + nodeAssert.throws(function () { assert() - }, - /node should be an object: `undefined`$/, - 'should throw if not given a node (#1)' - ) + }, /node should be an object: `undefined`$/) + }) - nodeAssert.throws( - () => { + await t.test('should throw if not given a node (#2)', async function () { + nodeAssert.throws(function () { assert(null) - }, - /node should be an object: `null`$/, - 'should throw if not given a node (#2)' - ) + }, /node should be an object: `null`$/) + }) - nodeAssert.throws( - () => { + await t.test('should throw if given a non-node (#1)', async function () { + nodeAssert.throws(function () { assert('foo') - }, - /node should be an object: `'foo'`$/, - 'should throw if given a non-node (#1)' - ) + }, /node should be an object: `'foo'`$/) + }) - nodeAssert.throws( - () => { + await t.test('should throw if not given a non-node (#2)', async function () { + nodeAssert.throws(function () { assert(6) - }, - /node should be an object: `6`$/, - 'should throw if not given a non-node (#2)' - ) + }, /node should be an object: `6`$/) + }) }) diff --git a/test/non-defined.js b/test/non-defined.js index abe7431..95c99fc 100644 --- a/test/non-defined.js +++ b/test/non-defined.js @@ -1,31 +1,37 @@ import nodeAssert from 'node:assert/strict' import test from 'node:test' -import {assert} from '../index.js' +import {assert} from 'unist-util-assert' -test('non-defined', () => { - nodeAssert.doesNotThrow(() => { - assert({ - type: 'element', - properties: { - className: ['alpha'], - id: 'bravo' - }, - children: [], - position: {}, - data: { - charlie: 'delta' - } - }) - }, 'should not throw if non-defined properties are found') - - nodeAssert.throws( - () => { - assert({ - type: 'break', - data: {foo: Function} +test('non-defined', async function (t) { + await t.test( + 'should not throw if non-defined properties are found', + async function () { + nodeAssert.doesNotThrow(function () { + assert({ + type: 'element', + properties: { + className: ['alpha'], + id: 'bravo' + }, + children: [], + position: {}, + data: { + charlie: 'delta' + } + }) }) - }, - /non-specced property `data` should be JSON: `{ type: 'break', data: { foo: \[Function: Function] } }`$/, - 'should throw if non-defined properties are not serialisable' + } + ) + + await t.test( + 'should throw if non-defined properties are not serialisable', + async function () { + nodeAssert.throws(function () { + assert({ + type: 'break', + data: {foo: Function} + }) + }, /non-specced property `data` should be JSON: `{ type: 'break', data: { foo: \[Function: Function] } }`$/) + } ) }) diff --git a/test/parent.js b/test/parent.js index c247a19..511d7d0 100644 --- a/test/parent.js +++ b/test/parent.js @@ -1,33 +1,35 @@ import assert from 'node:assert/strict' import test from 'node:test' -import {parent} from '../index.js' +import {parent} from 'unist-util-assert' -test('parent()', () => { - assert.throws( - () => { +test('parent()', async function (t) { + await t.test('should throw the same errors as `assert()`', async function () { + assert.throws(function () { parent({}) - }, - /node should have a type: `{}`$/, - 'should throw the same errors as `assert()`' - ) + }, /node should have a type: `{}`$/) + }) - assert.throws( - () => { - parent({type: 'text', value: 'foo'}) - }, - /parent should not have `value`: `{ type: 'text', value: 'foo' }`$/, - 'should throw if the given node has a `value`' + await t.test( + 'should throw if the given node has a `value`', + async function () { + assert.throws(function () { + parent({type: 'text', value: 'foo'}) + }, /parent should not have `value`: `{ type: 'text', value: 'foo' }`$/) + } ) - assert.throws( - () => { - parent({type: 'break'}) - }, - /parent should have `children`: `{ type: 'break' }`$/, - 'should throw if the given node has `children`' + await t.test( + 'should throw if the given node has `children`', + async function () { + assert.throws(function () { + parent({type: 'break'}) + }, /parent should have `children`: `{ type: 'break' }`$/) + } ) - assert.doesNotThrow(() => { - parent({type: 'strong', children: []}) - }, 'should not throw on valid void nodes') + await t.test('should not throw on valid void nodes', async function () { + assert.doesNotThrow(function () { + parent({type: 'strong', children: []}) + }) + }) }) diff --git a/test/position.js b/test/position.js index 7c09655..c687359 100644 --- a/test/position.js +++ b/test/position.js @@ -1,101 +1,158 @@ import nodeAssert from 'node:assert/strict' import test from 'node:test' -import {assert} from '../index.js' - -test('position', () => { - nodeAssert.throws( - () => { - assert({type: 'foo', position: 1}) - }, - /`position` should be an object: `{ type: 'foo', position: 1 }`$/, - 'should throw if given a non-object `position`' - ) - - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', position: null}) - }, 'should not throw if given a null `position`') - - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', position: {}}) - }, 'should not throw if given an empty `position` object') - - nodeAssert.throws( - () => { - assert({type: 'foo', position: {start: 1}}) - }, - /`position.start` should be an object: `{ type: 'foo', position: { start: 1 } }`$/, - 'should throw if given a non-object `position.start`' - ) - - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', position: {start: null}}) - }, 'should not throw if given a null `position.start`') - - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', position: {start: {}}}) - }, 'should not throw if given an empty `position.start` object') - - nodeAssert.throws( - () => { - assert({type: 'foo', position: {end: 1}}) - }, - /`position.end` should be an object: `{ type: 'foo', position: { end: 1 } }`$/, - 'should throw if given a non-object `position.end`' - ) - - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', position: {end: null}}) - }, 'should not throw if given a null `position.end`') - - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', position: {end: {}}}) - }, 'should not throw if given an empty `position.end` object') - - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', position: {start: {line: null}}}) - }, 'should not throw if given a `position.start.line` to `null`') - - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', position: {start: {column: null}}}) - }, 'should not throw if given a `position.start.column` to `null`') - - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', position: {end: {line: null}}}) - }, 'should not throw if given a `position.end.line` to `null`') - - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', position: {end: {column: null}}}) - }, 'should not throw if given a `position.end.column` to `null`') - - nodeAssert.throws( - () => { - assert({type: 'foo', position: {start: {line: 0}}}) - }, - /`position.start.line` should be gte `1`: `{ type: 'foo', position: { start: { line: 0 } } }`$/, - 'should throw if `position.start.line` is less than 1' - ) - - nodeAssert.throws( - () => { - assert({type: 'foo', position: {start: {column: 0}}}) - }, - /`position.start.column` should be gte `1`: `{ type: 'foo', position: { start: { column: 0 } } }`$/, - 'should throw if `position.start.column` is less than 1' - ) - - nodeAssert.throws( - () => { - assert({type: 'foo', position: {end: {line: 0}}}) - }, - /`position.end.line` should be gte `1`: `{ type: 'foo', position: { end: { line: 0 } } }`$/, - 'should throw if `position.end.line` is less than 1' - ) - - nodeAssert.throws( - () => { - assert({type: 'foo', position: {end: {column: 0}}}) - }, - /`position.end.column` should be gte `1`: `{ type: 'foo', position: { end: { column: 0 } } }`$/, - 'should throw if `position.end.column` is less than 1' +import {assert} from 'unist-util-assert' + +test('position', async function (t) { + await t.test( + 'should throw if given a non-object `position`', + async function () { + nodeAssert.throws(function () { + assert({type: 'foo', position: 1}) + }, /`position` should be an object: `{ type: 'foo', position: 1 }`$/) + } + ) + + await t.test( + 'should not throw if given a null `position`', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', position: null}) + }) + } + ) + + await t.test( + 'should not throw if given an empty `position` object', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', position: {}}) + }) + } + ) + + await t.test( + 'should throw if given a non-object `position.start`', + async function () { + nodeAssert.throws(function () { + assert({type: 'foo', position: {start: 1}}) + }, /`position.start` should be an object: `{ type: 'foo', position: { start: 1 } }`$/) + } + ) + + await t.test( + 'should not throw if given a null `position.start`', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', position: {start: null}}) + }) + } + ) + + await t.test( + 'should not throw if given an empty `position.start` object', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', position: {start: {}}}) + }) + } + ) + + await t.test( + 'should throw if given a non-object `position.end`', + async function () { + nodeAssert.throws(function () { + assert({type: 'foo', position: {end: 1}}) + }, /`position.end` should be an object: `{ type: 'foo', position: { end: 1 } }`$/) + } + ) + + await t.test( + 'should not throw if given a null `position.end`', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', position: {end: null}}) + }) + } + ) + + await t.test( + 'should not throw if given an empty `position.end` object', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', position: {end: {}}}) + }) + } + ) + + await t.test( + 'should not throw if given a `position.start.line` to `null`', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', position: {start: {line: null}}}) + }) + } + ) + + await t.test( + 'should not throw if given a `position.start.column` to `null`', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', position: {start: {column: null}}}) + }) + } + ) + + await t.test( + 'should not throw if given a `position.end.line` to `null`', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', position: {end: {line: null}}}) + }) + } + ) + + await t.test( + 'should not throw if given a `position.end.column` to `null`', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', position: {end: {column: null}}}) + }) + } + ) + + await t.test( + 'should throw if `position.start.line` is less than 1', + async function () { + nodeAssert.throws(function () { + assert({type: 'foo', position: {start: {line: 0}}}) + }, /`position.start.line` should be gte `1`: `{ type: 'foo', position: { start: { line: 0 } } }`$/) + } + ) + + await t.test( + 'should throw if `position.start.column` is less than 1', + async function () { + nodeAssert.throws(function () { + assert({type: 'foo', position: {start: {column: 0}}}) + }, /`position.start.column` should be gte `1`: `{ type: 'foo', position: { start: { column: 0 } } }`$/) + } + ) + + await t.test( + 'should throw if `position.end.line` is less than 1', + async function () { + nodeAssert.throws(function () { + assert({type: 'foo', position: {end: {line: 0}}}) + }, /`position.end.line` should be gte `1`: `{ type: 'foo', position: { end: { line: 0 } } }`$/) + } + ) + + await t.test( + 'should throw if `position.end.column` is less than 1', + async function () { + nodeAssert.throws(function () { + assert({type: 'foo', position: {end: {column: 0}}}) + }, /`position.end.column` should be gte `1`: `{ type: 'foo', position: { end: { column: 0 } } }`$/) + } ) }) diff --git a/test/type.js b/test/type.js index 52e2afd..d59e7d1 100644 --- a/test/type.js +++ b/test/type.js @@ -1,41 +1,41 @@ import nodeAssert from 'node:assert/strict' import test from 'node:test' -import {assert} from '../index.js' +import {assert} from 'unist-util-assert' -test('type', () => { - nodeAssert.throws( - () => { +test('type', async function (t) { + await t.test('should throw if not given a `type` (#1)', async function () { + nodeAssert.throws(function () { assert({}) - }, - /node should have a type: `{}`$/, - 'should throw if not given a `type` (#1)' - ) + }, /node should have a type: `{}`$/) + }) - nodeAssert.throws( - () => { + await t.test('should throw if not given a type (#2)', async function () { + nodeAssert.throws(function () { assert({value: 'foo'}) - }, - /node should have a type: `{ value: 'foo' }`$/, - 'should throw if not given a type (#2)' - ) + }, /node should have a type: `{ value: 'foo' }`$/) + }) - nodeAssert.throws( - () => { - assert({type: 1}) - }, - /`type` should be a string: `{ type: 1 }`$/, - 'should throw if not given a non-string type' + await t.test( + 'should throw if not given a non-string type', + async function () { + nodeAssert.throws(function () { + assert({type: 1}) + }, /`type` should be a string: `{ type: 1 }`$/) + } ) - nodeAssert.throws( - () => { + await t.test('should throw if given an empty string type', async function () { + nodeAssert.throws(function () { assert({type: ''}) - }, - /`type` should not be empty: `{ type: '' }`$/, - 'should throw if given an empty string type' - ) + }, /`type` should not be empty: `{ type: '' }`$/) + }) - nodeAssert.doesNotThrow(() => { - assert({type: 'foo'}) - }, 'should not throw if given a non-empty type string') + await t.test( + 'should not throw if given a non-empty type string', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo'}) + }) + } + ) }) diff --git a/test/value.js b/test/value.js index f2f50e5..9afbc9f 100644 --- a/test/value.js +++ b/test/value.js @@ -1,29 +1,44 @@ import nodeAssert from 'node:assert/strict' import test from 'node:test' -import {assert} from '../index.js' +import {assert} from 'unist-util-assert' -test('value', () => { - nodeAssert.throws( - () => { +test('value', async function (t) { + await t.test('should throw if given a non-string `value`', async function () { + nodeAssert.throws(function () { assert({type: 'foo', value: 1}) - }, - /`value` should be a string: `{ type: 'foo', value: 1 }`$/, - 'should throw if given a non-string `value`' - ) + }, /`value` should be a string: `{ type: 'foo', value: 1 }`$/) + }) - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', value: ''}) - }, 'should not throw if given an empty string `value`') + await t.test( + 'should not throw if given an empty string `value`', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', value: ''}) + }) + } + ) - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', value: 'foo'}) - }, 'should not throw if given an string `value`') + await t.test( + 'should not throw if given an string `value`', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', value: 'foo'}) + }) + } + ) - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', value: undefined}) - }, 'should not throw if given an undefined `value`') + await t.test( + 'should not throw if given an undefined `value`', + async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', value: undefined}) + }) + } + ) - nodeAssert.doesNotThrow(() => { - assert({type: 'foo', value: null}) - }, 'should not throw if given an null `value`') + await t.test('should not throw if given an null `value`', async function () { + nodeAssert.doesNotThrow(function () { + assert({type: 'foo', value: null}) + }) + }) }) diff --git a/test/void.js b/test/void.js index 7384f2c..d358bea 100644 --- a/test/void.js +++ b/test/void.js @@ -1,33 +1,35 @@ import assert from 'node:assert/strict' import test from 'node:test' -import {_void} from '../index.js' +import {_void} from 'unist-util-assert' -test('_void()', () => { - assert.throws( - () => { +test('_void()', async function (t) { + await t.test('should throw the same errors as `assert()`', async function () { + assert.throws(function () { _void({}) - }, - /node should have a type: `{}`$/, - 'should throw the same errors as `assert()`' - ) + }, /node should have a type: `{}`$/) + }) - assert.throws( - () => { - _void({type: 'text', value: 'foo'}) - }, - /void should not have `value`: `{ type: 'text', value: 'foo' }`$/, - 'should throw if the given node has a `value`' + await t.test( + 'should throw if the given node has a `value`', + async function () { + assert.throws(function () { + _void({type: 'text', value: 'foo'}) + }, /void should not have `value`: `{ type: 'text', value: 'foo' }`$/) + } ) - assert.throws( - () => { - _void({type: 'strong', children: []}) - }, - /void should not have `children`: `{ type: 'strong', children: \[] }`$/, - 'should throw if the given node has `children`' + await t.test( + 'should throw if the given node has `children`', + async function () { + assert.throws(function () { + _void({type: 'strong', children: []}) + }, /void should not have `children`: `{ type: 'strong', children: \[] }`$/) + } ) - assert.doesNotThrow(() => { - _void({type: 'break'}) - }, 'should not throw on valid void nodes') + await t.test('should not throw on valid void nodes', async function () { + assert.doesNotThrow(function () { + _void({type: 'break'}) + }) + }) }) diff --git a/tsconfig.json b/tsconfig.json index 1bc9e99..82cc749 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,15 @@ { - "include": ["**/**.js"], - "exclude": ["coverage/", "node_modules/"], "compilerOptions": { "checkJs": true, + "customConditions": ["development"], "declaration": true, "emitDeclarationOnly": true, "exactOptionalPropertyTypes": true, - "forceConsistentCasingInFileNames": true, - "lib": ["es2020"], + "lib": ["es2022"], "module": "node16", - "newLine": "lf", - "skipLibCheck": true, "strict": true, - "target": "es2020" - } + "target": "es2022" + }, + "exclude": ["coverage/", "node_modules/"], + "include": ["**/*.js"] }