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
Unblock Preact tests that are executed against fake clock #30186
Unblock Preact tests that are executed against fake clock #30186
Conversation
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.
LGTM, future would be smart to add some checks to prohibit this from happening in other ported components.
@@ -83,6 +83,7 @@ describes.realWin( | |||
}); | |||
|
|||
afterEach(() => { | |||
clock.runAll(); |
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.
Makes sense, perhaps we should add some additional enforcement to ensure this happens for all tests with a preact
implementation?
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.
Yeah. I'm looking for defense in depth right now. But no good ideas yet.
I actually ran into a very similar problem when making a rAF polyfill in Are we reusing the same queue / outdated fake timer in between the test files, or was it the same instance of Preact that had grabbed/held-on to the rAF? A defense could be a new instance of Preact and of fake-timers for each test file |
@samouri The specific problem is that the Preact's global queue is shared between all tests. When the first element is added to the queue (and only when the first element added) the queue is scheduled with the |
@dvoytenko I think the options hook you were looking for is Note: that we don't recommend changing scheduling functions. It can lead to unexpected consequences when libraries rely on specific scheduling semantics. Your choice to go the fake timer route is much more foolproof and reliable in the long run. It's indeed a gotcha with fake timers, that one has to run those to completion manually. Not sure how we can hint at this pitfall from Preact's side. We certainly can add a section for that in our docs. |
@marvinhagemeister, thanks a lot for the advice. We are actually running into an issue with hooks specifically. So I think per your note, we should try to work this around via |
Also discovered (and skipped) the following problem (updated in the description):
|
…#30186) * Unblock Preact tests that are executed against fake clock * another test fixed * skip render-failing tests due to Preact issue
This pull request reverts #30181.
The description of the problem 1:
Preact schedules handler only once for a queue, when
queue.length === 1
. We had a situation where the fake test clock was used to schedule the update forqueue.length === 1
, but then it was discarded. All followup queue pushes were not scheduled becausequeue.length > 1
. But the fake timer was never executed, so the queue was stuck - more items were added to it, but handler was never called. I was actually surprised by this a bit - I thoughclock.uninstall
would run all pending timers, but apparently not.Not yet clear how to defend from this in depth. Debugging this problem is extremely difficult - there's no way to determine a "hanged" queue on Preact's side. One thing I tried is setting
Preact.options.requestAnimationFrame
, which is similar to wrapping inact()
. However, even with this option, Preact still relies onsetTimeout
.The description of the problem 2:
Preact's test-utils used to break the queue when the render function fails. This has been fixed in preactjs/preact@4efcd75. However, we're currently blocked on our Preact upgrade due to unrelated Closure bug. See #30043.
In general, a failing render function is not a good idea and that should be fixed separately. However, noting this here since this is also very hard to debug.