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

Commit 1a387ba

Browse files
lgalfasoIgorMinar
authored andcommitted
fix($timeout): make $flush handle new $timeouts added in $timeout callbacks
If a $timeout handler calls $timeout itself, this new $timeout should be added to the mock deferred queue with a "now" time based on when the original handler was triggered. Previously it was being added with a now time of when the `$timeout.flush` method was originally called. Closes #5420 Closes #14686
1 parent 98e4a22 commit 1a387ba

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

src/ngMock/angular-mocks.js

+13-3
Original file line numberDiff line numberDiff line change
@@ -106,19 +106,29 @@ angular.mock.$Browser = function() {
106106
* @param {number=} number of milliseconds to flush. See {@link #defer.now}
107107
*/
108108
self.defer.flush = function(delay) {
109+
var nextTime;
110+
109111
if (angular.isDefined(delay)) {
110-
self.defer.now += delay;
112+
// A delay was passed so compute the next time
113+
nextTime = self.defer.now + delay;
111114
} else {
112115
if (self.deferredFns.length) {
113-
self.defer.now = self.deferredFns[self.deferredFns.length - 1].time;
116+
// No delay was passed so set the next time so that it clears the deferred queue
117+
nextTime = self.deferredFns[self.deferredFns.length - 1].time;
114118
} else {
119+
// No delay passed, but there are no deferred tasks so flush - indicates an error!
115120
throw new Error('No deferred tasks to be flushed');
116121
}
117122
}
118123

119-
while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) {
124+
while (self.deferredFns.length && self.deferredFns[0].time <= nextTime) {
125+
// Increment the time and call the next deferred function
126+
self.defer.now = self.deferredFns[0].time;
120127
self.deferredFns.shift().fn();
121128
}
129+
130+
// Ensure that the current time is correct
131+
self.defer.now = nextTime;
122132
};
123133

124134
self.$$baseHref = '/';

test/ngMock/angular-mocksSpec.js

+27-1
Original file line numberDiff line numberDiff line change
@@ -296,8 +296,10 @@ describe('ngMock', function() {
296296
expect(counter).toBe(1);
297297

298298
$interval.flush(1000);
299-
300299
expect(counter).toBe(2);
300+
301+
$interval.flush(2000);
302+
expect(counter).toBe(4);
301303
}));
302304

303305

@@ -692,6 +694,30 @@ describe('ngMock', function() {
692694
$timeout.flush(123);
693695
expect(count).toBe(2);
694696
}));
697+
698+
it('should resolve timeout functions following the timeline', inject(function($timeout) {
699+
var count1 = 0, count2 = 0;
700+
var iterate1 = function() {
701+
count1++;
702+
$timeout(iterate1, 100);
703+
};
704+
var iterate2 = function() {
705+
count2++;
706+
$timeout(iterate2, 150);
707+
};
708+
709+
$timeout(iterate1, 100);
710+
$timeout(iterate2, 150);
711+
$timeout.flush(150);
712+
expect(count1).toBe(1);
713+
expect(count2).toBe(1);
714+
$timeout.flush(50);
715+
expect(count1).toBe(2);
716+
expect(count2).toBe(1);
717+
$timeout.flush(400);
718+
expect(count1).toBe(6);
719+
expect(count2).toBe(4);
720+
}));
695721
});
696722

697723

0 commit comments

Comments
 (0)