Skip to content

Commit

Permalink
assert: add support for Set and Map
Browse files Browse the repository at this point in the history
Previously, assert.deepEqual used on maps and sets was not functioning
correctly.

This change adds support for correctly comparing Maps and Sets.

For Maps, comparison is done by iterating over each item in the first
Map and verifying that the key exists and the value is the same (depending
on whether strict is applied).

For Sets, each item is iterated over in the first Set and checked if it
exists in the other Set.

For both Maps and Sets, the size of both being compared is checked as
well.
  • Loading branch information
evanlucas committed Aug 7, 2015
1 parent 5d2acfb commit 68b723d
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 0 deletions.
37 changes: 37 additions & 0 deletions lib/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
59 changes: 59 additions & 0 deletions test/parallel/test-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

0 comments on commit 68b723d

Please sign in to comment.