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
This commit is contained in:
committed by
Peter Bacon Darwin
parent
de544807c2
commit
d23c1453cd
Vendored
+13
-3
@@ -106,19 +106,29 @@ angular.mock.$Browser = function() {
|
||||
* @param {number=} number of milliseconds to flush. See {@link #defer.now}
|
||||
*/
|
||||
self.defer.flush = function(delay) {
|
||||
var nextTime;
|
||||
|
||||
if (angular.isDefined(delay)) {
|
||||
self.defer.now += delay;
|
||||
// A delay was passed so compute the next time
|
||||
nextTime = self.defer.now + delay;
|
||||
} else {
|
||||
if (self.deferredFns.length) {
|
||||
self.defer.now = self.deferredFns[self.deferredFns.length - 1].time;
|
||||
// No delay was passed so set the next time so that it clears the deferred queue
|
||||
nextTime = self.deferredFns[self.deferredFns.length - 1].time;
|
||||
} else {
|
||||
// No delay passed, but there are no deferred tasks so flush - indicates an error!
|
||||
throw new Error('No deferred tasks to be flushed');
|
||||
}
|
||||
}
|
||||
|
||||
while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) {
|
||||
while (self.deferredFns.length && self.deferredFns[0].time <= nextTime) {
|
||||
// Increment the time and call the next deferred function
|
||||
self.defer.now = self.deferredFns[0].time;
|
||||
self.deferredFns.shift().fn();
|
||||
}
|
||||
|
||||
// Ensure that the current time is correct
|
||||
self.defer.now = nextTime;
|
||||
};
|
||||
|
||||
self.$$baseHref = '/';
|
||||
|
||||
Vendored
+27
-1
@@ -296,8 +296,10 @@ describe('ngMock', function() {
|
||||
expect(counter).toBe(1);
|
||||
|
||||
$interval.flush(1000);
|
||||
|
||||
expect(counter).toBe(2);
|
||||
|
||||
$interval.flush(2000);
|
||||
expect(counter).toBe(4);
|
||||
}));
|
||||
|
||||
|
||||
@@ -692,6 +694,30 @@ describe('ngMock', function() {
|
||||
$timeout.flush(123);
|
||||
expect(count).toBe(2);
|
||||
}));
|
||||
|
||||
it('should resolve timeout functions following the timeline', inject(function($timeout) {
|
||||
var count1 = 0, count2 = 0;
|
||||
var iterate1 = function() {
|
||||
count1++;
|
||||
$timeout(iterate1, 100);
|
||||
};
|
||||
var iterate2 = function() {
|
||||
count2++;
|
||||
$timeout(iterate2, 150);
|
||||
};
|
||||
|
||||
$timeout(iterate1, 100);
|
||||
$timeout(iterate2, 150);
|
||||
$timeout.flush(150);
|
||||
expect(count1).toBe(1);
|
||||
expect(count2).toBe(1);
|
||||
$timeout.flush(50);
|
||||
expect(count1).toBe(2);
|
||||
expect(count2).toBe(1);
|
||||
$timeout.flush(400);
|
||||
expect(count1).toBe(6);
|
||||
expect(count2).toBe(4);
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user