-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
fix(vitest): decouple fake/real time in waitFor()'s check #6802
base: main
Are you sure you want to change the base?
Conversation
When running with fake timers, and when polling for promise to complete, make sure we do the poll in a short *real* time interval, independent of the fake time interval. This makes it possible to use long time intervals in fake time without needing to wait for the corresponding amount of real time passing. A unit test is added to illustrate this behaviour: with the previous code, this unit test would have taken over a minute to complete, now it is near instantaneous.
✅ Deploy Preview for vitest-dev ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify site configuration. |
Please, don't drop the PR template: Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
The first point is especially important as we can't evaluate the usefulness of this change without examples and a proper discussion. |
Apologies, I created the PR with I was about to raise an issue, but thought the issue was very clear from a unit test, which I've included. If it's helpful to raise a issue and move the discussion there I'm happy to do that. But as it stands, there is a unit test and description here which would be the information I'd put in the issue. Would you like to consider discuss here, or shall I move this to an issue? |
You can start here.
The reasoning doesn't really make it clear to me. The test is very artificial. The |
The test is artificial, but it's based on a real use-case in my project. I've just simplified it. The current behaviour causes real problems in a (closed) project I'm working on. I believe the purpose of the I'd be interested in knowing what your definition of the A way to change this to not introduce any change in behaviour is to add another configuration option for this case; but that of course increases the size of the API. I'd be equally happy with such an approach in my use-case. |
You can already provide your own |
OK, fair enough.
I'm not entirely sure I follow that suggestion. In my case, I have the following scenario:
I believe the right answer here is: In the few cases I'd like to use Are you suggesting there is a way to use the API to solve for this case today without any modifications? I haven't quite been able to figure out what that is based on your last comment, sorry. |
Why do you even need such a big interval? It means the callback will be called once every 30 seconds. Don't you need a
Yeah, what you did in this PR looks like this in user code: vi.waitFor(() => {}, {
interval: vi.isFakeTimers() ? 40 : 30000
}) |
Because we're testing code that really does, in the real world, use long intervals. One case that is hopefully easy to describe: (something using) an exponential backoff timer. Consider something with a backoff that quickly results in the backoff time being a long duration after some error conditions are hit. It is reasonable to check that something will succeed after some amount of backing off.
Sorry, I don't agree. Are we perhaps talking at cross purposes? There are two separate things here: the amount of fake time that is increased per time we check, and the amount of real time that needs to pass. Consider the unit test code here: vi.useFakeTimers()
await vi.waitFor(() => {
return new Promise<void>((resolve) => {
setTimeout(() => {
resolve()
}, 60000)
})
}, { interval: 30000 }) Your suggestion is that we change the interval there to read:
In this trivialised case, this will obviously set the interval to 40.
I had a look at |
We talked within the team about this issue. We still don't understand the use case. Can you give an actual code example that helps understand this? And can you explain why you need to use |
When running with fake timers, and when polling for promise to complete, make sure we do the poll in a short real time interval, independent of the fake time interval.
This makes it possible to use long time intervals in fake time without needing to wait for the corresponding amount of real time passing. A unit test is added to illustrate this behaviour: with the previous code, this unit test would have taken over a minute to complete, now it is near instantaneous.