question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

clock.performance.now returns incorrect value within clock.setInterval callback

See original GitHub issue
  • FakeTimers version : 7.1.2
  • Environment : NodeJS
  • Example URL : N/A; see test below
  • Other libraries you are using: Jest

When passing fractional milliseconds to clock.setInterval and clock.tick, the return value of clock.performance.now is sometimes incorrect when called within the callback passed to clock.setInterval.

Here is an example test running within Jest:

import { Clock, install } from '@sinonjs/fake-timers';

let clock: Clock;

beforeAll(() => {
  clock = install();
});

afterAll(() => {
  clock.uninstall();
});

test('fake timers bug', () => {
  const timestamps: number[] = [];
  clock.setInterval(() => {
    timestamps.push(clock.performance.now());
  }, 16.6);

  clock.tick(16.6);
  clock.tick(16.6);

  expect(clock.performance.now()).toBe(33.2); // Passes
  expect(timestamps).toStrictEqual([16.6, 33.2]); // Fails
});

What did you expect to happen?

Each timestamp should be a multiple of 16.6.

What actually happens

The timestamp generated on the second iteration of the callback is off by 1 millisecond. The value 32.2 is returned rather than 33.2.

Screen Shot 2021-06-02 at 8 22 44 PM

Interestingly, when calling clock.performance.now outside of the clock.setInterval callback, the correct timestamp is returned.

How to reproduce

See test sample above.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
rrogowskicommented, Jun 3, 2021

@fatso83 Thank you for the thoughtful reply! You raise a good point about writing code that does not conform to the spec. I will re-think the code I am writing, which will hopefully make the functionality easier to test. I really appreciate your time on this matter, and I’m happy to close this issue as a non-bug!

1reaction
fatso83commented, Jun 3, 2021

Not totally sure what to say here. Code that uses a non-integer duration is essentially “wrong” (not spec-conforming), so this is a more general question of how would you test something that is not supported😃

I think your approach of testing the timers schedule updates at an approximately correct frequency should be fine, and it’s basically what you did above. In any case, most JS runtimes do not make hard realtime guarantees, so whether your timer in practice gets called 51 times per minute or 62 times per minute is totally browser/node/runtime specific. So you are only really testing that fake-timers schedules a call every parseInt(16.6) millisecond. Not sure if we can do better than that.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to create an accurate timer in javascript? - Stack Overflow
now (), the values returned by performance.now() always increase at a constant rate, independent of the system clock (which might be adjusted manually...
Read more >
setInterval callback function unexpected halt · Issue #22149
When the project has been running for a month or so, there is no error, the project does not stop, but the callback...
Read more >
setInterval() - Web APIs - MDN Web Docs
This method returns an interval ID which uniquely identifies the interval, so you can remove it later by calling clearInterval() .
Read more >
Scheduling: setTimeout and setInterval
To cancel the execution, we should call clearTimeout/clearInterval with the value returned by setTimeout/setInterval .
Read more >
A tale of two clocks - web.dev
The bad side of the JavaScript clock is that it is not very precise. For starters, Date.now() returns a value in milliseconds -...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found