Skip to content

Commit ab7e68e

Browse files
committed
assert: renamed deepEqual/deepStrictEqual to partialEqual/partialStrictEqual
1 parent 0ee83d4 commit ab7e68e

File tree

3 files changed

+132
-81
lines changed

3 files changed

+132
-81
lines changed

doc/api/assert.md

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2548,7 +2548,7 @@ 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])`
2551+
## `assert.partialDeepEqual(actual, expected[, message])`
25522552

25532553
<!-- YAML
25542554
added: REPLACEME
@@ -2558,54 +2558,54 @@ added: REPLACEME
25582558
* `expected` {any}
25592559
* `message` {string|Error}
25602560

2561-
[`assert.deepMatch()`][] evaluates the equivalence between the `actual` and `expected` parameters by
2561+
[`assert.partialDeepEqual()`][] evaluates the equivalence between the `actual` and `expected` parameters by
25622562
performing a deep comparison. This function ensures that all properties defined
25632563
in the `expected` parameter match those in the `actual` parameter in
25642564
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
2565+
[`assert.partialDeepEqual()`][] does not require all properties in the `actual` parameter to be present in the
25662566
`expected` parameter.
25672567

25682568
```mjs
25692569
import assert from 'node:assert';
25702570

2571-
assert.deepMatch({ a: 1, b: '2' }, { a: 1, b: 2 });
2571+
assert.partialDeepEqual({ a: 1, b: '2' }, { a: 1, b: 2 });
25722572
// OK
25732573

2574-
assert.deepMatch({ a: 1, b: '2', c: 3 }, { a: 1, b: 2 });
2574+
assert.partialDeepEqual({ a: 1, b: '2', c: 3 }, { a: 1, b: 2 });
25752575
// OK
25762576

2577-
assert.deepMatch({ a: { b: { c: '1' } } }, { a: { b: { c: 1 } } });
2577+
assert.partialDeepEqual({ a: { b: { c: '1' } } }, { a: { b: { c: 1 } } });
25782578
// OK
25792579

2580-
assert.deepMatch({ a: 1 }, { a: 1, b: 2 });
2580+
assert.partialDeepEqual({ a: 1 }, { a: 1, b: 2 });
25812581
// AssertionError
25822582

2583-
assert.deepMatch({ a: 1, b: true }, { a: 1, b: 'true' });
2583+
assert.partialDeepEqual({ a: 1, b: true }, { a: 1, b: 'true' });
25842584
// AssertionError
25852585

2586-
assert.deepMatch({ a: { b: 2 } }, { a: { b: 2, c: 3 } });
2586+
assert.partialDeepEqual({ a: { b: 2 } }, { a: { b: 2, c: 3 } });
25872587
// AssertionError
25882588
```
25892589

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

2593-
assert.deepMatch({ a: 1, b: '2' }, { a: 1, b: 2 });
2593+
assert.partialDeepEqual({ a: 1, b: '2' }, { a: 1, b: 2 });
25942594
// OK
25952595

2596-
assert.deepMatch({ a: 1, b: '2', c: 3 }, { a: 1, b: 2 });
2596+
assert.partialDeepEqual({ a: 1, b: '2', c: 3 }, { a: 1, b: 2 });
25972597
// OK
25982598

2599-
assert.deepMatch({ a: { b: { c: '1' } } }, { a: { b: { c: 1 } } });
2599+
assert.partialDeepEqual({ a: { b: { c: '1' } } }, { a: { b: { c: 1 } } });
26002600
// OK
26012601

2602-
assert.deepMatch({ a: 1 }, { a: 1, b: 2 });
2602+
assert.partialDeepEqual({ a: 1 }, { a: 1, b: 2 });
26032603
// AssertionError: Expected key b
26042604

2605-
assert.deepMatch({ a: 1, b: true }, { a: 1, b: 'true' });
2605+
assert.partialDeepEqual({ a: 1, b: true }, { a: 1, b: 'true' });
26062606
// AssertionError
26072607

2608-
assert.deepMatch({ a: { b: 2, d: 4 } }, { a: { b: 2, c: 3 } });
2608+
assert.partialDeepEqual({ a: { b: 2, d: 4 } }, { a: { b: 2, c: 3 } });
26092609
// AssertionError: Expected key c
26102610
```
26112611

