Skip to content

Commit d817c17

Browse files
BridgeARRafaelGSS
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 <rafael.nunu@hotmail.com> Reviewed-By: Vinícius Lourenço Claro Cardoso <contact@viniciusl.com.br>
1 parent 8202211 commit d817c17

File tree

5 files changed

+688
-471
lines changed

5 files changed

+688
-471
lines changed

doc/api/assert.md

+99-36
Original file line numberDiff line numberDiff line change
@@ -2589,87 +2589,151 @@ argument.
25892589
added: v22.13.0
25902590
-->
25912591

2592-
> Stability: 1.0 - Early development
2592+
> Stability: 1.2 - Release candidate
25932593
25942594
* `actual` {any}
25952595
* `expected` {any}
25962596
* `message` {string|Error}
25972597

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

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

2611-
assert.partialDeepStrictEqual({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
2612-
// OK
2607+
### Comparison details
26132608

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

2617-
assert.partialDeepStrictEqual(new Set(['value1', 'value2']), new Set(['value1', 'value2']));
2618-
// OK
2630+
```mjs
2631+
import assert from 'node:assert';
26192632

2620-
assert.partialDeepStrictEqual(new Map([['key1', 'value1']]), new Map([['key1', 'value1']]));
2633+
assert.partialDeepStrictEqual(
2634+
{ a: { b: { c: 1 } } },
2635+
{ a: { b: { c: 1 } } },
2636+
);
26212637
// OK
26222638

2623-
assert.partialDeepStrictEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3]));
2639+
assert.partialDeepStrictEqual(
2640+
{ a: 1, b: 2, c: 3 },
2641+
{ b: 2 },
2642+
);
26242643
// OK
26252644

2626-
assert.partialDeepStrictEqual(/abc/, /abc/);
2645+
assert.partialDeepStrictEqual(
2646+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2647+
[4, 5, 8],
2648+
);
26272649
// OK
26282650

2629-
assert.partialDeepStrictEqual([{ a: 5 }, { b: 5 }], [{ a: 5 }]);
2651+
assert.partialDeepStrictEqual(
2652+
new Set([{ a: 1 }, { b: 1 }]),
2653+
new Set([{ a: 1 }]),
2654+
);
26302655
// OK
26312656

2632-
assert.partialDeepStrictEqual(new Set([{ a: 1 }, { b: 1 }]), new Set([{ a: 1 }]));
2657+
assert.partialDeepStrictEqual(
2658+
new Map([['key1', 'value1'], ['key2', 'value2']]),
2659+
new Map([['key2', 'value2']]),
2660+
);
26332661
// OK
26342662

2635-
assert.partialDeepStrictEqual(new Date(0), new Date(0));
2663+
assert.partialDeepStrictEqual(123n, 123n);
26362664
// OK
26372665

2638-
assert.partialDeepStrictEqual({ a: 1 }, { a: 1, b: 2 });
2666+
assert.partialDeepStrictEqual(
2667+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2668+
[5, 4, 8],
2669+
);
26392670
// AssertionError
26402671

2641-
assert.partialDeepStrictEqual({ a: 1, b: '2' }, { a: 1, b: 2 });
2672+
assert.partialDeepStrictEqual(
2673+
{ a: 1 },
2674+
{ a: 1, b: 2 },
2675+
);
26422676
// AssertionError
26432677

2644-
assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } });
2678+
assert.partialDeepStrictEqual(
2679+
{ a: { b: 2 } },
2680+
{ a: { b: '2' } },
2681+
);
26452682
// AssertionError
26462683
```
26472684

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

2651-
assert.partialDeepStrictEqual({ a: 1, b: 2 }, { a: 1, b: 2 });
2688+
assert.partialDeepStrictEqual(
2689+
{ a: { b: { c: 1 } } },
2690+
{ a: { b: { c: 1 } } },
2691+
);
26522692
// OK
26532693

2654-
assert.partialDeepStrictEqual({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
2694+
assert.partialDeepStrictEqual(
2695+
{ a: 1, b: 2, c: 3 },
2696+
{ b: 2 },
2697+
);
26552698
// OK
26562699

2657-
assert.partialDeepStrictEqual({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
2700+
assert.partialDeepStrictEqual(
2701+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2702+
[4, 5, 8],
2703+
);
26582704
// OK
26592705

2660-
assert.partialDeepStrictEqual([{ a: 5 }, { b: 5 }], [{ a: 5 }]);
2706+
assert.partialDeepStrictEqual(
2707+
new Set([{ a: 1 }, { b: 1 }]),
2708+
new Set([{ a: 1 }]),
2709+
);
26612710
// OK
26622711

2663-
assert.partialDeepStrictEqual(new Set([{ a: 1 }, { b: 1 }]), new Set([{ a: 1 }]));
2712+
assert.partialDeepStrictEqual(
2713+
new Map([['key1', 'value1'], ['key2', 'value2']]),
2714+
new Map([['key2', 'value2']]),
2715+
);
26642716
// OK
26652717

2666-
assert.partialDeepStrictEqual({ a: 1 }, { a: 1, b: 2 });
2718+
assert.partialDeepStrictEqual(123n, 123n);
2719+
// OK
2720+
2721+
assert.partialDeepStrictEqual(
2722+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2723+
[5, 4, 8],
2724+
);
26672725
// AssertionError
26682726

2669-
assert.partialDeepStrictEqual({ a: 1, b: '2' }, { a: 1, b: 2 });
2727+
assert.partialDeepStrictEqual(
2728+
{ a: 1 },
2729+
{ a: 1, b: 2 },
2730+
);
26702731
// AssertionError
26712732

2672-
assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } });
2733+
assert.partialDeepStrictEqual(
2734+
{ a: { b: 2 } },
2735+
{ a: { b: '2' } },
2736+
);
26732737
// AssertionError
26742738
```
26752739

@@ -2693,7 +2757,6 @@ assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } });
26932757
[`assert.notEqual()`]: #assertnotequalactual-expected-message
26942758
[`assert.notStrictEqual()`]: #assertnotstrictequalactual-expected-message
26952759
[`assert.ok()`]: #assertokvalue-message
2696-
[`assert.partialDeepStrictEqual()`]: #assertpartialdeepstrictequalactual-expected-message
26972760
[`assert.strictEqual()`]: #assertstrictequalactual-expected-message
26982761
[`assert.throws()`]: #assertthrowsfn-error-message
26992762
[`getColorDepth()`]: tty.md#writestreamgetcolordepthenv

0 commit comments

Comments
 (0)