sinonjs / fake-timers

Fake setTimeout and friends (collectively known as "timers"). Useful in your JavaScript tests. Extracted from Sinon.JS
BSD 3-Clause "New" or "Revised" License
793 stars 103 forks source link

`runToLastAsync` doing infinite loop when `now` is specified to setup clock #450

Closed guillaumeduboc closed 1 year ago

guillaumeduboc commented 1 year ago

While working on https://github.com/vitest-dev/vitest/pull/2209 I have an issue with runToLastAsync doing an infinite loop Below you can find a minimal test to reproduce the issue

We understand you have a problem and are in a hurry, but please provide us with some info to make it much more likely for your issue to be understood, worked on and resolved quickly.

What did you expect to happen? An infinite loop shouldn't be possible and this test shouldn't break

What actually happens This test times out

How to reproduce Here is a minimal test to reproduce the issue

        it("new timers created from promises cannot cause an infinite loop when a date is given", function () {
            this.clock = FakeTimers.createClock(Date.now());
            const test = this;
            const spy = sinon.spy();
            const recursiveCallback = function () {
                global.Promise.resolve().then(function () {
                    test.clock.setTimeout(recursiveCallback, 0);
                });
            };

            this.clock.setTimeout(recursiveCallback, 0);
            this.clock.setTimeout(spy, 100);

            return this.clock.runToLastAsync().then(function () {
                assert.isTrue(spy.called);
            });
        });

The error for this test is

Capture d’écran 2022-11-19 à 01 08 23