- Merges #1427 from @eahciMic
- Fixes #1426
This commit is contained in:
Steve Gravrock
2018-01-02 08:15:30 -08:00
4 changed files with 66 additions and 9 deletions

View File

@@ -1,5 +1,5 @@
/*
Copyright (c) 2008-2017 Pivotal Labs
Copyright (c) 2008-2018 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -2066,6 +2066,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
var scheduledFunctions = {};
var currentTime = 0;
var delayedFnCount = 0;
var deletedKeys = [];
self.tick = function(millis, tickDate) {
millis = millis || 0;
@@ -2112,6 +2113,8 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
};
self.removeFunctionWithId = function(timeoutKey) {
deletedKeys.push(timeoutKey);
for (var runAtMillis in scheduledFunctions) {
var funcs = scheduledFunctions[runAtMillis];
var i = indexOfFirstToPass(funcs, function (func) {
@@ -2188,6 +2191,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
currentTime = newCurrentTime;
var funcsToRun = scheduledFunctions[currentTime];
delete scheduledFunctions[currentTime];
forEachFunction(funcsToRun, function(funcToRun) {
@@ -2197,8 +2201,13 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
});
forEachFunction(funcsToRun, function(funcToRun) {
if (deletedKeys.indexOf(funcToRun.timeoutKey) !== -1) {
// skip a timeoutKey deleted whilst we were running
return;
}
funcToRun.funcToCall.apply(null, funcToRun.params || []);
});
deletedKeys = [];
} while (scheduledLookup.length > 0 &&
// checking first if we're out of time prevents setTimeout(0)
// scheduled in a funcToRun from forcing an extra iteration

View File

@@ -714,4 +714,41 @@ describe("Clock (acceptance)", function() {
expect(actualTimes).toEqual([baseTime.getTime(), baseTime.getTime() + 1, baseTime.getTime() + 3]);
})
it('correctly clears a scheduled timeout while the Clock is advancing', function () {
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
global = {Date: Date, setTimeout: undefined},
mockDate = new jasmineUnderTest.MockDate(global),
clock = new jasmineUnderTest.Clock(global, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
var timerId2;
global.setTimeout(function () {
global.clearTimeout(timerId2);
}, 100);
timerId2 = global.setTimeout(fail, 100);
clock.tick(100);
});
it('correctly clears a scheduled interval while the Clock is advancing', function () {
var delayedFunctionScheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
global = {Date: Date, setTimeout: undefined},
mockDate = new jasmineUnderTest.MockDate(global),
clock = new jasmineUnderTest.Clock(global, function () { return delayedFunctionScheduler; }, mockDate);
clock.install();
var timerId2;
var timerId1 = global.setInterval(function () {
global.clearInterval(timerId2);
}, 100);
timerId2 = global.setInterval(fail, 100);
clock.tick(400);
});
});

View File

@@ -216,21 +216,23 @@ describe("DelayedFunctionScheduler", function() {
it("removes functions during a tick that runs the function", function() {
var scheduler = new jasmineUnderTest.DelayedFunctionScheduler(),
fn = jasmine.createSpy('fn'),
spy = jasmine.createSpy('fn'),
spyAndRemove = jasmine.createSpy('fn'),
fnDelay = 10,
timeoutKey;
timeoutKey = scheduler.scheduleFunction(fn, fnDelay, [], true);
scheduler.scheduleFunction(function () {
spyAndRemove.and.callFake(function() {
scheduler.removeFunctionWithId(timeoutKey);
}, 2 * fnDelay);
});
expect(fn).not.toHaveBeenCalled();
scheduler.scheduleFunction(spyAndRemove, fnDelay);
scheduler.tick(3 * fnDelay);
timeoutKey = scheduler.scheduleFunction(spy, fnDelay, [], true);
expect(fn).toHaveBeenCalled();
expect(fn.calls.count()).toBe(2);
scheduler.tick(2 * fnDelay);
expect(spy).not.toHaveBeenCalled();
expect(spyAndRemove).toHaveBeenCalled();
});
it("removes functions during the first tick that runs the function", function() {

View File

@@ -5,6 +5,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
var scheduledFunctions = {};
var currentTime = 0;
var delayedFnCount = 0;
var deletedKeys = [];
self.tick = function(millis, tickDate) {
millis = millis || 0;
@@ -51,6 +52,8 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
};
self.removeFunctionWithId = function(timeoutKey) {
deletedKeys.push(timeoutKey);
for (var runAtMillis in scheduledFunctions) {
var funcs = scheduledFunctions[runAtMillis];
var i = indexOfFirstToPass(funcs, function (func) {
@@ -127,6 +130,7 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
currentTime = newCurrentTime;
var funcsToRun = scheduledFunctions[currentTime];
delete scheduledFunctions[currentTime];
forEachFunction(funcsToRun, function(funcToRun) {
@@ -136,8 +140,13 @@ getJasmineRequireObj().DelayedFunctionScheduler = function() {
});
forEachFunction(funcsToRun, function(funcToRun) {
if (deletedKeys.indexOf(funcToRun.timeoutKey) !== -1) {
// skip a timeoutKey deleted whilst we were running
return;
}
funcToRun.funcToCall.apply(null, funcToRun.params || []);
});
deletedKeys = [];
} while (scheduledLookup.length > 0 &&
// checking first if we're out of time prevents setTimeout(0)
// scheduled in a funcToRun from forcing an extra iteration