Skip to content
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

Closed
wants to merge 2 commits into from

Conversation

BridgeAR
Copy link
Member

@BridgeAR BridgeAR commented Aug 27, 2017

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.

AssertionError [ERR_ASSERTION]: [Number: NaN] deepStrictEqual [Number: NaN]
    at Object.<anonymous> (/node/test/addons-napi/test_conversions/test.js:119:8)

Update: I commented out the failing test for now.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

assert

@BridgeAR BridgeAR added the blocked PRs that are blocked by other issues or PRs. label Aug 27, 2017
@nodejs-github-bot nodejs-github-bot added the assert Issues and PRs related to the assert subsystem. label Aug 27, 2017
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();
Copy link
Member

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 ?

@BridgeAR
Copy link
Member Author

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.

@BridgeAR BridgeAR removed the blocked PRs that are blocked by other issues or PRs. label Aug 29, 2017
@jasnell
Copy link
Member

jasnell commented Aug 29, 2017

Curious about the semver-iness of this change. Thoughts @nodejs/tsc?

Copy link
Member

@jasnell jasnell left a 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

@BridgeAR
Copy link
Member Author

@BridgeAR
Copy link
Member Author

BridgeAR commented Sep 1, 2017

Rebased due to conflicts.

@BridgeAR
Copy link
Member Author

BridgeAR commented Sep 2, 2017

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));
Copy link
Member

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?

Copy link
Member Author

@BridgeAR BridgeAR Sep 2, 2017

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.

Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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?

Copy link
Member Author

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.

@nodejs nodejs deleted a comment Sep 2, 2017
@nodejs nodejs deleted a comment Sep 2, 2017
@nodejs nodejs deleted a comment Sep 2, 2017
// 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') {
Copy link
Member

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..

Copy link
Member Author

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.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

@BridgeAR BridgeAR requested a review from Trott September 4, 2017 12:41
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.
Copy link
Member

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.

Copy link
Member

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?

Copy link
Member Author

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.

@@ -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.
Copy link
Member

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...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion!

Unbox all primitives and compare them as well instead of
only comparing boxed strings.
@BridgeAR
Copy link
Member Author

BridgeAR commented Sep 5, 2017

Rebased due to conflicts

Copy link
Member

@Trott Trott left a 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.

@joyeecheung
Copy link
Member

LGTM with the commented test uncommented

@BridgeAR
Copy link
Member Author

BridgeAR commented Sep 12, 2017

Landed in 22ae8c0

@BridgeAR BridgeAR closed this Sep 12, 2017
BridgeAR added a commit that referenced this pull request Sep 12, 2017
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]>
addaleax pushed a commit to addaleax/node that referenced this pull request Sep 13, 2017
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]>
@jasnell
Copy link
Member

jasnell commented Sep 20, 2017

this would need to be backported for v8.x

BridgeAR added a commit to BridgeAR/node that referenced this pull request Sep 21, 2017
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]>
jasnell pushed a commit that referenced this pull request Sep 21, 2017
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]>
@BridgeAR BridgeAR deleted the assert-boxed branch April 1, 2019 23:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
assert Issues and PRs related to the assert subsystem.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants