-
Notifications
You must be signed in to change notification settings - Fork 29.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in 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]]); |
This fixes a bug where deepEqual and deepStrictEqual would have incorrect behaviour in sets and maps containing multiple equivalent keys. PR-URL: #13426 Fixes: #13347 Refs: #12142 Reviewed-By: Refael Ackermann <[email protected]>
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: