`Intl.DateTimeFormat.format()` ignores mocked clock when called without arguments
Steps to Reproduce
describe('date formatting with mock clock', () => {
beforeEach(() => {
jasmine.clock().install();
jasmine.clock().mockDate(new Date(2020, 11, 20, 10, 10)); // Dec 20, 2020
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('should work with explicit date parameter', () => {
const formatter = new Intl.DateTimeFormat('en-US', { timeZone: 'UTC' });
// This works correctly - uses mocked date
expect(formatter.format(new Date())).toEqual('12/20/2020');
});
it('should work with implicit current date', () => {
const formatter = new Intl.DateTimeFormat('en-US', { timeZone: 'UTC' });
// This currently fails - uses real current date instead of mocked date
expect(formatter.format()).toEqual('12/20/2020');
});
});Expected Behavior
When jasmine.clock() is installed and mockDate() is called, Intl.DateTimeFormat#format() without arguments should use the mocked date, returning the same formatted output as format(new Date()).
Actual Behavior
Intl.DateTimeFormat#format() without arguments ignores the mocked clock and uses the system's real current time, causing inconsistent behavior in tests that mix explicit date formatting with implicit current date formatting.
Possible Solution
The issue occurs because Intl.DateTimeFormat#format() without arguments calls a lower-level time API that bypasses Jasmine's Date mocking. The solution would be to also mock the Intl.DateTimeFormat constructor to intercept calls to format() and ensure they use Date.now() (which is properly mocked) when no date argument is provided.
A potential implementation could wrap Intl.DateTimeFormat similar to how Date is currently wrapped, ensuring the format method uses the mocked time when called without arguments. I would opt to utilise Proxy but I'm not sure what requirements there are for Jasmine support see canIuse#Proxy.
Context
This bug affects tests that use internationalization formatting with implicit current dates. It's particularly problematic because:
- Inconsistent mocking behavior: Some date APIs respect the mock clock while others don't
- Test reliability: Tests become flaky when they expect deterministic date formatting but get real system time
- Developer confusion: The inconsistency isn't obvious and can lead to hard-to-debug test failure
This is actually stated as bad practice by MDN but it doesn't stop developers from doing it. (except from MDN below for ease of access).
Omitting it results in formatting the current date (as returned by Date.now()), which could be slightly confusing, so it is advisable to always explicitly pass a date.
jasmine-core version
latest
Versions of other relevant packages
No response
Node.js and/or browser version
n/a
Operating System
n/a
Source: jasmine/jasmine