Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 42af8ea

Browse files
committed
fix(mocks): $timeout#flush should not update time when empty
When $timeout#flush is called with a delay and no task can be flushed within that delay, the current time should not be updated as that gets the mock into an inconsistent state. BREAKING CHANGE: if a tests was written around the buggy behavior the delays might be off now This would typically not be a problem, but because of the previous breaking change in $timeout.flush, the combination of two might be confusing and that's why we are documenting it. Old behavior: ``` doSomething(); //schedules task to execute in 500ms from now doOtherStuff(); //schedules task to execute in 600ms from now try { $timeout.flush(300); // throws "no task to be flushed" exception } catch(e) {}; $time.flush(200); //flushes only doSomething() task ``` New behavior: ``` doSomething(); //schedules task to execute in 500ms from now doOtherStuff(); //schedules task to execute in 600ms from now try { $timeout.flush(300); // throws "no task to be flushed" exception } catch(e) {}; $time.flush(200); // throws "no task to be flushed" exception again // because previous exception didn't move the time forward ``` Fixed test: ``` doSomething(); //schedules task to execute in 500ms from now doOtherStuff(); //schedules task to execute in 600ms from now try { $timeout.flush(300); // throws "no task to be flushed" exception } catch(e) {}; $time.flush(500); // flushes only doSomething() task ```
1 parent cbf06a5 commit 42af8ea

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

src/ngMock/angular-mocks.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,17 @@ angular.mock.$Browser = function() {
105105
*/
106106
self.defer.flush = function(delay) {
107107
var flushedSomething = false;
108+
now = self.defer.now;
108109

109110
if (angular.isDefined(delay)) {
110-
self.defer.now += delay;
111+
now += delay;
111112
} else {
112113
if (self.deferredFns.length) {
113-
self.defer.now = self.deferredFns[self.deferredFns.length-1].time;
114+
now = self.deferredFns[self.deferredFns.length-1].time;
114115
}
115116
}
116117

117-
while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) {
118+
while (self.deferredFns.length && self.deferredFns[0].time <= now) {
118119
flushedSomething = true;
119120
self.deferredFns.shift().fn();
120121
}
@@ -126,6 +127,8 @@ angular.mock.$Browser = function() {
126127
throw Error('No deferred tasks with delay up to ' + delay + 'ms to be flushed!')
127128
}
128129
}
130+
131+
self.defer.now = now;
129132
};
130133

131134
/**

test/ngMock/angular-mocksSpec.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ describe('ngMock', function() {
404404
expect(function() {$timeout.flush(100);}).toThrow();
405405
expect(log).toEqual(['t1']);
406406

407-
$timeout.flush(900);
407+
$timeout.flush(1000);
408408
expect(log).toEqual(['t1', 't2']);
409409
expect(function() {$timeout.flush();}).toThrow();
410410
});
@@ -425,6 +425,21 @@ describe('ngMock', function() {
425425
});
426426

427427

428+
it('should not update the current time if an exception is thrown during a flush', function() {
429+
$timeout(log.fn('t1'), 100);
430+
$timeout(log.fn('t2'), 101);
431+
432+
expect(function() { $timeout.flush(90); }).toThrow();
433+
expect(function() { $timeout.flush(90); }).toThrow();
434+
435+
$timeout.flush(100);
436+
expect(log).toEqual(['t1']);
437+
438+
$timeout.flush(1);
439+
expect(log).toEqual(['t1', 't2']);
440+
});
441+
442+
428443
describe('verifyNoPendingTasks', function() {
429444

430445
it('should throw an exception when not flushed', function() {

0 commit comments

Comments
 (0)