Skip to content

Commit ff41830

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 <[email protected]> Reviewed-By: Vinícius Lourenço Claro Cardoso <[email protected]>
1 parent cfe643f commit ff41830

File tree

5 files changed

+687
-471
lines changed

5 files changed

+687
-471
lines changed

doc/api/assert.md

Lines changed: 99 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2596,87 +2596,151 @@ added:
25962596
- v22.13.0
25972597
-->
25982598

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

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

2615-
assert.partialDeepStrictEqual({ a: 1, b: 2 }, { a: 1, b: 2 });
2616-
// OK
2611+
This method always passes the same test cases as [`assert.deepStrictEqual()`][],
2612+
behaving as a super set of it.
26172613

2618-
assert.partialDeepStrictEqual({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
2619-
// OK
2614+
### Comparison details
26202615

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

2624-
assert.partialDeepStrictEqual(new Set(['value1', 'value2']), new Set(['value1', 'value2']));
2625-
// OK
2637+
```mjs
2638+
import assert from 'node:assert';
26262639

2627-
assert.partialDeepStrictEqual(new Map([['key1', 'value1']]), new Map([['key1', 'value1']]));
2640+
assert.partialDeepStrictEqual(
2641+
{ a: { b: { c: 1 } } },
2642+
{ a: { b: { c: 1 } } },
2643+
);
26282644
// OK
26292645

2630-
assert.partialDeepStrictEqual(new Uint8Array([1, 2, 3]), new Uint8Array([1, 2, 3]));
2646+
assert.partialDeepStrictEqual(
2647+
{ a: 1, b: 2, c: 3 },
2648+
{ b: 2 },
2649+
);
26312650
// OK
26322651

2633-
assert.partialDeepStrictEqual(/abc/, /abc/);
2652+
assert.partialDeepStrictEqual(
2653+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2654+
[4, 5, 8],
2655+
);
26342656
// OK
26352657

2636-
assert.partialDeepStrictEqual([{ a: 5 }, { b: 5 }], [{ a: 5 }]);
2658+
assert.partialDeepStrictEqual(
2659+
new Set([{ a: 1 }, { b: 1 }]),
2660+
new Set([{ a: 1 }]),
2661+
);
26372662
// OK
26382663

2639-
assert.partialDeepStrictEqual(new Set([{ a: 1 }, { b: 1 }]), new Set([{ a: 1 }]));
2664+
assert.partialDeepStrictEqual(
2665+
new Map([['key1', 'value1'], ['key2', 'value2']]),
2666+
new Map([['key2', 'value2']]),
2667+
);
26402668
// OK
26412669

2642-
assert.partialDeepStrictEqual(new Date(0), new Date(0));
2670+
assert.partialDeepStrictEqual(123n, 123n);
26432671
// OK
26442672

2645-
assert.partialDeepStrictEqual({ a: 1 }, { a: 1, b: 2 });
2673+
assert.partialDeepStrictEqual(
2674+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2675+
[5, 4, 8],
2676+
);
26462677
// AssertionError
26472678

2648-
assert.partialDeepStrictEqual({ a: 1, b: '2' }, { a: 1, b: 2 });
2679+
assert.partialDeepStrictEqual(
2680+
{ a: 1 },
2681+
{ a: 1, b: 2 },
2682+
);
26492683
// AssertionError
26502684

2651-
assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } });
2685+
assert.partialDeepStrictEqual(
2686+
{ a: { b: 2 } },
2687+
{ a: { b: '2' } },
2688+
);
26522689
// AssertionError
26532690
```
26542691

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

2658-
assert.partialDeepStrictEqual({ a: 1, b: 2 }, { a: 1, b: 2 });
2695+
assert.partialDeepStrictEqual(
2696+
{ a: { b: { c: 1 } } },
2697+
{ a: { b: { c: 1 } } },
2698+
);
26592699
// OK
26602700

2661-
assert.partialDeepStrictEqual({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
2701+
assert.partialDeepStrictEqual(
2702+
{ a: 1, b: 2, c: 3 },
2703+
{ b: 2 },
2704+
);
26622705
// OK
26632706

2664-
assert.partialDeepStrictEqual({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
2707+
assert.partialDeepStrictEqual(
2708+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2709+
[4, 5, 8],
2710+
);
26652711
// OK
26662712

2667-
assert.partialDeepStrictEqual([{ a: 5 }, { b: 5 }], [{ a: 5 }]);
2713+
assert.partialDeepStrictEqual(
2714+
new Set([{ a: 1 }, { b: 1 }]),
2715+
new Set([{ a: 1 }]),
2716+
);
26682717
// OK
26692718

2670-
assert.partialDeepStrictEqual(new Set([{ a: 1 }, { b: 1 }]), new Set([{ a: 1 }]));
2719+
assert.partialDeepStrictEqual(
2720+
new Map([['key1', 'value1'], ['key2', 'value2']]),
2721+
new Map([['key2', 'value2']]),
2722+
);
26712723
// OK
26722724

2673-
assert.partialDeepStrictEqual({ a: 1 }, { a: 1, b: 2 });
2725+
assert.partialDeepStrictEqual(123n, 123n);
2726+
// OK
2727+
2728+
assert.partialDeepStrictEqual(
2729+
[1, 2, 3, 4, 5, 6, 7, 8, 9],
2730+
[5, 4, 8],
2731+
);
26742732
// AssertionError
26752733

2676-
assert.partialDeepStrictEqual({ a: 1, b: '2' }, { a: 1, b: 2 });
2734+
assert.partialDeepStrictEqual(
2735+
{ a: 1 },
2736+
{ a: 1, b: 2 },
2737+
);
26772738
// AssertionError
26782739

2679-
assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } });
2740+
assert.partialDeepStrictEqual(
2741+
{ a: { b: 2 } },
2742+
{ a: { b: '2' } },
2743+
);
26802744
// AssertionError
26812745
```
26822746

@@ -2700,7 +2764,6 @@ assert.partialDeepStrictEqual({ a: { b: 2 } }, { a: { b: '2' } });
27002764
[`assert.notEqual()`]: #assertnotequalactual-expected-message
27012765
[`assert.notStrictEqual()`]: #assertnotstrictequalactual-expected-message
27022766
[`assert.ok()`]: #assertokvalue-message
2703-
[`assert.partialDeepStrictEqual()`]: #assertpartialdeepstrictequalactual-expected-message
27042767
[`assert.strictEqual()`]: #assertstrictequalactual-expected-message
27052768
[`assert.throws()`]: #assertthrowsfn-error-message
27062769
[`getColorDepth()`]: tty.md#writestreamgetcolordepthenv

0 commit comments

Comments
 (0)