You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is an open angular issue (angular/angular.js#14336) where $timeout.verifyNoPendingTasks() throws if there are deferred functions that are unrelated to $timeout.
When upgrading my app from angular 1.6.1 to 1.6.2, one of my unit tests started failing with:
Error: Deferred tasks to flush (1): {id: 0, time: 0}
at Function.$delegate.verifyNoPendingTasks (https://code.angularjs.org/1.6.2/angular-mocks.js:2153:13)
"What does this have to do with ui.router?", you ask?
I was able to trace the source of the deferred task back to ui.router.state.$state.$get()
It seems that the $get() function for the $stateProviderimmediately creates a rejected promise (TransitionSuperseded), which is later used if a state being transitioned to is no longer valid:
scheduleProcessQueue(state) checks if state.status === 2, and if so calls nextTick(processChecks) -> $rootScope.$evalAsync() -> $browser.defer(), which pushes an item onto $browser.deferredFns making it’s length > 0...hence a pending task.
Expected Behavior:
Although the real issue at the root of this is angular/angular.js#14336 -the fact that $timeout.verifyNoPendingTasks() throws when there are any pending tasks (not just $timeout related ones); is it correct that simply loading the ui.router module (without any states configured, and no transitions triggered) causes an item to be added to $browser.deferredFns?
A workaround to fix my failing test was to simply call $timout.flush() to ensure that there are no pending tasks before running test that checks $timeout.verifyNoPendingTasks(); but the question remains: is it right that ui.router creates a pending task just in case a state transition is later superseded?
I appreciate the detailed and well researched bug report, thank you.
I don't think building the rejection beforehand is necessarily an anti-pattern, but I also do not think that it is strictly necessary. If you create a PR for legacy branch which generates those rejections on the fly using a factory, I will merge it.
I'd potentially need the same PR also created against the master branch, if we're doing the same thing in 1.0 (we might not be).
I have recently updated from v0.4.2 to v1.0.5, and I am happy to report that this no longer appears to be an issue (and I was able to remove the superfluous $timeout.flush() call that was previously added).
This is a:
My version of UI-Router is: (version)
0.4.2
Bug Report
Current Behavior:
There is an open angular issue (angular/angular.js#14336) where
$timeout.verifyNoPendingTasks()
throws if there are deferred functions that are unrelated to$timeout
.When upgrading my app from angular 1.6.1 to 1.6.2, one of my unit tests started failing with:
"What does this have to do with
ui.router
?", you ask?I was able to trace the source of the deferred task back to
ui.router.state.$state.$get()
It seems that the
$get()
function for the$stateProvider
immediately creates a rejected promise (TransitionSuperseded
), which is later used if a state being transitioned to is no longer valid:The call to
$q.reject()
here creates a pending task, i.e. in angular:qFactory.reject()
->qFactory.rejectPromise()
->qFactory.$$reject()
->scheduleProcessQueue(promise.$$state)
scheduleProcessQueue(state)
checks ifstate.status === 2
, and if so callsnextTick(processChecks)
->$rootScope.$evalAsync()
->$browser.defer()
, which pushes an item onto$browser.deferredFns
making it’s length > 0...hence a pending task.Expected Behavior:
Although the real issue at the root of this is angular/angular.js#14336 -the fact that
$timeout.verifyNoPendingTasks()
throws when there are any pending tasks (not just$timeout
related ones); is it correct that simply loading theui.router
module (without any states configured, and no transitions triggered) causes an item to be added to$browser.deferredFns
?A workaround to fix my failing test was to simply call
$timout.flush()
to ensure that there are no pending tasks before running test that checks$timeout.verifyNoPendingTasks()
; but the question remains: is it right thatui.router
creates a pending task just in case a state transition is later superseded?Link to Plunker that reproduces the issue:
https://plnkr.co/edit/BlRThFUSqWL0eGTvfFaA?p=preview
(uncomment the
$timout.flush()
call to apply the workaround)The text was updated successfully, but these errors were encountered: