Repository: nodejs/node
Pull request: assert: make Maps be partially compared in partialDeepStrictEqual

Other PR aiming to make the `assert.partialDeepStrictEqual` function more complete.  
Since the introduction of the function in [here](https://github.com/nodejs/node/pull/54630) the `Map` comparison has been introduced as `strict`, making examples as the following not possible (e.g. `expected` is a subset of `actual` ):

```javascript
const assert = require('assert');

const actual = new Map([
  ['key1', 'value1'],
  ['key2', 'value2'],
  ['key3', 'value3'],
])

const expected = new Map([
  ['key1', 'value1'],
  ['key2', 'value2'],
])

assert.partialDeepStrictEqual(actual, expected);
```

This PR makes `assert.partialDeepStrictEqual` work with partial Map comparisons

Changed files:
filename: lib/assert.js
patch: @@ -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 (

filename: test/parallel/test-assert-objects.js
patch: @@ -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',