assert: make Maps be partially compared in partialDeepStrictEqual

PR-URL: https://github.com/nodejs/node/pull/56195
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Pietro Marchini <pietro.marchini94@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
Giovanni Bucci 2024-12-11 16:10:53 +01:00 committed by GitHub
parent b6c9dbe7e1
commit 9ec8b9e512
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 84 additions and 9 deletions

View File

@ -385,22 +385,26 @@ const typesToCallDeepStrictEqualWith = [
isKeyObject, isWeakSet, isWeakMap, Buffer.isBuffer, isSharedArrayBuffer,
];
function compareMaps(actual, expected, comparedObjects) {
if (MapPrototypeGetSize(actual) !== MapPrototypeGetSize(expected)) {
function partiallyCompareMaps(actual, expected, comparedObjects) {
if (MapPrototypeGetSize(expected) > MapPrototypeGetSize(actual)) {
return false;
}
const safeIterator = FunctionPrototypeCall(SafeMap.prototype[SymbolIterator], actual);
comparedObjects ??= new SafeWeakSet();
const expectedIterator = FunctionPrototypeCall(SafeMap.prototype[SymbolIterator], expected);
for (const { 0: key, 1: val } of safeIterator) {
if (!MapPrototypeHas(expected, key)) {
for (const { 0: key, 1: expectedValue } of expectedIterator) {
if (!MapPrototypeHas(actual, key)) {
return false;
}
if (!compareBranch(val, MapPrototypeGet(expected, key), comparedObjects)) {
const actualValue = MapPrototypeGet(actual, key);
if (!compareBranch(actualValue, expectedValue, comparedObjects)) {
return false;
}
}
return true;
}
@ -553,7 +557,7 @@ function compareBranch(
) {
// Check for Map object equality
if (isMap(actual) && isMap(expected)) {
return compareMaps(actual, expected, comparedObjects);
return partiallyCompareMaps(actual, expected, comparedObjects);
}
if (

View File

@ -169,12 +169,26 @@ describe('Object Comparison Tests', () => {
},
{
description:
'throws when comparing two Map objects with different length',
'throws when the expected Map has more entries than the actual Map',
actual: new Map([
['key1', 'value1'],
['key2', 'value2'],
]),
expected: new Map([['key1', 'value1']]),
expected: new Map([
['key1', 'value1'],
['key2', 'value2'],
['key3', 'value3'],
]),
},
{
description: 'throws when the nested array in the Map is not a subset of the other nested array',
actual: new Map([
['key1', ['value1', 'value2']],
['key2', 'value2'],
]),
expected: new Map([
['key1', ['value3']],
]),
},
{
description:
@ -564,6 +578,63 @@ describe('Object Comparison Tests', () => {
['key2', 'value2'],
]),
},
{
description:
'compares two Map objects where expected is a subset of actual',
actual: new Map([
['key1', 'value1'],
['key2', 'value2'],
]),
expected: new Map([['key1', 'value1']]),
},
{
description:
'compares two deeply nested Maps',
actual: {
a: {
b: {
c: new Map([
['key1', 'value1'],
['key2', 'value2'],
])
},
z: [1, 2, 3]
}
},
expected: {
a: {
z: [1, 2, 3],
b: {
c: new Map([['key1', 'value1']])
}
}
},
},
{
description: 'compares Maps nested into Maps',
actual: new Map([
['key1', new Map([
['nestedKey1', 'nestedValue1'],
['nestedKey2', 'nestedValue2'],
])],
['key2', 'value2'],
]),
expected: new Map([
['key1', new Map([
['nestedKey1', 'nestedValue1'],
])],
])
},
{
description: 'compares Maps with nested arrays inside',
actual: new Map([
['key1', ['value1', 'value2']],
['key2', 'value2'],
]),
expected: new Map([
['key1', ['value1', 'value2']],
]),
},
{
description:
'compares two objects with identical getter/setter properties',