Skip to content

Commit

Permalink
assert: adds deepMatch, deepMatchStrict, includes, includesStrict
Browse files Browse the repository at this point in the history
Fixes: #50399

Co-Authored-By: Cristian Barlutiu <[email protected]>
  • Loading branch information
puskin94 and synapse committed Aug 29, 2024
1 parent beabcec commit 04e92f0
Show file tree
Hide file tree
Showing 3 changed files with 1,001 additions and 1 deletion.
235 changes: 235 additions & 0 deletions doc/api/assert.md
Original file line number Diff line number Diff line change
Expand Up @@ -2548,6 +2548,237 @@ assert.throws(throwingFirst, /Second$/);
Due to the confusing error-prone notation, avoid a string as the second
argument.

## `assert.deepMatch(actual, expected[, message])`

<!-- YAML
added: REPLACEME
-->

* `actual` {any}
* `expected` {any}
* `message` {string|Error}

[`assert.deepMatch()`][] evaluates the equivalence between the `actual` and `expected` parameters by
performing a deep comparison. This function ensures that all properties defined
in the `expected` parameter match those in the `actual` parameter in
both value and type, allowing type coercion.

```mjs
import assert from 'node:assert';

assert.deepMatch({ a: 1, b: '2' }, { a: 1, b: 2 });
// OK

assert.deepMatch({ a: 1, b: '2', c: 3 }, { a: 1, b: 2 });
// OK

assert.deepMatch({ a: { b: { c: '1' } } }, { a: { b: { c: 1 } } });
// OK

assert.deepMatch({ a: 1 }, { a: 1, b: 2 });
// AssertionError

assert.deepMatch({ a: 1, b: true }, { a: 1, b: 'true' });
// AssertionError

assert.deepMatch({ a: { b: 2 } }, { a: { b: 2, c: 3 } });
// AssertionError
```

```cjs
const assert = require('node:assert');

assert.deepMatch({ a: 1, b: '2' }, { a: 1, b: 2 });
// OK

assert.deepMatch({ a: 1, b: '2', c: 3 }, { a: 1, b: 2 });
// OK

assert.deepMatch({ a: { b: { c: '1' } } }, { a: { b: { c: 1 } } });
// OK

assert.deepMatch({ a: 1 }, { a: 1, b: 2 });
// AssertionError: Expected key b

assert.deepMatch({ a: 1, b: true }, { a: 1, b: 'true' });
// AssertionError

assert.deepMatch({ a: { b: 2, d: 4 } }, { a: { b: 2, c: 3 } });
// AssertionError: Expected key c
```

If the values or keys are not equal in the `expected` parameter, an [`AssertionError`][] is thrown with a `message`
property set equal to the value of the `message` parameter. If the `message`
parameter is undefined, a default error message is assigned. If the `message`
parameter is an instance of an [`Error`][] then it will be thrown instead of the
`AssertionError`.

## `assert.deepMatchStrict(actual, expected[, message])`

<!-- YAML
added: REPLACEME
-->

* `actual` {any}
* `expected` {any}
* `message` {string|Error}

[`assert.deepMatchStrict()`][] Assesses the equivalence between the `actual` and `expected` parameters through a
deep comparison, ensuring that all properties in the `expected` parameter are
present in the `actual` parameter with equivalent values, not allowing type coercion.

```mjs
import assert from 'node:assert';

assert.deepMatchStrict({ a: 1, b: 2 }, { a: 1, b: 2 });
// OK

assert.deepMatchStrict({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
// OK

assert.deepMatchStrict({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
// OK

assert.deepMatchStrict({ a: 1 }, { a: 1, b: 2 });
// AssertionError

assert.deepMatchStrict({ a: 1, b: '2' }, { a: 1, b: 2 });
// AssertionError

assert.deepMatchStrict({ a: { b: 2 } }, { a: { b: '2' } });
// AssertionError
```

```cjs
const assert = require('node:assert');

assert.deepMatchStrict({ a: 1, b: 2 }, { a: 1, b: 2 });
// OK

assert.deepMatchStrict({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
// OK

assert.deepMatchStrict({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
// OK

assert.deepMatchStrict({ a: 1 }, { a: 1, b: 2 });
// AssertionError

assert.deepMatchStrict({ a: 1, b: '2' }, { a: 1, b: 2 });
// AssertionError

assert.deepMatchStrict({ a: { b: 2 } }, { a: { b: '2' } });
// AssertionError
```

