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

Commit be7dd96

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 7ac5470 commit be7dd96

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
}
@@ -2291,7 +2314,18 @@ angular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $
22912314
$delegate.verifyNoPendingTasks = function() {
22922315
// For historical reasons, `$timeout.verifyNoPendingTasks()` takes all types of pending tasks
22932316
// into account. Keep the same behavior for backwards compatibility.
2294-
$browser.defer.verifyNoPendingTasks();
2317+
var pendingTasks = $browser.defer.getPendingTasks();
2318+
2319+
if (pendingTasks.length) {
2320+
var formattedTasks = $browser.defer.formatPendingTasks(pendingTasks).join('\n ');
2321+
var hasPendingTimeout = pendingTasks.some(function(task) { return task.type === '$timeout'; });
2322+
var extraMessage = hasPendingTimeout ? '' : '\n\nNone of the pending tasks are timeouts. ' +
2323+
'If you only want to verify pending timeouts, use ' +
2324+
'`$verifyNoPendingTasks(\'$timeout\')` instead.';
2325+
2326+
throw new Error('Deferred tasks to flush (' + pendingTasks.length + '):\n ' +
2327+
formattedTasks + extraMessage);
2328+
}
22952329
};
22962330

22972331
return $delegate;

test/ngMock/angular-mocksSpec.js

+21
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,27 @@ describe('ngMock', function() {
920920
}));
921921

922922

923+
it('should recommend `$verifyNoPendingTasks()` when all pending tasks are not timeouts',
924+
inject(function($rootScope, $timeout) {
925+
var extraMessage = 'None of the pending tasks are timeouts. If you only want to verify ' +
926+
'pending timeouts, use `$verifyNoPendingTasks(\'$timeout\')` instead.';
927+
var errorMessage;
928+
929+
$timeout(noop, 100);
930+
$rootScope.$evalAsync(noop);
931+
try { $timeout.verifyNoPendingTasks(); } catch (err) { errorMessage = err.message; }
932+
933+
expect(errorMessage).not.toContain(extraMessage);
934+
935+
$timeout.flush(100);
936+
$rootScope.$evalAsync(noop);
937+
try { $timeout.verifyNoPendingTasks(); } catch (err) { errorMessage = err.message; }
938+
939+
expect(errorMessage).toContain(extraMessage);
940+
})
941+
);
942+
943+
923944
it('should do nothing when all tasks have been flushed', inject(function($rootScope, $timeout) {
924945
$timeout(noop, 100);
925946
$rootScope.$evalAsync(noop);

0 commit comments

Comments
 (0)