-
Notifications
You must be signed in to change notification settings - Fork 104
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
feat: mock intl api #474
feat: mock intl api #474
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #474 +/- ##
==========================================
+ Coverage 95.66% 95.80% +0.13%
==========================================
Files 2 2
Lines 669 691 +22
==========================================
+ Hits 640 662 +22
Misses 29 29
Flags with carried forward coverage won't be shown. Click here to find out more.
☔ View full report in Codecov by Sentry. |
Love when wanted features come with a PR <3 I am off on holiday with just a small mobile screen unsuitable for reviewing code, but hopefully someone else could have a looksie? |
I'm on medical leave I'll try to take a look next week and maybe ask Erick from Node to look |
As I don't have much context I think it LGTM |
Thanks for the interest folks! I'll look into these failing tests. |
Hi all, it looks like the issue in the test suite is being caused by a difference between the mochify and node runtimes. |
It's not mochify (which is running Chrome headless) vs Node, but specifically Node 14 breaking. You see the tests passing in Node 16 and 18. If you look at the engine comparisons page for Intl.DateTimeFormat you can see that In any case, we only support Node LTS versions, and Node 14 LTS has reached its EOL, so we can just remove that :) |
I have now removed Node 14 from Do you deem it ready for final review and merge? |
d93f9e3
to
58d15a3
Compare
Rebased just to keep things clean 👍 yes, it's ready for final review! |
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 an excellent PR. Really conforms to everything we want, so thank you very much! I'll merge it once the (tiny) changes have been done.
Update author info
Thanks for the review! Changes:
|
Purpose (TL;DR) - Mock the global Intl API
Solve the breaking of timer-dependant methods on the Intl global object by including a mocked version
Background (Problem in detail)
Even after calling install(), the Intl.DateTimeFormat() class will currently use the real time of the system, not the time specified by the fake clock.
Affected methods: DateTimeFormat.format(), DateTimeFormat.formatToParts()
My repo demonstrating the problem, using Jest (which uses sinonjs/fake-timers): https://github.com/BenIsenstein/jest_fix_intl_fake_timers
The fix works by following the patterns used to mock the global Date class and mocking the Intl object. A producer function is written to return an Intl object largely identical to the original, except for the DateTimeFormat() class. DateTimeFormat has several methods that are time-sensitive, and depend on the system time when no argument is passed. These are intercepted and made to default to the clock time.
This fake Intl object is provided to the Global object when install() is called.
Line 1176, inside createClock()
and the original Intl object is restored during uninstall().
Line 979 inside hijackMethod()
An else-if clause added to handle hijacking Intl. Because Intl isn't a straightforward global function, rather a global object used like a module, it can't be mocked using the default else clause at the end of hijackMethod(). It has its own clause to set the mocked Intl object globally.
I'm fairly confident on implementation, however less confident on the tests. All advice is appreciated!
Ben