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: use Object.is comparison in .strictEqual #17003

Closed
wants to merge 2 commits into from

Conversation

BridgeAR
Copy link
Member

This aligns assert.strictEqual and assert.notStrictEqual with
assert.deepStrictEqual to use the Object.is() comparison instead
of strict equality.

It looked somewhat nicer with === but I think it makes sense to use the equality checks in both functions.

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 assert Issues and PRs related to the assert subsystem. semver-major PRs that contain breaking changes and should be released in the next major version. labels Nov 13, 2017
@nodejs-github-bot nodejs-github-bot added the assert Issues and PRs related to the assert subsystem. label Nov 13, 2017
@addaleax
Copy link
Member

I am a bit worried about NaN tbh … I know I’ve used it quite a bit in tests that I have written

@BridgeAR
Copy link
Member Author

Well, I do not have strong feelings about this. I am fine to close this again but it seemed like it makes sense to align both equality comparisons. So I would like to get some more opinions before closing it again.

@mscdex
Copy link
Contributor

mscdex commented Nov 13, 2017

Is Object.is() still slow?

Also, you should be able to do a simple NaN equality check with something like:

if (actual !== actual && expected !== expected) {
 // actual === NaN && expected === NaN
}

Copy link
Member

@addaleax addaleax left a comment

Choose a reason for hiding this comment

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

LGTM if CITGM is fine with it

I guess if it’s too bad we’ll have more than enough time to revert before Node 10 :)

@@ -7,6 +7,9 @@
The `assert` module provides a simple set of assertion tests that can be used to
test invariants.

For more information about the used equality comparisons see
[MDN's guide on equality comparisons and sameness][mdn-equality-guide].
Copy link
Member

Choose a reason for hiding this comment

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

Is this unrelated? Or is this doc change due to the change in the code?

Copy link
Member Author

Choose a reason for hiding this comment

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

I removed the Caveats part as there are non left but I felt like this would still be a valuable information from that part, so I moved it to the top.

@BridgeAR
Copy link
Member Author

@mscdex Object.is is still slower with v8 6.2. It should be on par from 6.3 on. I can optimize it as the following but it is a lot more verbose and not that good to read (untested, just written down quickly).

// assert.strictEqual
if (actual === expected) {
  if (actual === 0 && !Object.is(actual, expected))
    fail()
} else (actual === actual || expected === expected) {
  fail();
}

// assert.notStrictEqual
if (actual !== expected) {
  if (actual !== actual && expected !== expected)
    fail()
} else (actual !== 0 || !Object.is(actual, expected)) {
  fail();
}

As this is semver-major though, I would rather stick to the plain Object.is (v.10 should work with v8 >= 6.3).

Copy link
Member

@joyeecheung joyeecheung left a comment

Choose a reason for hiding this comment

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

LGTM if CITGM is fine with it

Copy link
Member

@TimothyGu TimothyGu left a comment

Choose a reason for hiding this comment

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

This deserves a documentation change warning users that "strictEqual" doesn't actually use strict equality. A YAML annotation showing which version this behavior changed is also essential, because I anticipate many many people are going to see broken tests because of this.

This aligns assert.strictEqual and assert.notStrictEqual with
assert.deepStrictEqual to use the Object.is() comparison instead
of strict equality.
@BridgeAR
Copy link
Member Author

@TimothyGu very good point! I updated the documentation accordingly.

Copy link
Member

@TimothyGu TimothyGu left a comment

Choose a reason for hiding this comment

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

Compatibility still concerns me, but the code changes LGTM.

jasnell pushed a commit that referenced this pull request Nov 22, 2017
This aligns assert.strictEqual and assert.notStrictEqual with
assert.deepStrictEqual to use the Object.is() comparison instead
of strict equality.

PR-URL: #17003
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@jasnell
Copy link
Member

jasnell commented Nov 22, 2017

Landed in 493340f

@jasnell jasnell closed this Nov 22, 2017
@MylesBorins
Copy link
Contributor

It would appear that the citgm results were not looked at. This broke the test suite for eslint.

  1) RuleTester should throw an error when the error message is wrong:
     AssertionError: expected [Function] to throw error matching /Bad var\..*==.*Bad error message/ but got '\'Bad var.\' strictEqual \'Bad error message.\''
      at Context.it (tests/lib/testers/rule-tester.js:118:16)

  2) RuleTester should throw an error when the error is a string and it does not match error message:
     AssertionError: expected [Function] to throw error matching /Bad var\..*==.*Bad error message/ but got '\'Bad var.\' strictEqual \'Bad error message.\''
      at Context.it (tests/lib/testers/rule-tester.js:159:16)

Should we consider reverting this or is this something the eslint test suite should fix?

@MylesBorins
Copy link
Contributor

Sent PR to ESLint

eslint/eslint#9688

this was due to the change in the reported error message. This is likely going to nail anyone who was grepping the text of the strictEqual or notStrictEqual output... do we think this breakage is worth it? It is going to result in some gross legacy code like https://github.com/eslint/eslint/pull/9688/files#diff-0b8e8fdd097af4021779e0f5c567281fR129 in order to support both the old and new message.

@BridgeAR
Copy link
Member Author

BridgeAR commented Dec 6, 2017

@MylesBorins in general the changed error message might produce some more breakage but that should be limited to tests.

What we could do is to use === and !== in case the input does not contain NaN or +-0. That would reduce the breaking change in most cases but it would be somewhat inconsistent to the used comparison. I personally feel like the change here is similar to any error message that we change and land as semver-major.

@SimenB
Copy link
Member

SimenB commented Dec 9, 2017

(More as a datapoint than anything else)

This is gonna break Jest's test suite as well. Not as clean to fix as eslint due to Jest dumping the full output as a snapshot. https://github.com/facebook/jest/blob/ca1793e01eaf81497ad1985547bfa19c297881c5/integration_tests/__tests__/__snapshots__/failures.test.js.snap#L224-L252.

We already need a ugly hack (jestjs/jest#4851) for the change in node 9 (not merged as we have some issues with hanging tests on node 9 (#17040)), so we'll probably just work around it for 10 as well.

+1 for this change in general though, we made the same change in jest for the upcoming 22 🙂

@gibfahn
Copy link
Member

gibfahn commented Dec 28, 2017

do we think this breakage is worth it?

+1 for this change in general though, we made the same change in jest for the upcoming 22 🙂

At least for me, this is the information that's really useful, whether the people affected by the break agree that the new behaviour is worth having to patch their code. Given the lack of negative response, I'd say no need to revert.

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. semver-major PRs that contain breaking changes and should be released in the next major version.
Projects
None yet
Development

Successfully merging this pull request may close these issues.