@@ -2615,7 +2615,7 @@ parameter is undefined, a default error message is assigned. If the `message`
26152615
parameter is an instance of an [`Error`][] then it will be thrown instead of the
26162616
`AssertionError`.
26172617

2618-
## `assert.deepMatchStrict(actual, expected[, message])`
2618+
## `assert.partialDeepEqualStrict(actual, expected[, message])`
26192619

26202620
<!-- YAML
26212621
added: REPLACEME
@@ -2625,53 +2625,53 @@ added: REPLACEME
26252625
* `expected` {any}
26262626
* `message` {string|Error}
26272627

2628-
[`assert.deepMatchStrict()`][] Assesses the equivalence between the `actual` and `expected` parameters through a
2628+
[`assert.partialDeepEqualStrict()`][] Assesses the equivalence between the `actual` and `expected` parameters through a
26292629
deep comparison, ensuring that all properties in the `expected` parameter are
26302630
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.
2631+
The main difference with [`assert.deepStrictEqual()`][] is that [`assert.partialDeepEqualStrict()`][] does not require
2632+
all properties in the `actual` parameter to be present in the `expected` parameter.
26332633

26342634
```mjs
26352635
import assert from 'node:assert';
26362636

2637-
assert.deepMatchStrict({ a: 1, b: 2 }, { a: 1, b: 2 });
2637+
assert.partialDeepEqualStrict({ a: 1, b: 2 }, { a: 1, b: 2 });
26382638
// OK
26392639

2640-
assert.deepMatchStrict({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
2640+
assert.partialDeepEqualStrict({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
26412641
// OK
26422642

2643-
assert.deepMatchStrict({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
2643+
assert.partialDeepEqualStrict({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
26442644
// OK
26452645

2646-
assert.deepMatchStrict({ a: 1 }, { a: 1, b: 2 });
2646+
assert.partialDeepEqualStrict({ a: 1 }, { a: 1, b: 2 });
26472647
// AssertionError
26482648

2649-
assert.deepMatchStrict({ a: 1, b: '2' }, { a: 1, b: 2 });
2649+
assert.partialDeepEqualStrict({ a: 1, b: '2' }, { a: 1, b: 2 });
26502650
// AssertionError
26512651

2652-
assert.deepMatchStrict({ a: { b: 2 } }, { a: { b: '2' } });
2652+
assert.partialDeepEqualStrict({ a: { b: 2 } }, { a: { b: '2' } });
26532653
// AssertionError
26542654
```
26552655

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

2659-
assert.deepMatchStrict({ a: 1, b: 2 }, { a: 1, b: 2 });
2659+
assert.partialDeepEqualStrict({ a: 1, b: 2 }, { a: 1, b: 2 });
26602660
// OK
26612661

2662-
assert.deepMatchStrict({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
2662+
assert.partialDeepEqualStrict({ a: { b: { c: 1 } } }, { a: { b: { c: 1 } } });
26632663
// OK
26642664

2665-
assert.deepMatchStrict({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
2665+
assert.partialDeepEqualStrict({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 });
26662666
// OK
26672667

2668-
assert.deepMatchStrict({ a: 1 }, { a: 1, b: 2 });
2668+
assert.partialDeepEqualStrict({ a: 1 }, { a: 1, b: 2 });
26692669
// AssertionError
26702670

2671-
assert.deepMatchStrict({ a: 1, b: '2' }, { a: 1, b: 2 });
2671+
assert.partialDeepEqualStrict({ a: 1, b: '2' }, { a: 1, b: 2 });
26722672
// AssertionError
26732673

2674-
assert.deepMatchStrict({ a: { b: 2 } }, { a: { b: '2' } });
2674+
assert.partialDeepEqualStrict({ a: { b: 2 } }, { a: { b: '2' } });
26752675
// AssertionError
26762676
```
26772677

@@ -2803,8 +2803,6 @@ parameter is an instance of an [`Error`][] then it will be thrown instead of the
28032803
[`WeakMap`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap
28042804
[`WeakSet`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet
28052805
[`assert.deepEqual()`]: #assertdeepequalactual-expected-message
2806-
[`assert.deepMatch()`]: #assertdeepmatchactual-expected-message
2807-
[`assert.deepMatchStrict()`]: #assertdeepmatchstrictactual-expected-message
28082806
[`assert.deepStrictEqual()`]: #assertdeepstrictequalactual-expected-message
28092807
[`assert.doesNotThrow()`]: #assertdoesnotthrowfn-error-message
28102808
[`assert.equal()`]: #assertequalactual-expected-message
@@ -2815,6 +2813,8 @@ parameter is an instance of an [`Error`][] then it will be thrown instead of the
28152813
[`assert.notEqual()`]: #assertnotequalactual-expected-message
28162814
[`assert.notStrictEqual()`]: #assertnotstrictequalactual-expected-message
28172815
[`assert.ok()`]: #assertokvalue-message
2816+
[`assert.partialDeepEqual()`]: #assertpartialDeepEqualactual-expected-message
2817+
[`assert.partialDeepEqualStrict()`]: #assertpartialDeepEqualstrictactual-expected-message
28182818
[`assert.strictEqual()`]: #assertstrictequalactual-expected-message
28192819
[`assert.throws()`]: #assertthrowsfn-error-message
28202820
[`getColorDepth()`]: tty.md#writestreamgetcolordepthenv

lib/assert.js

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@
2121
'use strict';
2222

2323
const {
24+
ArrayFrom,
2425
ArrayIsArray,
26+
ArrayPrototypeEvery,
2527
ArrayPrototypeIndexOf,
2628
ArrayPrototypeJoin,
2729
ArrayPrototypePush,
2830
ArrayPrototypeShift,
2931
ArrayPrototypeSlice,
32+
ArrayPrototypeSome,
3033
Error,
3134
ErrorCaptureStackTrace,
3235
FunctionPrototypeBind,
@@ -636,7 +639,7 @@ function assertIncludes(actual, expected, loose) {
636639
return StringPrototypeIncludes(actual, expected);
637640
}
638641

639-
return expected.every((item) => actual.some((actualItem) => {
642+
return ArrayPrototypeEvery(expected, (item) => ArrayPrototypeSome(actual, (actualItem) => {
640643
// eslint-disable-next-line eqeqeq
641644
return loose ? actualItem == item : actualItem === item;
642645
}));
@@ -668,7 +671,11 @@ function compareBranch(
668671
return false;
669672
}
670673
const safeIterator = FunctionPrototypeCall(SafeMap.prototype[SymbolIterator], actual);
671-
for (const { 0: key, 1: val } of safeIterator) {
674+
const safeIteratorArray = ArrayFrom(safeIterator);
675+
676+
for (let i = 0; i < safeIteratorArray.length; i++) {
677+
const { 0: key, 1: val } = safeIteratorArray[i];
678+
672679
if (!MapPrototypeHas(expected, key)) {
673680
return false;
674681
}
@@ -685,8 +692,10 @@ function compareBranch(
685692
return false;
686693
}
687694
const safeIterator = FunctionPrototypeCall(SafeSet.prototype[SymbolIterator], actual);
688-
for (const item of safeIterator) {
689-
if (!SetPrototypeHas(expected, item)) {
695+
const safeIteratorArray = ArrayFrom(safeIterator);
696+
697+
for (let i = 0; i < safeIteratorArray.length; i++) {
698+
if (!SetPrototypeHas(expected, safeIteratorArray[i])) {
690699
return false;
691700
}
692701
}
@@ -706,16 +715,11 @@ function compareBranch(
706715
return loose ? isDeepEqual(actual, expected) : isDeepStrictEqual(actual, expected);
707716
}
708717

709-
// Check if actual and expected are null or not objects
710-
if (actual == null || expected == null) {
711-
return false;
712-
}
713-
714718
// Use Reflect.ownKeys() instead of Object.keys() to include symbol properties
715719
const keysExpected = ReflectOwnKeys(expected);
716720

717721
// Handle circular references
718-
if (comparedObjects.has(actual)) {
722+
if (SetPrototypeHas(comparedObjects, actual)) {
719723
return true;
720724
}
721725
comparedObjects.add(actual);
@@ -742,7 +746,7 @@ function compareBranch(
742746
* @param {string | Error} [message]
743747
* @returns {void}
744748
*/
745-
assert.deepMatchStrict = function deepMatchStrict(
749+
assert.partialDeepEqualStrict = function partialDeepEqualStrict(
746750
actual,
747751
expected,
748752
message,
@@ -756,8 +760,8 @@ assert.deepMatchStrict = function deepMatchStrict(
756760
actual,
757761
expected,
758762
message,
759-
operator: 'deepMatchStrict',
760-
stackStartFn: deepMatchStrict,
763+
operator: 'partialDeepEqualStrict',
764+
stackStartFn: partialDeepEqualStrict,
761765
});
762766
}
763767
};
@@ -769,7 +773,7 @@ assert.deepMatchStrict = function deepMatchStrict(
769773
* @param {string | Error} [message]
770774
* @returns {void}
771775
*/
772-
assert.deepMatch = function deepMatch(actual, expected, message) {
776+
assert.partialDeepEqual = function partialDeepEqual(actual, expected, message) {
773777
if (arguments.length < 2) {
774778
throw new ERR_MISSING_ARGS('actual', 'expected');
775779
}
@@ -779,12 +783,22 @@ assert.deepMatch = function deepMatch(actual, expected, message) {
779783
actual,
780784
expected,
781785
message,
782-
operator: 'deepMatch',
783-
stackStartFn: deepMatch,
786+
operator: 'partialDeepEqual',
787+
stackStartFn: partialDeepEqual,
784788
});
785789
}
786790
};
787791

792+
function throwIfInvalidIncludesParams(actual, expected) {
793+
if (typeof actual !== 'string' && !ArrayIsArray(actual)) {
794+
throw new ERR_INVALID_ARG_TYPE('actual', ['string', 'Array'], actual);
795+
}
796+
797+
if (typeof expected !== 'string' && !ArrayIsArray(expected)) {
798+
throw new ERR_INVALID_ARG_TYPE('expected', ['string', 'Array'], expected);
799+
}
800+
}
801+
788802
/**
789803
* The inclusion assertion test between two arrays or strings
790804
* @param {Array | string} actual
@@ -797,6 +811,8 @@ assert.includes = function includes(actual, expected, message) {
797811
throw new ERR_MISSING_ARGS('actual', 'expected');
798812
}
799813

814+
throwIfInvalidIncludesParams(actual, expected);
815+
800816
if (!assertIncludes(actual, expected, true)) {
801817
innerFail({
802818
actual,
@@ -821,6 +837,8 @@ assert.includesStrict = function includesStrict(actual, expected, message) {
821837
throw new ERR_MISSING_ARGS('actual', 'expected');
822838
}
823839

840+
throwIfInvalidIncludesParams(actual, expected);
841+
824842
if (!assertIncludes(actual, expected, false)) {
825843
innerFail({
826844
actual,
@@ -1298,7 +1316,7 @@ assert.strict = ObjectAssign(strict, assert, {
12981316
deepEqual: assert.deepStrictEqual,
12991317
notEqual: assert.notStrictEqual,
13001318
notDeepEqual: assert.notDeepStrictEqual,
1301-
deepMatch: assert.deepMatchStrict,
1319+
partialDeepEqual: assert.partialDeepEqualStrict,
13021320
includes: assert.includesStrict,
13031321
});
13041322

0 commit comments

Comments
 (0)