-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
assert: Add support for Map and Set in deepEqual #12142
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
Changes from 1 commit
561561a
f051840
1d6cda6
800ae46
031f6f3
d6baaee
8fb6ebf
acef701
ee131e8
7bc29b0
6bdfcaf
fc5196a
7f9d4d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Cleaned up as per comments in issue Ref: #6416
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -268,7 +268,7 @@ function _deepEqual(actual, expected, strict, memos) { | |
| // a) The same number of owned enumerable properties | ||
| // b) The same set of keys/indexes (although not necessarily the same order) | ||
| // c) Equivalent values for every corresponding key/index | ||
| // d) For Maps, strict-equal keys mapping to deep-equal values | ||
| // d) For Sets and Maps, equal contents | ||
| // Note: this accounts for both named and indexed properties on Arrays. | ||
|
|
||
| // Use memos to handle cycles. | ||
|
|
@@ -291,22 +291,20 @@ function setEquiv(a, b, strict, actualVisitedObjects) { | |
| // assert.deepEqual(new Set(['1', 1]), new Set([1])) | ||
| // | ||
| // In theory, all the items in the first set have a corresponding == value in | ||
| // the second set, but the sets have different sizes. Should they be | ||
| // considered to be non-strict deep equal to one another? Its a silly case, | ||
| // the second set, but the sets have different sizes. Its a silly case, | ||
| // and more evidence that deepStrictEqual should always be preferred over | ||
| // deepEqual. The implementation currently returns false, which is a simpler | ||
| // and faster implementation. | ||
| // deepEqual. The implementation currently returns false, which is simpler | ||
| // and slightly faster. | ||
| if (a.size !== b.size) | ||
| return false; | ||
|
|
||
| var val1, val2; | ||
| outer: for (val1 of a) { | ||
| outer: for (const val1 of a) { | ||
| if (!b.has(val1)) { | ||
| // The value doesn't exist in the second set by reference, so we'll go | ||
| // hunting for something thats deep-equal to it. Note that this is O(n^2) | ||
| // complexity, and will get slower if large, very similar sets / maps are | ||
| // nested inside. Unfortunately there's no real way around this. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it possible to optimize this by only starting the additional search if
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. Thats really clever, and very obvious now that you've pointed it out. Fixed. |
||
| for (val2 of b) { | ||
| for (const val2 of b) { | ||
| if (_deepEqual(val1, val2, strict, actualVisitedObjects)) { | ||
| continue outer; | ||
| } | ||
|
|
@@ -328,8 +326,7 @@ function mapEquiv(a, b, strict, actualVisitedObjects) { | |
| if (a.size !== b.size) | ||
| return false; | ||
|
|
||
| var key1, key2, item1, item2; | ||
| outer: for ([key1, item1] of a) { | ||
| outer: for (const [key1, item1] of a) { | ||
| // To be able to handle cases like: | ||
| // Map([[1, 'a'], ['1', 'b']]) vs Map([['1', 'a'], [1, 'b']]) | ||
| // or: | ||
|
|
@@ -346,7 +343,7 @@ function mapEquiv(a, b, strict, actualVisitedObjects) { | |
|
|
||
| // Hunt for keys which are deep-equal to key1 in b. Just like setEquiv | ||
| // above, this hunt makes this function O(n^2). | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto. |
||
| for ([key2, item2] of b) { | ||
| for (const [key2, item2] of b) { | ||
| // Just for performance. We already checked these keys above. | ||
| if (key2 === key1) | ||
| continue; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -245,4 +245,25 @@ assert.throws(() => | |
| assertNotDeepOrStrict(m1, m2); | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add a case where there is a circular reference?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
|
||
| { | ||
| // Circular references. | ||
| const s1 = new Set(); | ||
| s1.add(s1); | ||
| const s2 = new Set(); | ||
| s2.add(s2); | ||
| assertDeepAndStrictEqual(s1, s2); | ||
|
|
||
| const m1 = new Map(); | ||
| m1.set(2, m1); | ||
| const m2 = new Map(); | ||
| m2.set(2, m2); | ||
| assertDeepAndStrictEqual(m1, m2); | ||
|
|
||
| const m3 = new Map(); | ||
| m3.set(m3, 2); | ||
| const m4 = new Map(); | ||
| m4.set(m4, 2); | ||
| assertDeepAndStrictEqual(m3, m4); | ||
| } | ||
|
|
||
| /* eslint-enable */ | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I think
deepEqualshould be correct to reject sets of different sizes.