Skip to content

Commit

Permalink
assert: make Maps be partially compared in partialDeepStrictEqual
Browse files Browse the repository at this point in the history
PR-URL: #56195
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: Pietro Marchini <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
  • Loading branch information
puskin94 authored Dec 11, 2024
1 parent b6c9dbe commit 9ec8b9e
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 9 deletions.
18 changes: 11 additions & 7 deletions lib/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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 (
Expand Down
75 changes: 73 additions & 2 deletions test/parallel/test-assert-objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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',
Expand Down

0 comments on commit 9ec8b9e

Please sign in to comment.