## `assert.includes(actual, expected[, message])`

<!-- YAML
added: REPLACEME
-->

* `actual` {Array | string}
* `expected` {Array | string}
* `message` {string|Error}

[`assert.includes()`][] compares the `actual` and `expected` parameters to determine if the `expected`
parameter is included in the `actual` parameter; the comparison is done with type coercion.
The `actual` and the `expected` parameters can be
either an array or a string. If the `actual` parameter is an array,
the `expected` parameter must be an array and vice versa for strings.

```mjs
import assert from 'node:assert';

assert.includes([1, 2, 3], ['2', 3]);
// OK

assert.includes('Hello World!', 'World');
// OK

assert.includes([1, 2, 3], [2, 4]);
// AssertionError

assert.includes('Hello World!', 'Node.js');
// AssertionError
```

```cjs
const assert = require('node:assert');

assert.includes([1, 2, 3], [2, 3]);
// OK

assert.includes('Hello World!', 'World');
// OK

assert.includes([1, 2, 3], [2, 4]);
// AssertionError

assert.includes('Hello World!', 'Node.js');
// AssertionError
```

If the assertion fails, an [`AssertionError`][] is thrown with a `message`
property set equal to the value of the `message` parameter. If the `message`
parameter is undefined, a default error message is assigned. If the `message`
parameter is an instance of an [`Error`][] then it will be thrown instead of the
`AssertionError`.

## `assert.includesStrict(actual, expected[, message])`

<!-- YAML
added: REPLACEME
-->

* `actual` {Array | string}
* `expected` {Array | string}
* `message` {string|Error}

[`assert.includesStrict()`][] compares the `actual` and `expected` parameters to determine if the `expected`
parameter is included in the `actual` parameter; the comparison is done without type coercion.
The `actual` and the `expected` parameters can be
either an array or a string. If the `actual` parameter is an array,
the `expected` parameter must be an array and vice versa for strings.

```mjs
import assert from 'node:assert';

assert.includesStrict([1, 2, 3], [2, 3]);
// OK

assert.includesStrict('Hello World!', 'World');
// OK

assert.includesStrict([1, 2, 3], [2, 4]);
// AssertionError

assert.includesStrict('Hello World!', 'Node.js');
// AssertionError
```

```cjs
const assert = require('node:assert');

assert.includesStrict([1, 2, 3], [2, 3]);
// OK

assert.includesStrict('Hello World!', 'World');
// OK

assert.includesStrict([1, 2, 3], [2, 4]);
// AssertionError

assert.includesStrict('Hello World!', 'Node.js');
// AssertionError
```

If the assertion fails, an [`AssertionError`][] is thrown with a `message`
property set equal to the value of the `message` parameter. If the `message`
parameter is undefined, a default error message is assigned. If the `message`
parameter is an instance of an [`Error`][] then it will be thrown instead of the
`AssertionError`.

[Object wrappers]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript
[Object.prototype.toString()]: https://tc39.github.io/ecma262/#sec-object.prototype.tostring
[`!=` operator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Inequality
Expand All @@ -2568,9 +2799,13 @@ argument.
[`WeakMap`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap
[`WeakSet`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet
[`assert.deepEqual()`]: #assertdeepequalactual-expected-message
[`assert.deepMatch()`]: #assertdeepmatchactual-expected-message
[`assert.deepMatchStrict()`]: #assertdeepmatchstrictactual-expected-message
[`assert.deepStrictEqual()`]: #assertdeepstrictequalactual-expected-message
[`assert.doesNotThrow()`]: #assertdoesnotthrowfn-error-message
[`assert.equal()`]: #assertequalactual-expected-message
[`assert.includes()`]: #assertincludesactual-expected-message
[`assert.includesStrict()`]: #assertincludesstrictactual-expected-message
[`assert.notDeepEqual()`]: #assertnotdeepequalactual-expected-message
[`assert.notDeepStrictEqual()`]: #assertnotdeepstrictequalactual-expected-message
[`assert.notEqual()`]: #assertnotequalactual-expected-message
Expand Down
Loading

0 comments on commit 04e92f0

Please sign in to comment.