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

Fix #631, add jestFakeTimersAreEnabled and use it to detect faketimer in createTimeoutController #688

Merged
merged 14 commits into from
Sep 19, 2021

Conversation

chris110408
Copy link
Contributor

@chris110408 chris110408 commented Sep 6, 2021

What:

Fixes #631, add jestFakeTimersAreEnabled and use it detect the useFakeTimer.
when useFakeTimer has been detected and jest.advanceTimersByTime will advance time to the timeout-1
test:'should waitFor arbitrary expectation to pass when fake timers are not advanced explicitly' has been added

Why:
we need to add jestFakeTimersAreEnabled function the same function used on @testing-library/dom
and use it to detect the fake timer and use advanced time to make sure time is not stuck

How:
The problem was when the fake timer is used. the time will not move forward unless using the advanced time.
#682 createTimeoutController has been used to replace Promise.race.
the problem is to detect the fake timber and use advance time to move time forward to the last ms until the timeout.

Checklist:

  • Documentation updated
  • Tests
  • Ready to be merged
  • Added me to contributors table. @mpeyper my status is test contributor only could you please update my status to the code and test

@chris110408 chris110408 changed the title Fix #631, use Fix #631, add jestFakeTimersAreEnabled and use it to detect faketimer in createTimeoutController Sep 6, 2021
@netlify
Copy link

netlify bot commented Sep 6, 2021

✔️ Deploy Preview for react-hooks-testing-library ready!

🔨 Explore the source changes: d623572

🔍 Inspect the deploy log: https://app.netlify.com/sites/react-hooks-testing-library/deploys/614738594b33ad0008148c1f

😎 Browse the preview: https://deploy-preview-688--react-hooks-testing-library.netlify.app

@codecov
Copy link

codecov bot commented Sep 6, 2021

Codecov Report

Merging #688 (d623572) into alpha (8b72a87) will not change coverage.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff            @@
##             alpha      #688   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           15        16    +1     
  Lines          244       264   +20     
  Branches        32        38    +6     
=========================================
+ Hits           244       264   +20     
Impacted Files Coverage Δ
src/core/asyncUtils.ts 100.00% <100.00%> (ø)
src/helpers/createTimeoutController.ts 100.00% <100.00%> (ø)
src/helpers/fakeTimers.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8b72a87...d623572. Read the comment docs.

add new fakeTimer test and revise the function

add advanceTime

revise the advanceTime

use  jest.advanceTimersByTime

change timeout type

fix converage and revise type
@mpeyper
Copy link
Member

mpeyper commented Sep 9, 2021

@chris110408 I've just pushed some more tests for the fake timers test suite (they are the same as the regular async utils, except one).

Theoretically all these tests should pass, when fake timers are enabled. With your current changes, most are timing out (the CI agents are not handling this very well as it's taking a long time for all of the tests to time out).

src/core/asyncUtils.ts Outdated Show resolved Hide resolved
src/core/asyncUtils.ts Outdated Show resolved Hide resolved
src/core/asyncUtils.ts Outdated Show resolved Hide resolved
src/core/asyncUtils.ts Outdated Show resolved Hide resolved
@mpeyper
Copy link
Member

mpeyper commented Sep 9, 2021

@chris110408, you probably got a notification about it (but in case anyone is reading along) but I've pushed up a branch with most of the suggested changes here and a modified advance timers implementation that passes all the tests (at least locally for me).

@chris110408
Copy link
Contributor Author

@chris110408, you probably got a notification about it (but in case anyone is reading along) but I've pushed up a branch with most of the suggested changes here and a modified advance timers implementation that passes all the tests (at least locally for me).

Thank you. I will look at those change today

)
})

test('should not reject when waiting for next update if timeout has been disabled', async () => {
Copy link
Contributor Author

@chris110408 chris110408 Sep 9, 2021

Choose a reason for hiding this comment

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

…testing-library#689)

Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 4.30.0 to 4.31.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.31.0/packages/parser)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ry#690)

Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 4.30.0 to 4.31.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.31.0/packages/eslint-plugin)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@chris110408
Copy link
Contributor Author

chris110408 commented Sep 12, 2021

I'm just reading a few things (here, here and here) that suggest te build error we were getting was actually a node error (from v8) and just very unlucky timing on our part.

I'm going to try reenabling that test a see if it passes now, but will revert if it's still an issue.

Update: it worked!

Nice. Is there any thing I need to double check before we merge this PR?

@mpeyper
Copy link
Member

mpeyper commented Sep 13, 2021

I'm just reading a few things (here, here and here) that suggest te build error we were getting was actually a node error (from v8) and just very unlucky timing on our part.
I'm going to try reenabling that test a see if it passes now, but will revert if it's still an issue.
Update: it worked!

Nice. Is there any thing I need to double check before we merge this PR?

I need to properly review it (spent most of my time looking at the build issue the other night), but I'm thinking of putting this out in a beta release first.

@mpeyper mpeyper changed the base branch from main to alpha September 19, 2021 11:19
@mpeyper
Copy link
Member

mpeyper commented Sep 19, 2021

