Skip to content

Commit f694d7d

Browse files
BridgeARaduh95
authored andcommitted
assert: improve partialDeepStrictEqual
This significantly improves the assert.partialDeepStrictEqual implementation by reusing the already existing algorithm. It is significantly faster and handles edge cases like symbols identical as the deepStrictEqual algorithm. This is crucial to remove the experimental status from the implementation. PR-URL: #57370 Reviewed-By: Rafael Gonzaga <[email protected]> Reviewed-By: Vinícius Lourenço Claro Cardoso <[email protected]>
1 parent 3cff7f8 commit f694d7d

File tree

5 files changed

+687
-471
lines changed

5 files changed

+687
-471
lines changed

doc/api/assert.md

+99-36
Original file line numberDiff line numberDiff line change
@@ -2594,87 +2594,151 @@ argument.
25942594
added: v23.4.0
25952595
-->
25962596

2597-
> Stability: 1.0 - Early development
2597+
> Stability: 1.2 - Release candidate
25982598
25992599
* `actual` {any}
26002600
* `expected` {any}
26012601
* `message` {string|Error}
26022602

2603-
[`assert.partialDeepStrictEqual()`][] Asserts the equivalence between the `actual` and `expected` parameters through a
2604-
deep comparison, ensuring that all properties in the `expected` parameter are
2605-
present in the `actual` parameter with equivalent values, not allowing type coercion.
2606-
The main difference with [`assert.deepStrictEqual()`][] is that [`assert.partialDeepStrictEqual()`][] does not require
2607-
all properties in the `actual` parameter to be present in the `expected` parameter.
2608-
This method should always pass the same test cases as [`assert.deepStrictEqual()`][], behaving as a super set of it.
2609-
2610-
```mjs
2611-
import assert from 'node:assert';
2603+
Tests for partial deep equality between the `actual` and `expected` parameters.
2604+
"Deep" equality means that the enumerable "own" properties of child objects
2605+
are recursively evaluated also by the following rules. "Partial" equality means
2606+
that only properties that exist on the `expected` parameter are going to be
2607+
compared.
26122608

2613-
assert.partialDeepStrictEqual({ a: 1, b: 2 }, { a: 1, b: 2 });
2614-
// OK
2609+
This method always passes the same test cases as [`assert.deepStrictEqual()`][],
2610+
behaving as a super set of it.
26152611

2616-
assert.partialDeepStrictEqual({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
2617-
// OK
2612+
### Comparison details
26182613

2619-
assert.partialDeepStrictEqual({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
2620-
// OK
2614+
* Primitive values are compared using [`Object.is()`][].
2615+
* [Type tags][Object.prototype.toString()] of objects should be the same.
2616+
* [`[[Prototype]]`][prototype-spec] of objects are not compared.
2617+
* Only [enumerable "own" properties][] are considered.
2618+
* {Error} names, messages, causes, and errors are always compared,
2619+
even if these are not enumerable properties.
2620+
`errors` is also compared.
2621+
* Enumerable own {Symbol} properties are compared as well.
2622+
* [Object wrappers][] are compared both as objects and unwrapped values.
2623+
* `Object` properties are compared unordered.
2624+
* {Map} keys and {Set} items are compared unordered.
2625+
* Recursion stops when both sides differ or both sides encounter a circular
2626+
reference.
2627+
* {WeakMap} and {WeakSet} instances are **not** compared structurally.
2628+
They are only equal if they reference the same object. Any comparison between
2629+
different `WeakMap` or `WeakSet` instances will result in inequality,
2630+
even if they contain the same entries.
2631+
* {RegExp} lastIndex, flags, and source are always compared, even if these
2632+
are not enumerable properties.
2633+
* Holes in sparse arrays are ignored.
26212634

2622-
assert.partialDeepStrictEqual(new Set(['value1', 'value2']), new Set(['value1', 'value2']));
2623-
// OK
2635+
```mjs
2636+
import assert from 'node:assert';
26242637

2625-
assert.partialDeepStrictEqual(new Map([['key1', 'value1']]), new Map([['key1', 'value1']]));
2638+
assert.partialDeepStrictEqual(
2639+
{ a: { b: { c: 1 } } },
2640+
{ a: { b: { c: 1 } } },
2641+
);
26262642
// OK
26272643

2628-
assert.partialDeepStrictEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3]));
2644+
assert.partialDeepStrictEqual(
2645+
{ a: 1, b: 2, c: 3 },
2646+
{ b: 2 },
2647+
);
26292648
// OK
26302649

2631-
assert.partialDeepStrictEqual(/abc/, /abc/);
2650+
assert.partialDeepStrictEqual(
2651+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2652+
[4, 5, 8],
2653+
);
26322654
// OK
26332655

