@@ -2082,4 +2082,152 @@ describe('$route', function() {
2082
2082
expect ( function ( ) { $route . updateParams ( ) ; } ) . toThrowMinErr ( 'ngRoute' , 'norout' ) ;
2083
2083
} ) ) ;
2084
2084
} ) ;
2085
+
2086
+ describe ( 'testability' , function ( ) {
2087
+ it ( 'should wait for $resolve promises before calling callbacks' , function ( ) {
2088
+ var deferred ;
2089
+
2090
+ module ( function ( $provide , $routeProvider ) {
2091
+ $routeProvider . when ( '/path' , { template : '' , resolve : {
2092
+ a : function ( $q ) {
2093
+ deferred = $q . defer ( ) ;
2094
+ return deferred . promise ;
2095
+ }
2096
+ } } ) ;
2097
+ } ) ;
2098
+
2099
+ inject ( function ( $location , $route , $rootScope , $httpBackend , $$testability ) {
2100
+ $location . path ( '/path' ) ;
2101
+ $rootScope . $digest ( ) ;
2102
+
2103
+ var callback = jasmine . createSpy ( 'callback' ) ;
2104
+ $$testability . whenStable ( callback ) ;
2105
+ expect ( callback ) . not . toHaveBeenCalled ( ) ;
2106
+
2107
+ deferred . resolve ( ) ;
2108
+ $rootScope . $digest ( ) ;
2109
+ expect ( callback ) . toHaveBeenCalled ( ) ;
2110
+ } ) ;
2111
+ } ) ;
2112
+
2113
+ it ( 'should call callback after $resolve promises are rejected' , function ( ) {
2114
+ var deferred ;
2115
+
2116
+ module ( function ( $provide , $routeProvider ) {
2117
+ $routeProvider . when ( '/path' , { template : '' , resolve : {
2118
+ a : function ( $q ) {
2119
+ deferred = $q . defer ( ) ;
2120
+ return deferred . promise ;
2121
+ }
2122
+ } } ) ;
2123
+ } ) ;
2124
+
2125
+ inject ( function ( $location , $route , $rootScope , $httpBackend , $$testability ) {
2126
+ $location . path ( '/path' ) ;
2127
+ $rootScope . $digest ( ) ;
2128
+
2129
+ var callback = jasmine . createSpy ( 'callback' ) ;
2130
+ $$testability . whenStable ( callback ) ;
2131
+ expect ( callback ) . not . toHaveBeenCalled ( ) ;
2132
+
2133
+ deferred . reject ( ) ;
2134
+ $rootScope . $digest ( ) ;
2135
+ expect ( callback ) . toHaveBeenCalled ( ) ;
2136
+ } ) ;
2137
+ } ) ;
2138
+
2139
+ it ( 'should wait for resolveRedirectTo promises before calling callbacks' , function ( ) {
2140
+ var deferred ;
2141
+
2142
+ module ( function ( $provide , $routeProvider ) {
2143
+ $routeProvider . when ( '/path' , { template : '' , resolveRedirectTo : function ( $q ) {
2144
+ deferred = $q . defer ( ) ;
2145
+ return deferred . promise ;
2146
+ }
2147
+ } ) ;
2148
+ } ) ;
2149
+
2150
+ inject ( function ( $location , $route , $rootScope , $httpBackend , $$testability ) {
2151
+ $location . path ( '/path' ) ;
2152
+ $rootScope . $digest ( ) ;
2153
+
2154
+ var callback = jasmine . createSpy ( 'callback' ) ;
2155
+ $$testability . whenStable ( callback ) ;
2156
+ expect ( callback ) . not . toHaveBeenCalled ( ) ;
2157
+
2158
+ deferred . resolve ( ) ;
2159
+ $rootScope . $digest ( ) ;
2160
+ expect ( callback ) . toHaveBeenCalled ( ) ;
2161
+ } ) ;
2162
+ } ) ;
2163
+
2164
+ it ( 'should call callback after resolveRedirectTo promises are rejected' , function ( ) {
2165
+ var deferred ;
2166
+
2167
+ module ( function ( $provide , $routeProvider ) {
2168
+ $routeProvider . when ( '/path' , { template : '' , resolveRedirectTo : function ( $q ) {
2169
+ deferred = $q . defer ( ) ;
2170
+ return deferred . promise ;
2171
+ }
2172
+ } ) ;
2173
+ } ) ;
2174
+
2175
+ inject ( function ( $location , $route , $rootScope , $httpBackend , $$testability ) {
2176
+ $location . path ( '/path' ) ;
2177
+ $rootScope . $digest ( ) ;
2178
+
2179
+ var callback = jasmine . createSpy ( 'callback' ) ;
2180
+ $$testability . whenStable ( callback ) ;
2181
+ expect ( callback ) . not . toHaveBeenCalled ( ) ;
2182
+
2183
+ deferred . reject ( ) ;
2184
+ $rootScope . $digest ( ) ;
2185
+ expect ( callback ) . toHaveBeenCalled ( ) ;
2186
+ } ) ;
2187
+ } ) ;
2188
+
2189
+ it ( 'should wait for all route promises before calling callbacks' , function ( ) {
2190
+ var redirectDeferred ;
2191
+ var localsDeferred ;
2192
+
2193
+ module ( function ( $provide , $routeProvider ) {
2194
+ $routeProvider .
2195
+ when ( '/foo' , { template : '' , resolveRedirectTo : function ( $q ) {
2196
+ redirectDeferred = $q . defer ( ) ;
2197
+ return redirectDeferred . promise ;
2198
+ } } ) .
2199
+ when ( '/bar' , { template : '' , resolve : {
2200
+ a : function ( $q ) {
2201
+ localsDeferred = $q . defer ( ) ;
2202
+ return localsDeferred . promise ;
2203
+ }
2204
+ } } ) ;
2205
+ } ) ;
2206
+
2207
+ inject ( function ( $browser , $location , $route , $rootScope , $httpBackend , $$testability ) {
2208
+ $location . path ( '/foo' ) ;
2209
+ $rootScope . $digest ( ) ;
2210
+
2211
+ var callback = jasmine . createSpy ( 'callback' ) ;
2212
+ $$testability . whenStable ( callback ) ;
2213
+ expect ( callback ) . not . toHaveBeenCalled ( ) ;
2214
+
2215
+ // ngRoute code is wrapped in a $browser.defer call (via $rootScope.evalAsync), which in
2216
+ // production would automatically call $$incOutstandingRequestCount and
2217
+ // $$completeOutstandingRequest before/after execution. However, ngMock does not call these
2218
+ // functions in its $browser.defer implementation, as this logic would make many tests
2219
+ // difficult to write. In this one case we need that logic, however, so we call the
2220
+ // functions manually.
2221
+ $browser . $$incOutstandingRequestCount ( ) ;
2222
+ redirectDeferred . resolve ( '/bar' ) ;
2223
+ $rootScope . $digest ( ) ;
2224
+ $browser . $$completeOutstandingRequest ( ) ;
2225
+ expect ( callback ) . not . toHaveBeenCalled ( ) ;
2226
+
2227
+ localsDeferred . resolve ( ) ;
2228
+ $rootScope . $digest ( ) ;
2229
+ expect ( callback ) . toHaveBeenCalled ( ) ;
2230
+ } ) ;
2231
+ } ) ;
2232
+ } ) ;
2085
2233
} ) ;
0 commit comments