diff --git a/lib/assert.js b/lib/assert.js index ea142ed01f8f6e..ef49f251bab497 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -185,6 +185,36 @@ function isArguments(object) { return Object.prototype.toString.call(object) == '[object Arguments]'; } +function compareMaps(a, b, strict) { + // check size of the maps + if (a.size !== b.size) + return false; + + // iterate over all keys and check if they exist in the other + for (let kvs of a) { + const key = kvs[0]; + const val = kvs[1]; + if (!b.has(key)) { + return false; + } + + if (!_deepEqual(val, b.get(key), strict)) + return false; + } + return true; +} + +function compareSets(a, b) { + if (a.size !== b.size) + return false; + + for (let item of a) { + if (!b.has(item)) + return false; + } + return true; +} + function objEquiv(a, b, strict) { if (a === null || a === undefined || b === null || b === undefined) return false; @@ -202,6 +232,13 @@ function objEquiv(a, b, strict) { b = pSlice.call(b); return _deepEqual(a, b, strict); } + const aStr = Object.prototype.toString.call(a); + const bStr = Object.prototype.toString.call(b); + if (aStr === '[object Map]' && bStr === '[object Map]') { + return compareMaps(a, b, strict); + } else if (aStr === '[object Set]' && bStr === '[object Set]') { + return compareSets(a, b); + } var ka = Object.keys(a), kb = Object.keys(b), key, i; diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index ce84eabc34e1d4..ed99b01f91ec69 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -465,4 +465,63 @@ testBlockTypeError(assert.doesNotThrow, null); testBlockTypeError(assert.throws, undefined); testBlockTypeError(assert.doesNotThrow, undefined); +// Map deep equal, deep strict equal +const map1 = new Map(); +const map2 = new Map(); +map1.set('1', '2'); +map2.set('1', '2'); +assert.deepEqual(map1, map2); +map1.set('2', '2'); +assert.throws(function() { + assert.deepEqual(map1, map2); +}); +map1.delete('2'); +map2.set('1', 2); +assert.deepEqual(map1, map2); +assert.throws(function() { + assert.deepStrictEqual(map1, map2); +}); +map1.clear(); +map2.clear(); +map1.set(NaN, 'not a number'); +map2.set(NaN, 'not a number'); +assert.deepEqual(map1, map2); +map1.clear(); +map2.clear(); +map1.set('1', { name: 'test' }); +map2.set('1', { name: 'test' }); +assert.deepStrictEqual(map1, map2); +map1.clear(); +map2.clear(); +// verify that insertion order doesn't matter +map1.set('1', '1'); +map1.set('2', '2'); +map2.set('2', '2'); +map2.set('1', '1'); +assert.deepEqual(map1, map2); + +// Set deep equal, deep strict equal +var set1 = new Set(); +var set2 = new Set(); +set1.add(1); +set2.add(1); +assert.deepEqual(set1, set2); +set1.add(2); +assert.throws(function() { + assert.deepEqual(set1, set2); +}); +set1.delete(2); +set2.delete(1); +set2.add('1'); +// throws because we can't really check without being strict +assert.throws(function() { + assert.deepEqual(set1, set2); +}); + +assert.deepEqual(new Set([NaN]), new Set([NaN])); +// verify that insertion order doesn't matter +set1 = new Set([1, 2]); +set2 = new Set([2, 1]); +assert.deepEqual(set1, set2); + console.log('All OK');