Fix time-travel in delayed function scheduler
This commit is contained in:
@@ -3565,7 +3565,6 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
var endTime = currentTime + millis;
|
||||
|
||||
runScheduledFunctions(endTime, tickDate);
|
||||
currentTime = endTime;
|
||||
};
|
||||
|
||||
self.scheduleFunction = function(
|
||||
@@ -3683,16 +3682,20 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
function runScheduledFunctions(endTime, tickDate) {
|
||||
tickDate = tickDate || function() {};
|
||||
if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
|
||||
tickDate(endTime - currentTime);
|
||||
if (endTime >= currentTime) {
|
||||
tickDate(endTime - currentTime);
|
||||
currentTime = endTime;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
deletedKeys = [];
|
||||
var newCurrentTime = scheduledLookup.shift();
|
||||
tickDate(newCurrentTime - currentTime);
|
||||
|
||||
currentTime = newCurrentTime;
|
||||
if (newCurrentTime >= currentTime) {
|
||||
tickDate(newCurrentTime - currentTime);
|
||||
currentTime = newCurrentTime;
|
||||
}
|
||||
|
||||
var funcsToRun = scheduledFunctions[currentTime];
|
||||
|
||||
@@ -3721,8 +3724,9 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
);
|
||||
|
||||
// ran out of functions to call, but still time left on the clock
|
||||
if (currentTime !== endTime) {
|
||||
if (endTime >= currentTime) {
|
||||
tickDate(endTime - currentTime);
|
||||
currentTime = endTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,4 +278,58 @@ describe('DelayedFunctionScheduler', function() {
|
||||
expect(tickDate).toHaveBeenCalledWith(0);
|
||||
expect(tickDate).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
describe('ticking inside a scheduled function', function() {
|
||||
let clock;
|
||||
|
||||
// Runner function calls the callback until it returns false
|
||||
function runWork(workCallback) {
|
||||
while (workCallback()) {}
|
||||
}
|
||||
|
||||
// Make a worker that takes a little time and tracks when it finished
|
||||
function mockWork(times) {
|
||||
return () => {
|
||||
clock.tick(1);
|
||||
const now = new Date().getTime();
|
||||
expect(lastWork)
|
||||
.withContext('Previous function calls should always be in the past')
|
||||
.toBeLessThan(now);
|
||||
lastWork = now;
|
||||
times--;
|
||||
return times > 0;
|
||||
};
|
||||
}
|
||||
let lastWork = 0;
|
||||
|
||||
beforeEach(() => {
|
||||
clock = jasmine.clock();
|
||||
clock.install();
|
||||
clock.mockDate(new Date(1));
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
it('preserves monotonically-increasing current time', () => {
|
||||
const work1 = mockWork(3);
|
||||
setTimeout(() => {
|
||||
runWork(work1);
|
||||
}, 1);
|
||||
clock.tick(1);
|
||||
expect(lastWork)
|
||||
.withContext('tick should advance past last-scheduled function')
|
||||
.toBeLessThanOrEqual(new Date().getTime());
|
||||
|
||||
const work2 = mockWork(3);
|
||||
setTimeout(() => {
|
||||
runWork(work2);
|
||||
}, 1);
|
||||
clock.tick(1);
|
||||
expect(lastWork)
|
||||
.withContext('tick should advance past last-scheduled function')
|
||||
.toBeLessThanOrEqual(new Date().getTime());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,7 +12,6 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
var endTime = currentTime + millis;
|
||||
|
||||
runScheduledFunctions(endTime, tickDate);
|
||||
currentTime = endTime;
|
||||
};
|
||||
|
||||
self.scheduleFunction = function(
|
||||
@@ -130,16 +129,20 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
function runScheduledFunctions(endTime, tickDate) {
|
||||
tickDate = tickDate || function() {};
|
||||
if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
|
||||
tickDate(endTime - currentTime);
|
||||
if (endTime >= currentTime) {
|
||||
tickDate(endTime - currentTime);
|
||||
currentTime = endTime;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
deletedKeys = [];
|
||||
var newCurrentTime = scheduledLookup.shift();
|
||||
tickDate(newCurrentTime - currentTime);
|
||||
|
||||
currentTime = newCurrentTime;
|
||||
if (newCurrentTime >= currentTime) {
|
||||
tickDate(newCurrentTime - currentTime);
|
||||
currentTime = newCurrentTime;
|
||||
}
|
||||
|
||||
var funcsToRun = scheduledFunctions[currentTime];
|
||||
|
||||
@@ -168,8 +171,9 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
);
|
||||
|
||||
// ran out of functions to call, but still time left on the clock
|
||||
if (currentTime !== endTime) {
|
||||
if (endTime >= currentTime) {
|
||||
tickDate(endTime - currentTime);
|
||||
currentTime = endTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user