-
Notifications
You must be signed in to change notification settings - Fork 30.7k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
assert: deepEqual of two Sets with different content passes #13347
Comments
I can reproduce. assert.deepEqual(new Set([{a: 1}, {a: 1}]), new Set([{b: 1}, {b: 2}]));
assert.deepStrictEqual(new Set([{a: 1}, {a: 1}]), new Set([{b: 1}, {b: 2}])); This also fails: assert.deepEqual(new Set([{a: 1}]), new Set([{a: 2}]));
assert.deepStrictEqual(new Set([{a: 1}]), new Set([{a: 2}])); |
сс @nodejs/testing |
Errr, yep this is a bug.
There's two semantics going on here:
So you've made a set with two different objects that are considered identical by deepEqual. As far as deepEqual should be concerned, is this equivalent to a set with only one Anyway, after a long discussion deep equality comparison currently works by doing this:
The .size comparison uses the semantics of sets - that is, internal reference equality. The pairwise item comparisons uses the semantics of
(... although then step 1 isn't needed anymore, and might cause more bugs?) Alternately, we could track which items of set 2 have already been consumed by the matching. So:
.. Which I think is correct. |
And, maps have the equivalent logic & same bug: assert.deepEqual(new Map([[{x:1}, 5], [{x:1}, 5]]), new Map([[{x:1}, 5], [{x:2}, 5]]))
assert.deepStrictEqual(new Map([[{x:1}, 5], [{x:1}, 5]]), new Map([[{x:1}, 5], [{x:2}, 5]])) |
Is it still needed with this approach to prevent this from being equal? assert.deepStrictEqual(new Set([{a: 1}, {a: 1}]), new Set([{a: 1}])) |
.... Er, yeah, sure is @vsemozhetbyt :) Actually the first method would consider these sets to be equal: new Set([{a:1}, {a:1}, {a:2}])
new Set([{a:1}, {a:2}, {a:2}]) So we should fix this using the second method. |
This fixes a bug where deepEqual and deepStrictEqual would have incorrect behaviour in sets and maps containing multiple equivalent keys. Fixes: nodejs#13347 Refs: nodejs#12142
This also fails to throw, due to the same bug: assert.deepEqual(new Set([3, '3']), new Set([3, 4]));
// and
assert.deepEqual(new Map([[3, 0], ['3', 0]]), new Map([[3, 0], [4, 0]]); |
A simpler case... and heads up by a bro from lodash.js assert.deepEqual( new Map([['x', 'y']]),
new Map([['y', 'x']]) ); // Doesn't throw I assert that this is fixed in v8.7.0. |
Primitive support for map and set equality wasn't added until node 8. In node 6 all maps and all sets are considered equivalent. These also didn't throw in node 7 and below: assert.deepEqual(new Map(), new Map())
assert.deepEqual(new Map(), new Set()) |
Both of these checks passes, while I would expect them to fail.
The text was updated successfully, but these errors were encountered: