You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
assert: deepEqual of two Sets with different content passes #13347
assert.deepStrictEqual(new Set([{a: 1}, {a: 1}]), new Set([{a: 1}, {a: 2}]))
There's two semantics going on here:
In a set, these objects are different: {a:1} and {a:1} because they aren't references to the same object.
In deep[Strict]Equal, they are the same.
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 {a:1} in it? Its sort of weird.
Anyway, after a long discussion deep equality comparison currently works by doing this:
Assert the sets have identical .size
For each item in set 1, find an equivalent item in set 2
The .size comparison uses the semantics of sets - that is, internal reference equality. The pairwise item comparisons uses the semantics of deepEqual / deepStrictEqual. And hence the bug.
We could fix it by changing the code to do it both ways around:(Edit: This is also buggy - see my comment below)
Assert the sets have identical .size
For each item in set 1, find an equivalent item in set 2
For each item in set 2, find an equivalent item in set 1
(... 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:
Assert the sets have identical .size
For each item in set 1, find an equivalent item in set 2 that hasn't already been used
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:
Activity
vsemozhetbyt commentedon May 31, 2017
I can reproduce.
This fails:
This also fails:
vsemozhetbyt commentedon May 31, 2017
сс @nodejs/testing
vsemozhetbyt commentedon May 31, 2017
Also cc @josephg due to #12142
josephg commentedon May 31, 2017
Errr, yep this is a bug.
There's two semantics going on here:
{a:1}and{a:1}because they aren't references to the same object.deep[Strict]Equal, they are the same.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
{a:1}in it? Its sort of weird.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
deepEqual/deepStrictEqual. And hence the bug.We could fix it by changing the code to do it both ways around:(Edit: This is also buggy - see my comment below)(... 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.
josephg commentedon May 31, 2017
And, maps have the equivalent logic & same bug:
vsemozhetbyt commentedon May 31, 2017
Is it still needed with this approach to prevent this from being equal?
josephg commentedon May 31, 2017
.... Er, yeah, sure is @vsemozhetbyt :)
Actually the first method would consider these sets to be equal:
So we should fix this using the second method.
josephg commentedon Jun 3, 2017
This also fails to throw, due to the same bug:
assert: fix deepEqual similar sets and maps bug
assert: fix deepEqual similar sets and maps bug
escKeyStroke commentedon Oct 17, 2017
A simpler case
... and heads up by a bro from lodash.js
(version 6.11.4, Windows x64)
I assert that this is fixed in v8.7.0.
josephg commentedon Oct 17, 2017
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: