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

Commit 58f9413

Browse files
committed
docs(ngMock/$timeout): recommend $verifyNoPendingTasks() when appropriate
For historical reasons, `$timeout.verifyNoPendingTasks()` throws if there is any type of task pending (even if it is not a timeout). When calling `$timeout.verifyNoPendingTasks()`, the user is most likely interested in verifying pending timeouts only, which is now possible with `$verifyNoPendingTasks('$timeout')`. To raise awareness of `$verifyNoPendingTasks()`, it is mentioned in the error message thrown by `$timeoutverifyNoPendingTasks()` if none of the pending tasks is a timeout.
1 parent 6f7674a commit 58f9413

File tree

2 files changed

+65
-10
lines changed

2 files changed

+65
-10
lines changed

src/ngMock/angular-mocks.js

+44-10
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,36 @@ angular.mock.$Browser = function($log, $$taskTrackerFactory) {
150150
self.defer.now = nextTime;
151151
};
152152

153+
/**
154+
* @name $browser#defer.getPendingTasks
155+
*
156+
* @description
157+
* Returns the currently pending tasks that need to be flushed.
158+
* You can request a specific type of tasks only, by specifying a `taskType`.
159+
*
160+
* @param {string=} taskType - The type tasks to return.
161+
*/
162+
self.defer.getPendingTasks = function(taskType) {
163+
return !taskType
164+
? self.deferredFns
165+
: self.deferredFns.filter(function(task) { return task.type === taskType; });
166+
};
167+
168+
/**
169+
* @name $browser#defer.formatPendingTasks
170+
*
171+
* @description
172+
* Formats each task in a list of pending tasks as a string, suitable for use in error messages.
173+
*
174+
* @param {Array<Object>} pendingTasks - A list of task objects.
175+
* @return {Array<string>} A list of stringified tasks.
176+
*/
177+
self.defer.formatPendingTasks = function(pendingTasks) {
178+
return pendingTasks.map(function(task) {
179+
return '{id: ' + task.id + ', type: ' + task.type + ', time: ' + task.time + '}';
180+
});
181+
};
182+
153183
/**
154184
* @name $browser#defer.verifyNoPendingTasks
155185
*
@@ -162,17 +192,10 @@ angular.mock.$Browser = function($log, $$taskTrackerFactory) {
162192
* @param {string=} taskType - The type tasks to check for.
163193
*/
164194
self.defer.verifyNoPendingTasks = function(taskType) {
165-
var pendingTasks = !taskType
166-
? self.deferredFns
167-
: self.deferredFns.filter(function(task) { return task.type === taskType; });
195+
var pendingTasks = self.defer.getPendingTasks(taskType);
168196

169197
if (pendingTasks.length) {
170-
var formattedTasks = pendingTasks
171-
.map(function(task) {
172-
return '{id: ' + task.id + ', type: ' + task.type + ', time: ' + task.time + '}';
173-
})
174-
.join('\n ');
175-
198+
var formattedTasks = self.defer.formatPendingTasks(pendingTasks).join('\n ');
176199
throw new Error('Deferred tasks to flush (' + pendingTasks.length + '):\n ' +
177200
formattedTasks);
178201
}
@@ -2306,7 +2329,18 @@ angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $
23062329
$delegate.verifyNoPendingTasks = function() {
23072330
// For historical reasons, `$timeout.verifyNoPendingTasks()` takes all types of pending tasks
23082331
// into account. Keep the same behavior for backwards compatibility.
2309-
$browser.defer.verifyNoPendingTasks();
2332+
var pendingTasks = $browser.defer.getPendingTasks();
2333+
2334+
if (pendingTasks.length) {
2335+
var formattedTasks = $browser.defer.formatPendingTasks(pendingTasks).join('\n ');
2336+
var hasPendingTimeout = pendingTasks.some(function(task) { return task.type === '$timeout'; });
2337+
var extraMessage = hasPendingTimeout ? '' : '\n\nNone of the pending tasks are timeouts. ' +
2338+
'If you only want to verify pending timeouts, use ' +
2339+
'`$verifyNoPendingTasks(\'$timeout\')` instead.';
2340+
2341+
throw new Error('Deferred tasks to flush (' + pendingTasks.length + '):\n ' +
2342+
formattedTasks + extraMessage);
2343+
}
23102344
};
23112345

23122346
return $delegate;

test/ngMock/angular-mocksSpec.js

+21
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,27 @@ describe('ngMock', function() {
977977
}));
978978

979979

980+
it('should recommend `$verifyNoPendingTasks()` when all pending tasks are not timeouts',
981+
inject(function($rootScope, $timeout) {
982+
var extraMessage = 'None of the pending tasks are timeouts. If you only want to verify ' +
983+
'pending timeouts, use `$verifyNoPendingTasks(\'$timeout\')` instead.';
984+
var errorMessage;
985+
986+
$timeout(noop, 100);
987+
$rootScope.$evalAsync(noop);
988+
try { $timeout.verifyNoPendingTasks(); } catch (err) { errorMessage = err.message; }
989+
990+
expect(errorMessage).not.toContain(extraMessage);
991+
992+
$timeout.flush(100);
993+
$rootScope.$evalAsync(noop);
994+
try { $timeout.verifyNoPendingTasks(); } catch (err) { errorMessage = err.message; }
995+
996+
expect(errorMessage).toContain(extraMessage);
997+
})
998+
);
999+
1000+
9801001
it('should do nothing when all tasks have been flushed', inject(function($rootScope, $timeout) {
9811002
$timeout(noop, 100);
9821003
$rootScope.$evalAsync(noop);

0 commit comments

Comments
 (0)