Skip to content

Commit 47eb288

Browse files
committed
[Breaking] compare Map, Set, WeakMap, WeakSet matching node assert
Fixes #54. Fixes #46.
1 parent 4856185 commit 47eb288

File tree

4 files changed

+133
-15
lines changed

4 files changed

+133
-15
lines changed

.eslintrc

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
"max-statements-per-line": [2, { "max": 2 }],
1111
"strict": 1,
1212
},
13+
"globals": {
14+
"WeakMap": false,
15+
"WeakSet": false,
16+
},
1317
"overrides": [
1418
{
1519
"files": "example/**",

index.js

+42-1
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,17 @@ var isArray = require('isarray');
77
var isDate = require('is-date-object');
88
var whichBoxedPrimitive = require('which-boxed-primitive');
99
var callBound = require('es-abstract/helpers/callBound');
10+
var whichCollection = require('which-collection');
11+
var getIterator = require('es-get-iterator');
1012

1113
var $getTime = callBound('Date.prototype.getTime');
1214
var gPO = Object.getPrototypeOf;
1315
var $objToString = callBound('Object.prototype.toString');
1416

17+
var $mapHas = callBound('Map.prototype.has', true);
18+
var $mapGet = callBound('Map.prototype.get', true);
19+
var $setHas = callBound('Set.prototype.has', true);
20+
1521
function deepEqual(actual, expected, options) {
1622
var opts = options || {};
1723

@@ -62,7 +68,7 @@ function isBuffer(x) {
6268
}
6369

6470
function objEquiv(a, b, opts) {
65-
/* eslint max-statements: [2, 70], max-lines-per-function: [2, 80] */
71+
/* eslint max-statements: [2, 100], max-lines-per-function: [2, 120], max-depth: [2, 5] */
6672
var i, key;
6773

6874
if (typeof a !== typeof b) { return false; }
@@ -138,6 +144,41 @@ function objEquiv(a, b, opts) {
138144
if (!deepEqual(a[key], b[key], opts)) { return false; }
139145
}
140146

147+
var aCollection = whichCollection(a);
148+
var bCollection = whichCollection(b);
149+
if (aCollection !== bCollection) {
150+
return false;
151+
}
152+
if (aCollection === 'Map' || aCollection === 'Set') {
153+
var iA = getIterator(a);
154+
var iB = getIterator(b);
155+
var resultA;
156+
var resultB;
157+
if (aCollection === 'Map') { // aCollection === bCollection
158+
var aWithBKey;
159+
var bWithAKey;
160+
while ((resultA = iA.next()) && (resultB = iB.next()) && !resultA.done && !resultB.done) {
161+
if (!$mapHas(a, resultB.value[0]) || !$mapHas(b, resultA.value[0])) { return false; }
162+
if (resultA.value[0] === resultB.value[0]) { // optimization: keys are the same, no need to look up values
163+
if (!deepEqual(resultA.value[1], resultB.value[1])) { return false; }
164+
} else {
165+
aWithBKey = $mapGet(a, resultB.value[0]);
166+
bWithAKey = $mapGet(b, resultA.value[0]);
167+
if (!deepEqual(resultA.value[1], bWithAKey) || !deepEqual(resultB.value[1], aWithBKey)) {
168+
return false;
169+
}
170+
}
171+
}
172+
} else if (aCollection === 'Set') { // aCollection === bCollection
173+
while ((resultA = iA.next()) && (resultB = iB.next()) && !resultA.done && !resultB.done) {
174+
if (!$setHas(a, resultB.value) || !$setHas(b, resultA.value)) { return false; }
175+
}
176+
}
177+
if (resultA && resultB && resultA.done !== resultB.done) {
178+
return false;
179+
}
180+
}
181+
141182
return true;
142183
}
143184

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@
3030
},
3131
"dependencies": {
3232
"es-abstract": "^1.16.2",
33+
"es-get-iterator": "^1.0.1",
3334
"is-arguments": "^1.0.4",
3435
"is-date-object": "^1.0.1",
3536
"is-regex": "^1.0.4",
3637
"isarray": "^2.0.5",
3738
"object-is": "^1.0.1",
3839
"object-keys": "^1.1.1",
3940
"regexp.prototype.flags": "^1.2.0",
40-
"which-boxed-primitive": "^1.0.1"
41+
"which-boxed-primitive": "^1.0.1",
42+
"which-collection": "^1.0.0"
4143
},
4244
"devDependencies": {
4345
"@ljharb/eslint-config": "^15.0.2",

test/cmp.js

+84-13
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,110 @@ test('equal', function (t) {
1313
false
1414
);
1515

16+
t.end();
17+
});
18+
19+
test('Maps', { skip: typeof Map !== 'function' }, function (t) {
1620
t.deepEqualTest(
1721
new Map([['a', 1], ['b', 2]]),
1822
new Map([['b', 2], ['a', 1]]),
1923
'two equal Maps',
2024
true,
21-
true,
25+
true
26+
);
27+
28+
t.deepEqualTest(
29+
new Map([['a', [1, 2]]]),
30+
new Map([['a', [2, 1]]]),
31+
'two Maps with inequal values on the same key',
32+
false,
33+
false
34+
);
35+
36+
t.deepEqualTest(
37+
new Map([['a', 1]]),
38+
new Map([['b', 1]]),
39+
'two inequal Maps',
40+
false,
2241
false
2342
);
2443

2544
t.end();
2645
});
2746

28-
test('not equal', function (t) {
47+
test('WeakMaps', { skip: typeof WeakMap !== 'function' }, function (t) {
2948
t.deepEqualTest(
30-
{ x: 5, y: [6] },
31-
{ x: 5, y: 6 },
32-
'two inequal objects are',
33-
false,
34-
false
49+
new WeakMap([[Object, null], [Function, true]]),
50+
new WeakMap([[Function, true], [Object, null]]),
51+
'two equal WeakMaps',
52+
true,
53+
true
3554
);
3655

3756
t.deepEqualTest(
38-
new Map([['a', [1, 2]]]),
39-
new Map([['a', [2, 1]]]),
40-
'two Maps with inequal values on the same key',
57+
new WeakMap([[Object, null]]),
58+
new WeakMap([[Object, true]]),
59+
'two WeakMaps with inequal values on the same key',
60+
true,
61+
true
62+
);
63+
64+
t.deepEqualTest(
65+
new WeakMap([[Object, null], [Function, true]]),
66+
new WeakMap([[Object, null]]),
67+
'two inequal WeakMaps',
68+
true,
69+
true
70+
);
71+
72+
t.end();
73+
});
74+
75+
test('Sets', { skip: typeof Set !== 'function' }, function (t) {
76+
t.deepEqualTest(
77+
new Set(['a', 1, 'b', 2]),
78+
new Set(['b', 2, 'a', 1]),
79+
'two equal Sets',
80+
true,
81+
true
82+
);
83+
84+
t.deepEqualTest(
85+
new Set(['a', 1]),
86+
new Set(['b', 1]),
87+
'two inequal Sets',
4188
false,
4289
false
4390
);
4491

92+
t.end();
93+
});
94+
95+
test('WeakSets', { skip: typeof WeakSet !== 'function' }, function (t) {
4596
t.deepEqualTest(
46-
new Map([['a', 1]]),
47-
new Map([['b', 1]]),
48-
'two inequal Maps',
97+
new WeakSet([Object, Function]),
98+
new WeakSet([Function, Object]),
99+
'two equal WeakSets',
100+
true,
101+
true
102+
);
103+
104+
t.deepEqualTest(
105+
new WeakSet([Object, Function]),
106+
new WeakSet([Object]),
107+
'two inequal WeakSets',
108+
true,
109+
true
110+
);
111+
112+
t.end();
113+
});
114+
115+
test('not equal', function (t) {
116+
t.deepEqualTest(
117+
{ x: 5, y: [6] },
118+
{ x: 5, y: 6 },
119+
'two inequal objects are',
49120
false,
50121
false
51122
);

0 commit comments

Comments
 (0)