@@ -301,7 +301,6 @@ describe('$http', function() {
301
301
$http = $h ;
302
302
$rootScope = $rs ;
303
303
$sce = $sc ;
304
- spyOn ( $rootScope , '$apply' ) . and . callThrough ( ) ;
305
304
} ] ) ) ;
306
305
307
306
it ( 'should throw error if the request configuration is not an object' , function ( ) {
@@ -1073,35 +1072,7 @@ describe('$http', function() {
1073
1072
1074
1073
describe ( 'callbacks' , function ( ) {
1075
1074
1076
- it ( 'should $apply after success callback' , function ( ) {
1077
- $httpBackend . when ( 'GET' ) . respond ( 200 ) ;
1078
- $http ( { method : 'GET' , url : '/some' } ) ;
1079
- $httpBackend . flush ( ) ;
1080
- expect ( $rootScope . $apply ) . toHaveBeenCalledOnce ( ) ;
1081
- } ) ;
1082
-
1083
-
1084
- it ( 'should $apply after error callback' , function ( ) {
1085
- $httpBackend . when ( 'GET' ) . respond ( 404 ) ;
1086
- $http ( { method : 'GET' , url : '/some' } ) . catch ( noop ) ;
1087
- $httpBackend . flush ( ) ;
1088
- expect ( $rootScope . $apply ) . toHaveBeenCalledOnce ( ) ;
1089
- } ) ;
1090
-
1091
-
1092
- it ( 'should $apply even if exception thrown during callback' , inject ( function ( $exceptionHandler ) {
1093
- $httpBackend . when ( 'GET' ) . respond ( 200 ) ;
1094
- callback . and . throwError ( 'error in callback' ) ;
1095
-
1096
- $http ( { method : 'GET' , url : '/some' } ) . then ( callback ) ;
1097
- $httpBackend . flush ( ) ;
1098
- expect ( $rootScope . $apply ) . toHaveBeenCalledOnce ( ) ;
1099
-
1100
- $exceptionHandler . errors = [ ] ;
1101
- } ) ) ;
1102
-
1103
-
1104
- it ( 'should pass the event handlers through to the backend' , function ( ) {
1075
+ it ( 'should pass the event handlers through to the backend' , inject ( function ( $browser ) {
1105
1076
var progressFn = jasmine . createSpy ( 'progressFn' ) ;
1106
1077
var uploadProgressFn = jasmine . createSpy ( 'uploadProgressFn' ) ;
1107
1078
$httpBackend . when ( 'GET' ) . respond ( 200 ) ;
@@ -1117,16 +1088,17 @@ describe('$http', function() {
1117
1088
expect ( mockXHR . upload . $$events . progress ) . toEqual ( jasmine . any ( Function ) ) ;
1118
1089
1119
1090
var eventObj = { } ;
1120
- spyOn ( $rootScope , '$digest' ) ;
1121
1091
1122
1092
mockXHR . $$events . progress ( eventObj ) ;
1093
+ // The invocation of the callback is scheduled via `$evalAsync`,
1094
+ // that's why `flush` is needed here.
1095
+ $browser . defer . flush ( ) ;
1123
1096
expect ( progressFn ) . toHaveBeenCalledOnceWith ( eventObj ) ;
1124
- expect ( $rootScope . $digest ) . toHaveBeenCalledTimes ( 1 ) ;
1125
1097
1126
1098
mockXHR . upload . $$events . progress ( eventObj ) ;
1099
+ $browser . defer . flush ( ) ;
1127
1100
expect ( uploadProgressFn ) . toHaveBeenCalledOnceWith ( eventObj ) ;
1128
- expect ( $rootScope . $digest ) . toHaveBeenCalledTimes ( 2 ) ;
1129
- } ) ;
1101
+ } ) ) ;
1130
1102
} ) ;
1131
1103
1132
1104
@@ -2293,35 +2265,27 @@ describe('$http', function() {
2293
2265
} ) ;
2294
2266
2295
2267
2296
- describe ( '$http with $applyAsync' , function ( ) {
2297
- var $http , $httpBackend , $rootScope , $browser , log ;
2298
- beforeEach ( module ( function ( $httpProvider ) {
2299
- $httpProvider . useApplyAsync ( true ) ;
2300
- } , provideLog ) ) ;
2301
-
2268
+ describe ( '$http interacting with digest cycle' , function ( ) {
2269
+ var $http , $httpBackend , $browser , log ;
2270
+ beforeEach ( module ( provideLog ) ) ;
2302
2271
2303
- beforeEach ( inject ( [ '$http' , '$httpBackend' , '$rootScope' , '$ browser', 'log' , function ( http , backend , scope , browser , logger ) {
2272
+ beforeEach ( inject ( [ '$http' , '$httpBackend' , '$browser' , 'log' , function ( http , backend , browser , logger ) {
2304
2273
$http = http ;
2305
2274
$httpBackend = backend ;
2306
- $rootScope = scope ;
2307
2275
$browser = browser ;
2308
- spyOn ( $rootScope , '$apply' ) . and . callThrough ( ) ;
2309
- spyOn ( $rootScope , '$applyAsync' ) . and . callThrough ( ) ;
2310
- spyOn ( $rootScope , '$digest' ) . and . callThrough ( ) ;
2311
- spyOn ( $browser . defer , 'cancel' ) . and . callThrough ( ) ;
2312
2276
log = logger ;
2313
2277
} ] ) ) ;
2314
2278
2315
2279
2316
- it ( 'should schedule coalesced apply on response ' , function ( ) {
2280
+ it ( 'should execute callbacks asynchronously in $digest ' , function ( ) {
2317
2281
var handler = jasmine . createSpy ( 'handler' ) ;
2318
2282
$httpBackend . expect ( 'GET' , '/template1.html' ) . respond ( 200 , '<h1>Header!</h1>' , { } ) ;
2319
2283
$http . get ( '/template1.html' ) . then ( handler ) ;
2320
- // Ensure requests are sent
2321
- $rootScope . $digest ( ) ;
2284
+ // Ensure requests are sent. ($http is internally promise-based and doesn't start working until
2285
+ // $digest occurs.)
2286
+ $browser . defer . flush ( ) ;
2322
2287
2323
2288
$httpBackend . flush ( null , null , false ) ;
2324
- expect ( $rootScope . $applyAsync ) . toHaveBeenCalledOnce ( ) ;
2325
2289
expect ( handler ) . not . toHaveBeenCalled ( ) ;
2326
2290
2327
2291
$browser . defer . flush ( ) ;
@@ -2336,11 +2300,14 @@ describe('$http with $applyAsync', function() {
2336
2300
$http . get ( '/template1.html' ) . then ( log . fn ( 'response 1' ) ) ;
2337
2301
$http . get ( '/template2.html' ) . then ( log . fn ( 'response 2' ) ) ;
2338
2302
// Ensure requests are sent
2339
- $rootScope . $digest ( ) ;
2303
+ $browser . defer . flush ( ) ;
2340
2304
2305
+ // Resolve the promises. When a $q promise is resolved it uses $rootScope.$evalAsync to schedule
2306
+ // the execution of its callbacks.
2341
2307
$httpBackend . flush ( null , null , false ) ;
2342
2308
expect ( log ) . toEqual ( [ ] ) ;
2343
2309
2310
+ // Execute the promises' callbacks in the $digest scheduled with $evalAsync
2344
2311
$browser . defer . flush ( ) ;
2345
2312
expect ( log ) . toEqual ( [ 'response 1' , 'response 2' ] ) ;
2346
2313
} ) ;
@@ -2354,16 +2321,16 @@ describe('$http with $applyAsync', function() {
2354
2321
$http . get ( '/template1.html' ) . then ( log . fn ( 'response 1' ) ) ;
2355
2322
$http . get ( '/template2.html' ) . then ( log . fn ( 'response 2' ) ) ;
2356
2323
$http . get ( '/template3.html' ) . then ( log . fn ( 'response 3' ) ) ;
2357
- // Ensure requests are sent
2358
- $rootScope . $digest ( ) ;
2359
2324
2360
2325
// Intermediate $digest occurs before 3rd response is received, assert that pending responses
2361
- /// are handled
2326
+ // are handled. Unless false is passed as the second parameter, $httpBackend.flush calls
2327
+ // $rootScope.$digest at least twice (before and after doing the flush).
2362
2328
$httpBackend . flush ( 2 ) ;
2363
2329
expect ( log ) . toEqual ( [ 'response 1' , 'response 2' ] ) ;
2364
2330
2365
- // Finally, third response is received, and a second coalesced $apply is started
2331
+ // Finally, third response is received, and its callback is scheduled with $evalAsync
2366
2332
$httpBackend . flush ( null , null , false ) ;
2333
+ // Execute the promises' callbacks in the $digest scheduled with $evalAsync
2367
2334
$browser . defer . flush ( ) ;
2368
2335
expect ( log ) . toEqual ( [ 'response 1' , 'response 2' , 'response 3' ] ) ;
2369
2336
} ) ;
0 commit comments