Thanks a lot @chris110408. I've made a few, most cosmetic changes.

The biggest change was no using DEFAULT_TIMEOUT for advancing timers when timeout = false to rather keep advancing while the promise is outstanding.

The only other thing I noticed that might have been an issue (no tests were failing) was that timers were being advance in both the timeout and interval controllers since they were moved out of the the if (timeout) check for the timeout = false, interval = false test case, but that just meant we needed to pick one to run the timers.

I'm going to push out an alpha build for this now.

@mpeyper mpeyper merged commit 732ec46 into testing-library:alpha Sep 19, 2021
@github-actions
Copy link

🎉 This PR is included in version 8.0.0-alpha.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@mpeyper mpeyper added the BREAKING CHANGE This change will require a major version bump label Sep 19, 2021
@mpeyper
Copy link
Member

mpeyper commented Sep 19, 2021

Just wondering if we need some a note in the async utils docs about fake timers?

@mpeyper
Copy link
Member

mpeyper commented Sep 20, 2021

I've got a fairly complicated real world example that I thought would be fixed by this change, but after testing out the alpha it's still not working. I'll try to get a boiled down version onto a test to help work through it, but so far it appears as though the microtask queue is not flushing as we advance timers. I'm not sure why this is occurring for the setup yet, but wanted to drop a comment here in case anyone else tries it with a more real world example and is also running into issues.

@chris110408
Copy link
Contributor Author

Thanks a lot @chris110408. I've made a few, most cosmetic changes.

The biggest change was no using DEFAULT_TIMEOUT for advancing timers when timeout = false to rather keep advancing while the promise is outstanding.

The only other thing I noticed that might have been an issue (no tests were failing) was that timers were being advance in both the timeout and interval controllers since they were moved out of the the if (timeout) check for the timeout = false, interval = false test case, but that just meant we needed to pick one to run the timers.

I'm going to push out an alpha build for this now.

@mpeyper Could you please add me to the code contributor list?

@chris110408
Copy link
Contributor Author

Just wondering if we need some a note in the async utils docs about fake timers?

I could work on that If we need to

@chris110408
Copy link
Contributor Author

I've got a fairly complicated real world example that I thought would be fixed by this change, but after testing out the alpha it's still not working. I'll try to get a boiled down version onto a test to help work through it, but so far it appears as though the microtask queue is not flushing as we advance timers. I'm not sure why this is occurring for the setup yet, but wanted to drop a comment here in case anyone else tries it with a more real world example and is also running into issues.

will look at it this weekend

@mpeyper
Copy link
Member

mpeyper commented Sep 20, 2021

@mpeyper Could you please add me to the code contributor list?

I did, it's just in the alpha branch for now.

I could work on that If we need to

Thanks. Just target the alpha branch if it's not in main when you make the PR.

will look at it this weekend

Hopefully I will have boiled down the example by then. I'll post it here if I do. I'm actively working on this too as the hook/test in question is part of my day job.

@chris110408
Copy link
Contributor Author

chris110408 commented Sep 20, 2021

@mpeyper Could you please add me to the code contributor list?

I did, it's just in the alpha branch for now.

I could work on that If we need to

Thanks. Just target the alpha branch if it's not in main when you make the PR.

will look at it this weekend

Hopefully I will have boiled down the example by then. I'll post it here if I do. I'm actively working on this too as the hook/test in question is part of my day job.

Thank you

@mpeyper
Copy link
Member

mpeyper commented Sep 27, 2021

I've got a fairly complicated real world example that I thought would be fixed by this change, but after testing out the alpha it's still not working. I'll try to get a boiled down version onto a test to help work through it, but so far it appears as though the microtask queue is not flushing as we advance timers. I'm not sure why this is occurring for the setup yet, but wanted to drop a comment here in case anyone else tries it with a more real world example and is also running into issues.

So after a few hours of replacing portions of this very complex hook setup, I've managed to narrow it down to an API call being made with node-fetch that is being mocked with msw. If I replace that API call with a promise that resolves after a short timeout, the test works as expected.

I'm out of steam today to look at this anymore, but I'll try to setup a small example just with node-fetch and msw and see I can replicate it without everything else going on in this hook (it's also got event emitters, intervals, memoized functions and redux dispatching all thrown in mix) sometime over the next few days.

@icatalina
Copy link

Hi! thanks for fixing this! We are facing this issue, when are we planning to release it? thanks 🙇

@mpeyper
Copy link
Member

mpeyper commented Nov 30, 2021

Hi @icatalina, I'm not sure this will ever see a full release at this point, given what is happening over in RTL. I believe renderHook is available now in a stable release, so you should probably check that out. As a bonus, their version of waitFor already supports fake timers from jest.

@icatalina
Copy link

Ohhh!! I had no idea! thanks heaps for pointing that out! :)

@snowystinger snowystinger mentioned this pull request Dec 7, 2021
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BREAKING CHANGE This change will require a major version bump released on @alpha
Projects
None yet
Development

Successfully merging this pull request may close these issues.

waitFor doesn't work if jest fake timers are used
3 participants