-
Notifications
You must be signed in to change notification settings - Fork 47k
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
chore(tests): don't rely on jest fake timers scheduling real timers #14003
Conversation
global.Date.now = function() { | ||
return originalDateNow(); | ||
}; | ||
// TODO remove `requestAnimationFrame` when upgrading to Jest 24 with Lolex |
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.
Using Jest 24, the test passes without faking global.requestAnimationFrame
. So whenever the upgrade lands, just remove the implementation here
@@ -18,10 +18,7 @@ let ReactCache; | |||
function initEnvForAsyncTesting() { | |||
// Boilerplate copied from ReactDOMRoot-test | |||
// TODO pull this into helper method, reduce repetition. | |||
const originalDateNow = Date.now; | |||
global.Date.now = 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.
Lolex will fake this.
The test also passed when removing it when using Jest 23, not sure what it was supposed to do?
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.
This is curious! I'm not sure what this was for. I'm guessing that this was just an artifact copy/pasting a snippet from ReactDOMRoot-test. It's quite a bit more sophisticated:
react/packages/react-dom/src/__tests__/ReactDOMRoot-test.js
Lines 23 to 45 in c84b9bf
container = document.createElement('div'); | |
// TODO pull this into helper method, reduce repetition. | |
// mock the browser APIs which are used in schedule: | |
// - requestAnimationFrame should pass the DOMHighResTimeStamp argument | |
// - calling 'window.postMessage' should actually fire postmessage handlers | |
// - must allow artificially changing time returned by Date.now | |
// Performance.now is not supported in the test environment | |
const originalDateNow = Date.now; | |
let advancedTime = null; | |
global.Date.now = function() { | |
if (advancedTime) { | |
return originalDateNow() + advancedTime; | |
} | |
return originalDateNow(); | |
}; | |
advanceCurrentTime = function(amount) { | |
advancedTime = amount; | |
}; | |
global.requestAnimationFrame = function(cb) { | |
return setTimeout(() => { | |
cb(Date.now()); | |
}); | |
}; |
I think this is safe to remove.
Details of bundled changes.Comparing: ae4f3f0...5029cba scheduler
Generated by 🚫 dangerJS |
@@ -140,7 +137,7 @@ describe('ProfilerDOM', () => { | |||
|
|||
// Evaluate in an unwrapped callback, | |||
// Because trace/wrap won't decrement the count within the wrapped callback. | |||
setImmediate(() => { | |||
Promise.resolve().then(() => { |
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 kind of wish this could be re-used, but it's unclear where something like that could go. .
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.
Could do an await
, then you're guaranteed a tick even if promises are faked
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.
Naw, I think this is fine.
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.
This looks good to me. What does the timing of this look like? Should we keep this open until the change in Jest publishes?
Seeing as the tests still pass, there's no reason not to merge, imo :) |
Sure. Let's run with it. Thanks! |
@nhunzaker In the future, please at least tag the person who wrote the code that's being changed. Brian or me, in this case. Unless it's to unbreak master. Sometimes even small changes like this could have unforeseen consequences. |
Sorry 😥. Sure thing! |
Did it break anything, or is that just a precaution? |
…acebook#14003) * chore: don't rely on jest fake timers scheduling real timers * re-add one part not working with Jest 23
…acebook#14003) * chore: don't rely on jest fake timers scheduling real timers * re-add one part not working with Jest 23
I'm currently working on replacing Jest's custom fake timers implementation with Lolex (jestjs/jest#5171). As part of that, I wanted to test that React's tests still work. They didn't...
A quirk of Jest's current implementation is that we schedule
process.nextTick
andsetImmediate
on the real timers, even though they're faked. Then we just make sure to do nothing if Jest invoked the function when advancing time, or vice versa if Node triggered it before us. That behavior is intentionally not re-implemented in the new version.This PR changes from using
setImmediate
toPromise.resolve().then()
to "wait 1 tick" which behaves the same.