Skip to content

Commit eb96074

Browse files
committed
feat(ngMock): add $flushPendingTasks() and $verifyNoPendingTasks()
`$flushPendingTasks([delay])` allows flushing all pending tasks (or up to a specific delay). This includes `$timeout`s, `$q` promises and tasks scheduled via `$rootScope.$applyAsync()` and `$rootScope.$evalAsync()`. (ATM, it only flushes tasks scheduled via `$browser.defer()`, which does not include `$http` requests and `$route` transitions.) `$verifyNoPendingTasks([taskType])` allows verifying that there are no pending tasks (in general or of a specific type). This includes tasks flushed by `$flushPendingTasks()` as well as pending `$http` requests and in-progress `$route` transitions. Background: `ngMock/$timeout` has `flush()` and `verifyNoPendingTasks()` methods, but they take all kinds of tasks into account which is confusing. For example, `$timeout.verifyNoPendingTasks()` can fail (even if there are no pending timeouts) because of an unrelated pending `$http` request. This behavior is retained for backwards compatibility, but the new methods are more generic (and thus less confusing) and also allow more fine-grained control (when appropriate). Closes angular#14336
1 parent a015177 commit eb96074

File tree

1 file changed

+77
-2
lines changed

1 file changed

+77
-2
lines changed

src/ngMock/angular-mocks.js

+77-2
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ angular.mock.$Browser = function($$taskTrackerFactory, $log) {
155155
* Verifies that there are no pending tasks that need to be flushed.
156156
* You can check for a specific type of tasks only, by specifying a `taskType`.
157157
*
158-
* @param {string=} taskType - The type task to check for.
158+
* @param {string=} taskType - The type tasks to check for.
159159
*/
160160
self.defer.verifyNoPendingTasks = function(taskType) {
161161
var pendingTasks = !taskType
@@ -212,6 +212,56 @@ angular.mock.$Browser.prototype = {
212212
}
213213
};
214214

215+
/**
216+
* @ngdoc function
217+
* @name $flushPendingTasks
218+
*
219+
* @description
220+
* Flushes all pending tasks and executes the corresponding callbacks.
221+
* Flushed tasks include `$timeout`s, `
222+
*
223+
* @param {number=} delay - The number of milliseconds to flush.
224+
*/
225+
angular.mock.$FlushPendingTasksProvider = function() {
226+
this.$get = [
227+
'$browser',
228+
function($browser) {
229+
return function $flushPendingTasks(delay) {
230+
return $browser.defer.flush(delay);
231+
};
232+
}
233+
];
234+
};
235+
236+
/**
237+
* @ngdoc function
238+
* @name $verifyNoPendingTasks
239+
*
240+
* @description
241+
* Verifies that there are no pending tasks that need to be flushed.
242+
* You can check for a specific type of tasks only, by specifying a `taskType`.
243+
*
244+
* Available task types:
245+
*
246+
* - `$timeout`: Pending timeouts (via {@link $timeout}).
247+
* - `$http`: Pending HTTP requests (via {@link $http}).
248+
* - `$route`: In-progress route transitions (via {@link $route}).
249+
* - `$applyAsync`: Pending tasks scheduled via {@link $rootScope#$applyAsync}.
250+
* - `$evalAsync`: Pending tasks scheduled via {@link $rootScope#$evalAsync}.
251+
* These include tasks scheduled via `$evalAsync()` indirectly (such as {@link $q} promises).
252+
*
253+
* @param {string=} taskType - The type of tasks to check for.
254+
*/
255+
angular.mock.$VerifyNoPendingTasksProvider = function() {
256+
this.$get = [
257+
'$browser',
258+
function($browser) {
259+
return function $verifyNoPendingTasks(taskType) {
260+
return $browser.defer.verifyNoPendingTasks(taskType);
261+
};
262+
}
263+
];
264+
};
215265

216266
/**
217267
* @ngdoc provider
@@ -2178,6 +2228,13 @@ angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $
21782228
* @description
21792229
*
21802230
* Flushes the queue of pending tasks.
2231+
* _This method is essentially an alias of {@link ngMock.$flushPendingTasks}._
2232+
*
2233+
* <div class="alert alert-warning">
2234+
* For historical reasons, this method will also flush non-`$timeout` pending tasks, such as
2235+
* {@link $q} promises and tasks scheduled via {@link $rootScope#$applyAsync} and
2236+
* {@link $rootScope#$evalAsync}.
2237+
* </div>
21812238
*
21822239
* @param {number=} delay maximum timeout amount to flush up until
21832240
*/
@@ -2194,6 +2251,22 @@ angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $
21942251
* @description
21952252
*
21962253
* Verifies that there are no pending tasks that need to be flushed.
2254+
* _This method is essentially an alias of {@link ngMock/$verifyNoPendingTasks} (called with no
2255+
* arguments)._
2256+
*
2257+
* <div class="alert alert-warning">
2258+
* <p>
2259+
* For historical reasons, this method will also verify non-`$timeout` pending tasks, such as
2260+
* pending {@link $http} requests, in-progress {@link $route} transitions, unresolved
2261+
* {@link $q} promises and tasks scheduled via {@link $rootScope#$applyAsync} and
2262+
* {@link $rootScope#$evalAsync}.
2263+
* </p>
2264+
* <p>
2265+
* It is recommended to use {@link ngMock/$verifyNoPendingTasks} instead, which additionally
2266+
* supports verifying a specific type of tasks. For example, you can verify there are no
2267+
* pending timeouts with `$verifyNoPendingTasks('$timeout')`.
2268+
* </p>
2269+
* </div>
21972270
*/
21982271
$delegate.verifyNoPendingTasks = function() {
21992272
// For historical reasons, `$timeout.verifyNoPendingTasks()` takes all types of pending tasks
@@ -2422,7 +2495,9 @@ angular.module('ngMock', ['ng']).provider({
24222495
$log: angular.mock.$LogProvider,
24232496
$interval: angular.mock.$IntervalProvider,
24242497
$rootElement: angular.mock.$RootElementProvider,
2425-
$componentController: angular.mock.$ComponentControllerProvider
2498+
$componentController: angular.mock.$ComponentControllerProvider,
2499+
$flushPendingTasks: angular.mock.$FlushPendingTasksProvider,
2500+
$verifyNoPendingTasks: angular.mock.$VerifyNoPendingTasksProvider
24262501
}).config(['$provide', '$compileProvider', function($provide, $compileProvider) {
24272502
$provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
24282503
$provide.decorator('$$rAF', angular.mock.$RAFDecorator);

0 commit comments

Comments
 (0)