Skip to content

Commit 0ee83d4

Browse files
puskinsynapse
andcommitted
assert: adds deepMatch, deepMatchStrict, includes, includesStrict
Fixes: #50399 Co-Authored-By: Cristian Barlutiu <[email protected]>
1 parent beabcec commit 0ee83d4

File tree

3 files changed

+1097
-1
lines changed

3 files changed

+1097
-1
lines changed

doc/api/assert.md

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2548,6 +2548,241 @@ assert.throws(throwingFirst, /Second$/);
25482548
Due to the confusing error-prone notation, avoid a string as the second
25492549
argument.
25502550

2551+
## `assert.deepMatch(actual, expected[, message])`
2552+
2553+
<!-- YAML
2554+
added: REPLACEME
2555+
-->
2556+
2557+
* `actual` {any}
2558+
* `expected` {any}
2559+
* `message` {string|Error}
2560+
2561+
[`assert.deepMatch()`][] evaluates the equivalence between the `actual` and `expected` parameters by
2562+
performing a deep comparison. This function ensures that all properties defined
2563+
in the `expected` parameter match those in the `actual` parameter in
2564+
both value and type, allowing type coercion. The main difference with [`assert.deepEqual()`][] is that
2565+
[`assert.deepMatch()`][] does not require all properties in the `actual` parameter to be present in the
2566+
`expected` parameter.
2567+
2568+
```mjs
2569+
import assert from 'node:assert';
2570+
2571+
assert.deepMatch({ a: 1, b: '2' }, { a: 1, b: 2 });
2572+
// OK
2573+
2574+
assert.deepMatch({ a: 1, b: '2', c: 3 }, { a: 1, b: 2 });
2575+
// OK
2576+
2577+
assert.deepMatch({ a: { b: { c: '1' } } }, { a: { b: { c: 1 } } });
2578+
// OK
2579+
2580+
assert.deepMatch({ a: 1 }, { a: 1, b: 2 });
2581+
// AssertionError
2582+
2583+
assert.deepMatch({ a: 1, b: true }, { a: 1, b: 'true' });
2584+
// AssertionError
2585+
2586+
assert.deepMatch({ a: { b: 2 } }, { a: { b: 2, c: 3 } });
2587+
// AssertionError
2588+
```
2589+
2590+
```cjs
2591+
const assert = require('node:assert');
2592+
2593+
assert.deepMatch({ a: 1, b: '2' }, { a: 1, b: 2 });
2594+
// OK
2595+
2596+
assert.deepMatch({ a: 1, b: '2', c: 3 }, { a: 1, b: 2 });
2597+
// OK
2598+
2599+
assert.deepMatch({ a: { b: { c: '1' } } }, { a: { b: { c: 1 } } });
2600+
// OK
2601+
2602+
assert.deepMatch({ a: 1 }, { a: 1, b: 2 });
2603+
// AssertionError: Expected key b
2604+
2605+
assert.deepMatch({ a: 1, b: true }, { a: 1, b: 'true' });
2606+
// AssertionError
2607+
2608+
assert.deepMatch({ a: { b: 2, d: 4 } }, { a: { b: 2, c: 3 } });
2609+
// AssertionError: Expected key c
2610+
```
2611+
2612+
If the values or keys are not equal in the `expected` parameter, an [`AssertionError`][] is thrown with a `message`
2613+
property set equal to the value of the `message` parameter. If the `message`
2614+
parameter is undefined, a default error message is assigned. If the `message`
2615+
parameter is an instance of an [`Error`][] then it will be thrown instead of the
2616+
`AssertionError`.
2617+
2618+
## `assert.deepMatchStrict(actual, expected[, message])`
2619+
2620+
<!-- YAML
2621+
added: REPLACEME
2622+
-->
2623+
2624+
* `actual` {any}
2625+
* `expected` {any}
2626+
* `message` {string|Error}
2627+
2628+
[`assert.deepMatchStrict()`][] Assesses the equivalence between the `actual` and `expected` parameters through a
2629+
deep comparison, ensuring that all properties in the `expected` parameter are
2630+
present in the `actual` parameter with equivalent values, not allowing type coercion.
2631+
The main difference with [`assert.deepStrictEqual()`][] is that [`assert.deepMatchStrict()`][] does not require all
2632+
properties in the `actual` parameter to be present in the `expected` parameter.
2633+
2634+
```mjs
2635+
import assert from 'node:assert';
2636+
2637+
assert.deepMatchStrict({ a: 1, b: 2 }, { a: 1, b: 2 });
2638+
// OK
2639+
2640+
assert.deepMatchStrict({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
2641+
// OK
2642+
2643+
assert.deepMatchStrict({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
2644+
// OK
2645+
2646+
assert.deepMatchStrict({ a: 1 }, { a: 1, b: 2 });
2647+
// AssertionError
2648+
2649+
assert.deepMatchStrict({ a: 1, b: '2' }, { a: 1, b: 2 });
2650+
// AssertionError
2651+
2652+
assert.deepMatchStrict({ a: { b: 2 } }, { a: { b: '2' } });
2653+
// AssertionError
2654+
```
2655+
2656+
```cjs
2657+
const assert = require('node:assert');
2658+
2659+
assert.deepMatchStrict({ a: 1, b: 2 }, { a: 1, b: 2 });
2660+
// OK
2661+
2662+
assert.deepMatchStrict({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
2663+
// OK
2664+
2665+
assert.deepMatchStrict({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
2666+
// OK
2667+
2668+
assert.deepMatchStrict({ a: 1 }, { a: 1, b: 2 });
2669+
// AssertionError
2670+
2671+
assert.deepMatchStrict({ a: 1, b: '2' }, { a: 1, b: 2 });
2672+
// AssertionError
2673+
2674+
assert.deepMatchStrict({ a: { b: 2 } }, { a: { b: '2' } });
2675+
// AssertionError
2676+
```
2677+
2678+
## `assert.includes(actual, expected[, message])`
2679+
2680+
<!-- YAML
2681+
added: REPLACEME
2682+
-->
2683+
2684+
* `actual` {Array | string}
2685+
* `expected` {Array | string}
2686+
* `message` {string|Error}
2687+
2688+
[`assert.includes()`][] compares the `actual` and `expected` parameters to determine if the `expected`
2689+
parameter is included in the `actual` parameter; the comparison is done with type coercion.
2690+
The `actual` and the `expected` parameters can be
2691+
either an array or a string. If the `actual` parameter is an array,
2692+
the `expected` parameter must be an array and vice versa for strings.
2693+
2694+
```mjs
2695+
import assert from 'node:assert';
2696+
2697+
assert.includes([1, 2, 3], ['2', 3]);
2698+
// OK
2699+
2700+
assert.includes('Hello World!', 'World');
2701+
// OK
2702+
2703+
assert.includes([1, 2, 3], [2, 4]);
2704+
// AssertionError
2705+
2706+
assert.includes('Hello World!', 'Node.js');
2707+
// AssertionError
2708+
```
2709+
2710+
```cjs
2711+
const assert = require('node:assert');
2712+
2713+
assert.includes([1, 2, 3], [2, 3]);
2714+
// OK
2715+
2716+
assert.includes('Hello World!', 'World');
2717+
// OK
2718+
2719+
assert.includes([1, 2, 3], [2, 4]);
2720+
// AssertionError
2721+
2722+
assert.includes('Hello World!', 'Node.js');
2723+
// AssertionError
2724+
```
2725+
2726+
If the assertion fails, an [`AssertionError`][] is thrown with a `message`
2727+
property set equal to the value of the `message` parameter. If the `message`
2728+
parameter is undefined, a default error message is assigned. If the `message`
2729+
parameter is an instance of an [`Error`][] then it will be thrown instead of the
2730+
`AssertionError`.
2731+
2732+
## `assert.includesStrict(actual, expected[, message])`
2733+
2734+
<!-- YAML
2735+
added: REPLACEME
2736+
-->
2737+
2738+
* `actual` {Array | string}
2739+
* `expected` {Array | string}
2740+
* `message` {string|Error}
2741+
2742+
[`assert.includesStrict()`][] compares the `actual` and `expected` parameters to determine if the `expected`
2743+
parameter is included in the `actual` parameter; the comparison is done without type coercion.
2744+
The `actual` and the `expected` parameters can be
2745+
either an array or a string. If the `actual` parameter is an array,
2746+
the `expected` parameter must be an array and vice versa for strings.
2747+
2748+
```mjs
2749+
import assert from 'node:assert';
2750+
2751+
assert.includesStrict([1, 2, 3], [2, 3]);
2752+
// OK
2753+
2754+
assert.includesStrict('Hello World!', 'World');
2755+
// OK
2756+
2757+
assert.includesStrict([1, 2, 3], [2, 4]);
2758+
// AssertionError
2759+
2760+
assert.includesStrict('Hello World!', 'Node.js');
2761+
// AssertionError
2762+
```
2763+
2764+
```cjs
2765+
const assert = require('node:assert');
2766+
2767+
assert.includesStrict([1, 2, 3], [2, 3]);
2768+
// OK
2769+
2770+
assert.includesStrict('Hello World!', 'World');
2771+
// OK
2772+
2773+
assert.includesStrict([1, 2, 3], [2, 4]);
2774+
// AssertionError
2775+
2776+
assert.includesStrict('Hello World!', 'Node.js');
2777+
// AssertionError
2778+
```
2779+
2780+
If the assertion fails, an [`AssertionError`][] is thrown with a `message`
2781+
property set equal to the value of the `message` parameter. If the `message`
2782+
parameter is undefined, a default error message is assigned. If the `message`
2783+
parameter is an instance of an [`Error`][] then it will be thrown instead of the
2784+
`AssertionError`.
2785+
25512786
[Object wrappers]: https://developer.mozilla.org/en-US/docs/Glossary/Primitive#Primitive_wrapper_objects_in_JavaScript
25522787
[Object.prototype.toString()]: https://tc39.github.io/ecma262/#sec-object.prototype.tostring
25532788
[`!=` operator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Inequality
@@ -2568,9 +2803,13 @@ argument.
25682803
[`WeakMap`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap
25692804
[`WeakSet`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet
25702805
[`assert.deepEqual()`]: #assertdeepequalactual-expected-message
2806+
[`assert.deepMatch()`]: #assertdeepmatchactual-expected-message
2807+
[`assert.deepMatchStrict()`]: #assertdeepmatchstrictactual-expected-message
25712808
[`assert.deepStrictEqual()`]: #assertdeepstrictequalactual-expected-message
25722809
[`assert.doesNotThrow()`]: #assertdoesnotthrowfn-error-message
25732810
[`assert.equal()`]: #assertequalactual-expected-message
2811+
[`assert.includes()`]: #assertincludesactual-expected-message
2812+
[`assert.includesStrict()`]: #assertincludesstrictactual-expected-message
25742813
[`assert.notDeepEqual()`]: #assertnotdeepequalactual-expected-message
25752814
[`assert.notDeepStrictEqual()`]: #assertnotdeepstrictequalactual-expected-message
25762815
[`assert.notEqual()`]: #assertnotequalactual-expected-message

0 commit comments

Comments
 (0)