2634-
assert.partialDeepStrictEqual([{ a: 5 }, { b: 5 }], [{ a: 5 }]);
2656+
assert.partialDeepStrictEqual(
2657+
new Set([{ a: 1 }, { b: 1 }]),
2658+
new Set([{ a: 1 }]),
2659+
);
26352660
// OK
26362661

2637-
assert.partialDeepStrictEqual(new Set([{ a: 1 }, { b: 1 }]), new Set([{ a: 1 }]));
2662+
assert.partialDeepStrictEqual(
2663+
new Map([['key1', 'value1'], ['key2', 'value2']]),
2664+
new Map([['key2', 'value2']]),
2665+
);
26382666
// OK
26392667

2640-
assert.partialDeepStrictEqual(new Date(0), new Date(0));
2668+
assert.partialDeepStrictEqual(123n, 123n);
26412669
// OK
26422670

2643-
assert.partialDeepStrictEqual({ a: 1 }, { a: 1, b: 2 });
2671+
assert.partialDeepStrictEqual(
2672+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2673+
[5, 4, 8],
2674+
);
26442675
// AssertionError
26452676

2646-
assert.partialDeepStrictEqual({ a: 1, b: '2' }, { a: 1, b: 2 });
2677+
assert.partialDeepStrictEqual(
2678+
{ a: 1 },
2679+
{ a: 1, b: 2 },
2680+
);
26472681
// AssertionError
26482682

2649-
assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } });
2683+
assert.partialDeepStrictEqual(
2684+
{ a: { b: 2 } },
2685+
{ a: { b: '2' } },
2686+
);
26502687
// AssertionError
26512688
```
26522689

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

2656-
assert.partialDeepStrictEqual({ a: 1, b: 2 }, { a: 1, b: 2 });
2693+
assert.partialDeepStrictEqual(
2694+
{ a: { b: { c: 1 } } },
2695+
{ a: { b: { c: 1 } } },
2696+
);
26572697
// OK
26582698

2659-
assert.partialDeepStrictEqual({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
2699+
assert.partialDeepStrictEqual(
2700+
{ a: 1, b: 2, c: 3 },
2701+
{ b: 2 },
2702+
);
26602703
// OK
26612704

2662-
assert.partialDeepStrictEqual({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
2705+
assert.partialDeepStrictEqual(
2706+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2707+
[4, 5, 8],
2708+
);
26632709
// OK
26642710

2665-
assert.partialDeepStrictEqual([{ a: 5 }, { b: 5 }], [{ a: 5 }]);
2711+
assert.partialDeepStrictEqual(
2712+
new Set([{ a: 1 }, { b: 1 }]),
2713+
new Set([{ a: 1 }]),
2714+
);
26662715
// OK
26672716

2668-
assert.partialDeepStrictEqual(new Set([{ a: 1 }, { b: 1 }]), new Set([{ a: 1 }]));
2717+
assert.partialDeepStrictEqual(
2718+
new Map([['key1', 'value1'], ['key2', 'value2']]),
2719+
new Map([['key2', 'value2']]),
2720+
);
26692721
// OK
26702722

2671-
assert.partialDeepStrictEqual({ a: 1 }, { a: 1, b: 2 });
2723+
assert.partialDeepStrictEqual(123n, 123n);
2724+
// OK
2725+
2726+
assert.partialDeepStrictEqual(
2727+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2728+
[5, 4, 8],
2729+
);
26722730
// AssertionError
26732731

2674-
assert.partialDeepStrictEqual({ a: 1, b: '2' }, { a: 1, b: 2 });
2732+
assert.partialDeepStrictEqual(
2733+
{ a: 1 },
2734+
{ a: 1, b: 2 },
2735+
);
26752736
// AssertionError
26762737

2677-
assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } });
2738+
assert.partialDeepStrictEqual(
2739+
{ a: { b: 2 } },
2740+
{ a: { b: '2' } },
2741+
);
26782742
// AssertionError
26792743
```
26802744

@@ -2698,7 +2762,6 @@ assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } });
26982762
[`assert.notEqual()`]: #assertnotequalactual-expected-message
26992763
[`assert.notStrictEqual()`]: #assertnotstrictequalactual-expected-message
27002764
[`assert.ok()`]: #assertokvalue-message
2701-
[`assert.partialDeepStrictEqual()`]: #assertpartialdeepstrictequalactual-expected-message
27022765
[`assert.strictEqual()`]: #assertstrictequalactual-expected-message
27032766
[`assert.throws()`]: #assertthrowsfn-error-message
27042767
[`getColorDepth()`]: tty.md#writestreamgetcolordepthenv

0 commit comments

Comments
 (0)