-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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: fix boxed primitives in deep*Equal #15050
Conversation
lib/assert.js
Outdated
@@ -203,6 +203,11 @@ function strictDeepEqual(actual, expected) { | |||
Object.keys(expected).length === expected.length) { | |||
return true; | |||
} | |||
} else if (typeof actual.valueOf === 'function') { | |||
const rawA = actual.valueOf(); |
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.
rawA [](start = 10, length = 4)
nit: can you have better name like rawAcual
?
I rebased due to conflicts, addressed the nit and added a fast path for boxed primitives. I also commented out the failing test, so now it is not blocked anymore. |
Curious about the semver-iness of this change. Thoughts @nodejs/tsc? |
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.
The code change LGTM but I'd like a CITGM run and others from @nodejs/tsc to sign off
b2887a7
to
fd96e26
Compare
Rebased due to conflicts. |
Ping @nodejs/ctc @nodejs/tsc PTAL |
@@ -116,7 +116,8 @@ assert.deepStrictEqual(new Boolean(false), test.toObject(false)); | |||
assert.deepStrictEqual(new Boolean(true), test.toObject(true)); | |||
assert.deepStrictEqual(new String(''), test.toObject('')); | |||
assert.deepStrictEqual(new Number(0), test.toObject(0)); | |||
assert.deepStrictEqual(new Number(Number.NaN), test.toObject(Number.NaN)); | |||
// TODO: Add test back in as soon as NaN is properly compared | |||
// assert.deepStrictEqual(new Number(Number.NaN), test.toObject(Number.NaN)); |
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.
Can we remove the todo and add the test back?
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.
Not before #15036 landed (still trying to figure out if that one should be semver-major or a patch though). Otherwise the test would fail.
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.
what's the depedency of this change to #15036?
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.
Currently assert.deepStrictEqual(NaN, NaN)
will fail. This test only worked because NaN
was never compared as it was not unboxed before. #15036 will change that to not fail anymore in case NaN
is compared to itself.
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.
Have you pushed you changes to this PR? Looks like these lines are still commented?
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.
Thanks a lot for reminding me! It is now back in place.
// Buffer.compare returns true, so actual.length === expected.length | ||
// if they both only contain numeric keys, we don't need to exam further | ||
if (Object.keys(actual).length === actual.length && | ||
Object.keys(expected).length === expected.length) { | ||
return true; | ||
} | ||
} else if (typeof actual.valueOf === 'function') { |
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.
IIUC this also affects objects with custom valueOf
, so the documentation needs to be updated as well..
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.
You are right! I am going to add that to the documentation.
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.
Addressed
doc/api/assert.md
Outdated
assert.deepStrictEqual({}, new Number(1)); | ||
// Fails as the wrapped number is unwrapped and compared as well. | ||
assert.deepStrictEqual(new String('foo'), Object('foo')); | ||
// Ok, both objects and strings are unwrapped identical. |
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.
Nit: Perhaps change the comment to something like:
OK because the object and the string are identical when unwrapped.
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'm confused by this documentation. It's supposed to document new behavior you're adding, right? But the assertions here are already fail/succeed as described in Node.js 8.4.0 so the behavior isn't because of any changes added here. Am I misunderstanding?
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.
Changed. I indeed chose a bad example for the number and updated that. Currently only wrapped strings are compared but in my former example with the wrapped number, the toString()
was not identical and it failed early.
doc/api/assert.md
Outdated
@@ -161,6 +162,11 @@ assert.deepEqual(date, fakeDate); | |||
assert.deepStrictEqual(date, fakeDate); | |||
// AssertionError: 2017-03-11T14:25:31.849Z deepStrictEqual Date {} | |||
// Different type tags | |||
|
|||
assert.deepStrictEqual({}, new Number(1)); | |||
// Fails as the wrapped number is unwrapped and compared as well. |
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.
Micro-nit: Fails as the wrapped number is...
-> Fails because the wrapped number is...
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.
Thanks for the suggestion!
320cfae
to
af780c9
Compare
Unbox all primitives and compare them as well instead of only comparing boxed strings.
af780c9
to
66432d8
Compare
Rebased due to conflicts |
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.
Seems good to me. I've refrained from giving at a green check because I worry I may not be grasping all the ramifications.
LGTM with the commented test uncommented |
Landed in 22ae8c0 |
Unbox all primitives and compare them as well instead of only comparing boxed strings. PR-URL: #15050 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
Unbox all primitives and compare them as well instead of only comparing boxed strings. PR-URL: nodejs#15050 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
this would need to be backported for v8.x |
Unbox all primitives and compare them as well instead of only comparing boxed strings. PR-URL: nodejs#15050 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
Unbox all primitives and compare them as well instead of only comparing boxed strings. PR-URL: #15050 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
Unbox all primitives and compare them as well instead of
only comparing boxed strings.
This is blocked by #15036 because there is a test case from N-API that currently only passes because deepStrictEqual is not testing them properly and this hides the underlying NaN issue.Update: I commented out the failing test for now.
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
assert