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

handle negative infinity timeout #165

Merged
merged 1 commit into from
May 8, 2018
Merged

Conversation

SimenB
Copy link
Member

@SimenB SimenB commented May 7, 2018

See this issue in Jest, with links to spec: jestjs/jest#5960. Without changing the implementation of Lolex, Jest test suite breaks when attempting to use it

calls.push("-Infinity");
}, Number.NEGATIVE_INFINITY);
this.clock.runAll();
assert.equals(calls, ["NaN", "Infinity", "-Infinity"]);
Copy link
Member Author

Choose a reason for hiding this comment

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

without the code change, -Infinity is before Infinity in the array

src/lolex-src.js Outdated
@@ -196,6 +208,9 @@ function addTimer(clock, timer) {
timer.type = timer.immediate ? "Immediate" : "Timeout";

if (timer.hasOwnProperty("delay")) {
if (!isNumberFinite(timer.delay)) {
Copy link
Member

Choose a reason for hiding this comment

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

So I checked - the spec actually says (if < 0 then = 0) but Infinity isn't explicitly treated - >Int32 numbers overflow and also get set to 0 but not explicitly.

Node on the other hand sets the value to 1 (and not 0) https://github.com/nodejs/node/blob/master/lib/internal/timers.js#L19 done in https://github.com/nodejs/node/blob/master/lib/internal/timers.js#L55

Copy link
Member

Choose a reason for hiding this comment

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

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've never read much spec, so all questions are in good faith)

From the linked issue in Jest, I read it as point 8 in https://heycam.github.io/webidl/#abstract-opdef-converttoint (as it's a long, not EnforceRange), namely

If x is NaN, +0, +∞, or −∞, then return +0.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, exactly.

Copy link
Member Author

@SimenB SimenB May 8, 2018

Choose a reason for hiding this comment

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

Oh, so we are in agreement. Cool! 😀

Do you think it's a bug in Node?

I suppose it's easy enough to emulate Node's behavior when we think we're faking timers in Node (as we have the addTimerReturnsObject variable)

Copy link
Member Author

Choose a reason for hiding this comment

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

Seeing as the tag failed, I'll be a bit cheeky and do @bnoordhuis

Choose a reason for hiding this comment

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

Do you happen to remember why timers are set to 1 and not 0?

Because that's what browsers did at the time. :-)

Copy link
Contributor

Choose a reason for hiding this comment

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

So glad you guys are looking into the sweaty details of this. Delegation is 👑 Hope you add some comments to the implementation to make code archaeology easier for future maintainers :)

Copy link
Member

Choose a reason for hiding this comment

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

I've opened an issue over at core about the bahvior - I think it's fine to be honest, it's not what the timers spec says but it's what Chrome and Node do basically nodejs/node#20596

Copy link
Member Author

@SimenB SimenB May 8, 2018

Choose a reason for hiding this comment

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

FWIW, I'm fine setting it to 1. That's not observable from my test - the test is the order in which the callbacks gets invoked, not if the timeout is 0 or 1.

Node and Chrome behaves the way I expect for Infinity, -Infinity and NaN.

setTimeout(() => console.log(1), Infinity);
setTimeout(() => console.log(2), NaN);
setTimeout(() => console.log(3), -Infinity);
// => 1
// => 2
// => 3

While Lolex does 2, 3, 1. This PR fixes that, which is what matters to me 🙂

@fatso83
Copy link
Contributor

fatso83 commented May 8, 2018

rebase to get merged :)

@SimenB
Copy link
Member Author

SimenB commented May 8, 2018

Rebased!

@fatso83 fatso83 merged commit b166f58 into sinonjs:master May 8, 2018
@fatso83
Copy link
Contributor

fatso83 commented May 8, 2018

2.4.1 out.

@SimenB SimenB deleted the negative-infinity branch May 8, 2018 15:48
@SimenB
Copy link
Member Author

SimenB commented May 8, 2018

Awesome. Updated the PR in Jest. Getting closer!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants