Fix time-travel in delayed function scheduler
This commit is contained in:
@@ -3565,7 +3565,6 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
|||||||
var endTime = currentTime + millis;
|
var endTime = currentTime + millis;
|
||||||
|
|
||||||
runScheduledFunctions(endTime, tickDate);
|
runScheduledFunctions(endTime, tickDate);
|
||||||
currentTime = endTime;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.scheduleFunction = function(
|
self.scheduleFunction = function(
|
||||||
@@ -3683,16 +3682,20 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
|||||||
function runScheduledFunctions(endTime, tickDate) {
|
function runScheduledFunctions(endTime, tickDate) {
|
||||||
tickDate = tickDate || function() {};
|
tickDate = tickDate || function() {};
|
||||||
if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
|
if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
|
||||||
tickDate(endTime - currentTime);
|
if (endTime >= currentTime) {
|
||||||
|
tickDate(endTime - currentTime);
|
||||||
|
currentTime = endTime;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
deletedKeys = [];
|
deletedKeys = [];
|
||||||
var newCurrentTime = scheduledLookup.shift();
|
var newCurrentTime = scheduledLookup.shift();
|
||||||
tickDate(newCurrentTime - currentTime);
|
if (newCurrentTime >= currentTime) {
|
||||||
|
tickDate(newCurrentTime - currentTime);
|
||||||
currentTime = newCurrentTime;
|
currentTime = newCurrentTime;
|
||||||
|
}
|
||||||
|
|
||||||
var funcsToRun = scheduledFunctions[currentTime];
|
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
|
// ran out of functions to call, but still time left on the clock
|
||||||
if (currentTime !== endTime) {
|
if (endTime >= currentTime) {
|
||||||
tickDate(endTime - currentTime);
|
tickDate(endTime - currentTime);
|
||||||
|
currentTime = endTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -278,4 +278,58 @@ describe('DelayedFunctionScheduler', function() {
|
|||||||
expect(tickDate).toHaveBeenCalledWith(0);
|
expect(tickDate).toHaveBeenCalledWith(0);
|
||||||
expect(tickDate).toHaveBeenCalledWith(1);
|
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;
|
var endTime = currentTime + millis;
|
||||||
|
|
||||||
runScheduledFunctions(endTime, tickDate);
|
runScheduledFunctions(endTime, tickDate);
|
||||||
currentTime = endTime;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.scheduleFunction = function(
|
self.scheduleFunction = function(
|
||||||
@@ -130,16 +129,20 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
|||||||
function runScheduledFunctions(endTime, tickDate) {
|
function runScheduledFunctions(endTime, tickDate) {
|
||||||
tickDate = tickDate || function() {};
|
tickDate = tickDate || function() {};
|
||||||
if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
|
if (scheduledLookup.length === 0 || scheduledLookup[0] > endTime) {
|
||||||
tickDate(endTime - currentTime);
|
if (endTime >= currentTime) {
|
||||||
|
tickDate(endTime - currentTime);
|
||||||
|
currentTime = endTime;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
deletedKeys = [];
|
deletedKeys = [];
|
||||||
var newCurrentTime = scheduledLookup.shift();
|
var newCurrentTime = scheduledLookup.shift();
|
||||||
tickDate(newCurrentTime - currentTime);
|
if (newCurrentTime >= currentTime) {
|
||||||
|
tickDate(newCurrentTime - currentTime);
|
||||||
currentTime = newCurrentTime;
|
currentTime = newCurrentTime;
|
||||||
|
}
|
||||||
|
|
||||||
var funcsToRun = scheduledFunctions[currentTime];
|
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
|
// ran out of functions to call, but still time left on the clock
|
||||||
if (currentTime !== endTime) {
|
if (endTime >= currentTime) {
|
||||||
tickDate(endTime - currentTime);
|
tickDate(endTime - currentTime);
|
||||||
|
currentTime = endTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user