| OLD | NEW |
| 1 library zone_spec; | 1 library zone_spec; |
| 2 | 2 |
| 3 import '../_specs.dart'; | 3 import '../_specs.dart'; |
| 4 | 4 |
| 5 import 'dart:async'; | 5 import 'dart:async'; |
| 6 | 6 |
| 7 void main() { | 7 main() => describe('zone', () { |
| 8 describe('zone', () { | 8 var zone; |
| 9 var zone; | 9 var exceptionHandler; |
| 10 var exceptionHandler; | 10 beforeEach(module((Module module) { |
| 11 beforeEachModule((Module module) { | 11 exceptionHandler = new LoggingExceptionHandler(); |
| 12 exceptionHandler = new LoggingExceptionHandler(); | 12 module.value(ExceptionHandler, exceptionHandler); |
| 13 module.value(ExceptionHandler, exceptionHandler); | 13 })); |
| 14 }); | 14 |
| 15 | 15 beforeEach(inject((Logger log, ExceptionHandler eh) { |
| 16 beforeEach((Logger log, ExceptionHandler eh) { | 16 zone = new NgZone(); |
| 17 zone = new VmTurnZone(); | 17 zone.onTurnDone = () { |
| 18 log('onTurnDone'); |
| 19 }; |
| 20 zone.onError = (e, s, ls) => eh(e, s); |
| 21 })); |
| 22 |
| 23 |
| 24 describe('exceptions', () { |
| 25 it('should rethrow exceptions from the body and call onError', () { |
| 26 var error; |
| 27 zone.onError = (e, s, l) => error = e; |
| 28 expect(() { |
| 29 zone.run(() { |
| 30 throw ['hello']; |
| 31 }); |
| 32 }).toThrow('hello'); |
| 33 expect(error).toEqual(['hello']); |
| 34 }); |
| 35 |
| 36 |
| 37 it('should call onError for errors from scheduleMicrotask', async(inject(()
{ |
| 38 zone.run(() { |
| 39 scheduleMicrotask(() { |
| 40 throw ["async exception"]; |
| 41 }); |
| 42 }); |
| 43 |
| 44 expect(exceptionHandler.errors.length).toEqual(1); |
| 45 expect(exceptionHandler.errors[0].error).toEqual(["async exception"]); |
| 46 }))); |
| 47 |
| 48 |
| 49 it('should allow executing code outside the zone', inject(() { |
| 50 var zone = new NgZone(); |
| 51 var outerZone = Zone.current; |
| 52 var ngZone; |
| 53 var outsideZone; |
| 54 zone.run(() { |
| 55 ngZone = Zone.current; |
| 56 zone.runOutsideAngular(() { |
| 57 outsideZone = Zone.current; |
| 58 }); |
| 59 }); |
| 60 |
| 61 expect(outsideZone).toEqual(outerZone); |
| 62 expect(ngZone.parent).toEqual((outerZone)); |
| 63 })); |
| 64 |
| 65 |
| 66 it('should rethrow exceptions from the onTurnDone and call onError when the
zone is sync', () { |
| 18 zone.onTurnDone = () { | 67 zone.onTurnDone = () { |
| 19 log('onTurnDone'); | 68 throw ["fromOnTurnDone"]; |
| 20 }; | 69 }; |
| 21 zone.onTurnStart = () { | 70 |
| 22 log('onTurnStart'); | 71 expect(() { |
| 72 zone.run(() { }); |
| 73 }).toThrow('fromOnTurnDone'); |
| 74 |
| 75 expect(exceptionHandler.errors.length).toEqual(1); |
| 76 expect(exceptionHandler.errors[0].error).toEqual(["fromOnTurnDone"]); |
| 77 }); |
| 78 |
| 79 |
| 80 it('should rethrow exceptions from the onTurnDone and call onError when the
zone is async', () { |
| 81 var asyncRan = false; |
| 82 |
| 83 zone.onTurnDone = () { |
| 84 throw ["fromOnTurnDone"]; |
| 23 }; | 85 }; |
| 24 zone.onError = (e, s, ls) => eh(e, s); | 86 |
| 25 }); | 87 expect(() { |
| 26 | |
| 27 | |
| 28 describe('exceptions', () { | |
| 29 it('should rethrow exceptions from the body and call onError', () { | |
| 30 var error; | |
| 31 zone.onError = (e, s, l) => error = e; | |
| 32 expect(() { | |
| 33 zone.run(() { | |
| 34 throw ['hello']; | |
| 35 }); | |
| 36 }).toThrow('hello'); | |
| 37 expect(error).toEqual(['hello']); | |
| 38 }); | |
| 39 | |
| 40 | |
| 41 it('should call onError for errors from scheduleMicrotask', async(() { | |
| 42 zone.run(() { | 88 zone.run(() { |
| 43 scheduleMicrotask(() { | 89 scheduleMicrotask(() { |
| 44 throw ["async exception"]; | 90 asyncRan = true; |
| 45 }); | 91 }); |
| 46 }); | 92 }); |
| 47 | 93 }).toThrow('fromOnTurnDone'); |
| 48 expect(exceptionHandler.errors.length).toEqual(1); | 94 |
| 49 expect(exceptionHandler.errors[0].error).toEqual(["async exception"]); | 95 expect(asyncRan).toBeTruthy(); |
| 50 })); | 96 expect(exceptionHandler.errors.length).toEqual(1); |
| 51 | 97 expect(exceptionHandler.errors[0].error).toEqual(["fromOnTurnDone"]); |
| 52 | 98 }); |
| 53 it('should allow executing code outside the zone', () { | 99 }); |
| 54 var zone = new VmTurnZone(); | 100 |
| 55 var outerZone = Zone.current; | 101 xdescribe('long stack traces', () { |
| 56 var ngZone; | 102 it('should have nice error when crossing scheduleMicrotask boundries', async
(inject(() { |
| 57 var outsideZone; | 103 var error; |
| 58 zone.run(() { | 104 var stack; |
| 59 ngZone = Zone.current; | 105 var longStacktrace; |
| 60 zone.runOutsideAngular(() { | 106 |
| 61 outsideZone = Zone.current; | 107 zone.onError = (e, s, f) { |
| 62 }); | 108 error = e; |
| 63 }); | 109 stack = s; |
| 64 | 110 longStacktrace = f; |
| 65 expect(outsideZone).toEqual(outerZone); | |
| 66 expect(ngZone.parent).toEqual((outerZone)); | |
| 67 }); | |
| 68 | |
| 69 | |
| 70 it('should rethrow exceptions from the onTurnDone and call onError when th
e zone is sync', () { | |
| 71 zone.onTurnDone = () { | |
| 72 throw ["fromOnTurnDone"]; | |
| 73 }; | |
| 74 | |
| 75 expect(() { | |
| 76 zone.run(() { }); | |
| 77 }).toThrow('fromOnTurnDone'); | |
| 78 | |
| 79 expect(exceptionHandler.errors.length).toEqual(1); | |
| 80 expect(exceptionHandler.errors[0].error).toEqual(["fromOnTurnDone"]); | |
| 81 }); | |
| 82 | |
| 83 | |
| 84 it('should rethrow exceptions from the onTurnDone and call onError when th
e zone is async', () { | |
| 85 var asyncRan = false; | |
| 86 | |
| 87 zone.onTurnDone = () { | |
| 88 throw ["fromOnTurnDone"]; | |
| 89 }; | |
| 90 | |
| 91 expect(() { | |
| 92 zone.run(() { | |
| 93 scheduleMicrotask(() { | |
| 94 asyncRan = true; | |
| 95 }); | |
| 96 }); | |
| 97 }).toThrow('fromOnTurnDone'); | |
| 98 | |
| 99 expect(asyncRan).toBeTruthy(); | |
| 100 expect(exceptionHandler.errors.length).toEqual(1); | |
| 101 expect(exceptionHandler.errors[0].error).toEqual(["fromOnTurnDone"]); | |
| 102 }); | |
| 103 }); | |
| 104 | |
| 105 xdescribe('long stack traces', () { | |
| 106 it('should have nice error when crossing scheduleMicrotask boundries', asy
nc(() { | |
| 107 var error; | |
| 108 var stack; | |
| 109 var longStacktrace; | |
| 110 | |
| 111 zone.onError = (e, s, f) { | |
| 112 error = e; | |
| 113 stack = s; | |
| 114 longStacktrace = f; | |
| 115 }; | |
| 116 var FRAME = new RegExp(r'.*\(.*\:(\d+):\d+\)'); | |
| 117 | |
| 118 var line = ((){ try {throw [];} catch(e, s) { return int.parse(FRAME.fir
stMatch('$s')[1]);}})(); | |
| 119 var throwFn = () { throw ['double zonned']; }; | |
| 120 var inner = () => zone.run(throwFn); | |
| 121 var middle = () => scheduleMicrotask(inner); | |
| 122 var outer = () => scheduleMicrotask(middle); | |
| 123 zone.run(outer); | |
| 124 | |
| 125 microLeap(); | |
| 126 expect(error).toEqual(['double zonned']); | |
| 127 | |
| 128 // Not in dart2js.. | |
| 129 if ('$stack'.contains('.dart.js')) { | |
| 130 return; | |
| 131 } | |
| 132 | |
| 133 expect('$stack').toContain('zone_spec.dart:${line+1}'); | |
| 134 expect('$stack').toContain('zone_spec.dart:${line+2}'); | |
| 135 expect('$longStacktrace').toContain('zone_spec.dart:${line+3}'); | |
| 136 expect('$longStacktrace').toContain('zone_spec.dart:${line+4}'); | |
| 137 expect('$longStacktrace').toContain('zone_spec.dart:${line+5}'); | |
| 138 })); | |
| 139 }); | |
| 140 | |
| 141 it('should call onTurnDone after a synchronous view', (Logger log) { | |
| 142 zone.run(() { | |
| 143 log('run'); | |
| 144 }); | |
| 145 expect(log.result()).toEqual('onTurnStart; run; onTurnDone'); | |
| 146 }); | |
| 147 | |
| 148 | |
| 149 it('should return the body return value from run', () { | |
| 150 expect(zone.run(() { return 6; })).toEqual(6); | |
| 151 }); | |
| 152 | |
| 153 | |
| 154 it('should call onTurnStart before executing a microtask scheduled in onTurn
Done as well as ' | |
| 155 'onTurnDone after executing the task', async((Logger log) { | |
| 156 var ran = false; | |
| 157 zone.onTurnDone = () { | |
| 158 log('onTurnDone(begin)'); | |
| 159 if (!ran) { | |
| 160 scheduleMicrotask(() { ran = true; log('executedMicrotask'); }); | |
| 161 } | |
| 162 log('onTurnDone(end)'); | |
| 163 }; | 111 }; |
| 164 zone.run(() { | 112 var FRAME = new RegExp(r'.*\(.*\:(\d+):\d+\)'); |
| 165 log('run'); | 113 |
| 166 }); | 114 var line = ((){ try {throw [];} catch(e, s) { return int.parse(FRAME.first
Match('$s')[1]);}})(); |
| 115 var throwFn = () { throw ['double zonned']; }; |
| 116 var inner = () => zone.run(throwFn); |
| 117 var middle = () => scheduleMicrotask(inner); |
| 118 var outer = () => scheduleMicrotask(middle); |
| 119 zone.run(outer); |
| 120 |
| 167 microLeap(); | 121 microLeap(); |
| 168 | 122 expect(error).toEqual(['double zonned']); |
| 169 expect(log.result()).toEqual('onTurnStart; run; onTurnDone(begin); onTurnD
one(end); onTurnStart; executedMicrotask; onTurnDone(begin); onTurnDone(end)'); | 123 |
| 170 })); | 124 // Not in dart2js.. |
| 171 | 125 if ('$stack'.contains('.dart.js')) { |
| 172 | 126 return; |
| 173 it('should call onTurnStart and onTurnDone for a scheduleMicrotask in onTurn
Done triggered by a scheduleMicrotask in run', async((Logger log) { | 127 } |
| 174 var ran = false; | 128 |
| 175 zone.onTurnDone = () { | 129 expect('$stack').toContain('zone_spec.dart:${line+1}'); |
| 176 log('onTurnDone(begin)'); | 130 expect('$stack').toContain('zone_spec.dart:${line+2}'); |
| 177 if (!ran) { | 131 expect('$longStacktrace').toContain('zone_spec.dart:${line+3}'); |
| 178 log('onTurnDone(scheduleMicrotask)'); | 132 expect('$longStacktrace').toContain('zone_spec.dart:${line+4}'); |
| 179 scheduleMicrotask(() { | 133 expect('$longStacktrace').toContain('zone_spec.dart:${line+5}'); |
| 180 ran = true; | 134 }))); |
| 181 log('onTurnDone(executeMicrotask)'); | 135 }); |
| 182 }); | 136 |
| 183 } | 137 it('should call onTurnDone after a synchronous block', inject((Logger log) { |
| 184 log('onTurnDone(end)'); | 138 zone.run(() { |
| 185 }; | 139 log('run'); |
| 186 zone.run(() { | 140 }); |
| 187 log('scheduleMicrotask'); | 141 expect(log.result()).toEqual('run; onTurnDone'); |
| 188 scheduleMicrotask(() { | 142 })); |
| 189 log('run(executeMicrotask)'); | 143 |
| 190 }); | 144 |
| 191 }); | 145 it('should return the body return value from run', () { |
| 192 microLeap(); | 146 expect(zone.run(() { return 6; })).toEqual(6); |
| 193 | 147 }); |
| 194 expect(log.result()).toEqual('onTurnStart; scheduleMicrotask; run(executeM
icrotask); onTurnDone(begin); onTurnDone(scheduleMicrotask); onTurnDone(end); on
TurnStart; onTurnDone(executeMicrotask); onTurnDone(begin); onTurnDone(end)'); | 148 |
| 195 })); | 149 |
| 196 | 150 it('should call onTurnDone for a scheduleMicrotask in onTurnDone', async(injec
t((Logger log) { |
| 197 | 151 var ran = false; |
| 198 | 152 zone.onTurnDone = () { |
| 199 it('should call onTurnStart once before a turn and onTurnDone once after the
turn', async((Logger log) { | 153 if (!ran) { |
| 200 zone.run(() { | 154 scheduleMicrotask(() { ran = true; log('onTurnAsync'); }); |
| 201 log('run start'); | 155 } |
| 202 scheduleMicrotask(() { | 156 log('onTurnDone'); |
| 203 log('async'); | 157 }; |
| 204 }); | 158 zone.run(() { |
| 205 log('run end'); | 159 log('run'); |
| 206 }); | 160 }); |
| 207 microLeap(); | 161 microLeap(); |
| 208 | 162 |
| 209 expect(log.result()).toEqual('onTurnStart; run start; run end; async; onTu
rnDone'); | 163 expect(log.result()).toEqual('run; onTurnDone; onTurnAsync; onTurnDone'); |
| 210 })); | 164 }))); |
| 211 | 165 |
| 212 | 166 |
| 213 it('should work for Future.value as well', async((Logger log) { | 167 it('should call onTurnDone for a scheduleMicrotask in onTurnDone triggered by
a scheduleMicrotask in run', async(inject((Logger log) { |
| 214 var futureRan = false; | 168 var ran = false; |
| 215 zone.onTurnDone = () { | 169 zone.onTurnDone = () { |
| 216 log('onTurnDone(begin)'); | 170 if (!ran) { |
| 217 if (!futureRan) { | 171 scheduleMicrotask(() { ran = true; log('onTurnAsync'); }); |
| 218 log('onTurnDone(scheduleFuture)'); | 172 } |
| 219 new Future.value(null).then((_) { log('onTurnDone(executeFuture)'); })
; | 173 log('onTurnDone'); |
| 220 futureRan = true; | 174 }; |
| 221 } | 175 zone.run(() { |
| 222 log('onTurnDone(end)'); | 176 scheduleMicrotask(() { log('scheduleMicrotask'); }); |
| 223 }; | 177 log('run'); |
| 224 | 178 }); |
| 225 zone.run(() { | 179 microLeap(); |
| 226 log('run start'); | 180 |
| 227 new Future.value(null) | 181 expect(log.result()).toEqual('run; scheduleMicrotask; onTurnDone; onTurnAsyn
c; onTurnDone'); |
| 182 }))); |
| 183 |
| 184 |
| 185 |
| 186 it('should call onTurnDone once after a turn', async(inject((Logger log) { |
| 187 zone.run(() { |
| 188 log('run start'); |
| 189 scheduleMicrotask(() { |
| 190 log('async'); |
| 191 }); |
| 192 log('run end'); |
| 193 }); |
| 194 microLeap(); |
| 195 |
| 196 expect(log.result()).toEqual('run start; run end; async; onTurnDone'); |
| 197 }))); |
| 198 |
| 199 |
| 200 it('should work for Future.value as well', async(inject((Logger log) { |
| 201 var futureRan = false; |
| 202 zone.onTurnDone = () { |
| 203 if (!futureRan) { |
| 204 new Future.value(null).then((_) { log('onTurn future'); }); |
| 205 futureRan = true; |
| 206 } |
| 207 log('onTurnDone'); |
| 208 }; |
| 209 |
| 210 zone.run(() { |
| 211 log('run start'); |
| 212 new Future.value(null) |
| 228 .then((_) { | 213 .then((_) { |
| 229 log('future then'); | 214 log('future then'); |
| 230 new Future.value(null) | 215 new Future.value(null) |
| 231 .then((_) { log('future foo'); }); | 216 .then((_) { log('future ?'); }); |
| 232 return new Future.value(null); | 217 return new Future.value(null); |
| 233 }) | 218 }) |
| 234 .then((_) { | 219 .then((_) { |
| 235 log('future bar'); | 220 log('future ?'); |
| 236 }); | 221 }); |
| 237 log('run end'); | 222 log('run end'); |
| 238 }); | 223 }); |
| 224 microLeap(); |
| 225 |
| 226 expect(log.result()).toEqual('run start; run end; future then; future ?; fut
ure ?; onTurnDone; onTurn future; onTurnDone'); |
| 227 }))); |
| 228 |
| 229 |
| 230 it('should call onTurnDone after each turn', async(inject((Logger log) { |
| 231 Completer a, b; |
| 232 zone.run(() { |
| 233 a = new Completer(); |
| 234 b = new Completer(); |
| 235 a.future.then((_) => log('a then')); |
| 236 b.future.then((_) => log('b then')); |
| 237 log('run start'); |
| 238 }); |
| 239 microLeap(); |
| 240 zone.run(() { |
| 241 a.complete(null); |
| 242 }); |
| 243 microLeap(); |
| 244 zone.run(() { |
| 245 b.complete(null); |
| 246 }); |
| 247 microLeap(); |
| 248 |
| 249 expect(log.result()).toEqual('run start; onTurnDone; a then; onTurnDone; b t
hen; onTurnDone'); |
| 250 }))); |
| 251 |
| 252 |
| 253 it('should call onTurnDone after each turn in a chain', async(inject((Logger l
og) { |
| 254 zone.run(() { |
| 255 log('run start'); |
| 256 scheduleMicrotask(() { |
| 257 log('async1'); |
| 258 scheduleMicrotask(() { |
| 259 log('async2'); |
| 260 }); |
| 261 }); |
| 262 log('run end'); |
| 263 }); |
| 264 microLeap(); |
| 265 |
| 266 expect(log.result()).toEqual('run start; run end; async1; async2; onTurnDone
'); |
| 267 }))); |
| 268 |
| 269 it('should call onTurnDone for futures created outside of run body', async(inj
ect((Logger log) { |
| 270 var future = new Future.value(4).then((x) => new Future.value(x)); |
| 271 zone.run(() { |
| 272 future.then((_) => log('future then')); |
| 273 log('zone run'); |
| 274 }); |
| 275 microLeap(); |
| 276 |
| 277 expect(log.result()).toEqual('zone run; onTurnDone; future then; onTurnDone'
); |
| 278 }))); |
| 279 |
| 280 |
| 281 it('should call onTurnDone even if there was an exception in body', async(inje
ct((Logger log) { |
| 282 zone.onError = (e, s, l) => log('onError'); |
| 283 expect(() => zone.run(() { |
| 284 log('zone run'); |
| 285 throw 'zoneError'; |
| 286 })).toThrow('zoneError'); |
| 287 expect(() => zone.assertInTurn()).toThrow(); |
| 288 expect(log.result()).toEqual('zone run; onError; onTurnDone'); |
| 289 }))); |
| 290 |
| 291 |
| 292 it('should call onTurnDone even if there was an exception in scheduleMicrotask
', async(inject((Logger log) { |
| 293 zone.onError = (e, s, l) => log('onError'); |
| 294 zone.run(() { |
| 295 log('zone run'); |
| 296 scheduleMicrotask(() { |
| 297 log('scheduleMicrotask'); |
| 298 throw new Error(); |
| 299 }); |
| 300 }); |
| 301 |
| 302 microLeap(); |
| 303 |
| 304 expect(() => zone.assertInTurn()).toThrow(); |
| 305 expect(log.result()).toEqual('zone run; scheduleMicrotask; onError; onTurnDo
ne'); |
| 306 }))); |
| 307 |
| 308 it('should support assertInZone', async(() { |
| 309 var calls = ''; |
| 310 zone.onTurnDone = () { |
| 311 zone.assertInZone(); |
| 312 calls += 'done;'; |
| 313 }; |
| 314 zone.run(() { |
| 315 zone.assertInZone(); |
| 316 calls += 'sync;'; |
| 317 scheduleMicrotask(() { |
| 318 zone.assertInZone(); |
| 319 calls += 'async;'; |
| 320 }); |
| 321 }); |
| 322 |
| 323 microLeap(); |
| 324 expect(calls).toEqual('sync;async;done;'); |
| 325 })); |
| 326 |
| 327 it('should throw outside of the zone', () { |
| 328 expect(async(() { |
| 329 zone.assertInZone(); |
| 239 microLeap(); | 330 microLeap(); |
| 240 | 331 })).toThrow(); |
| 241 expect(log.result()).toEqual('onTurnStart; run start; run end; future then
; future foo; future bar; onTurnDone(begin); onTurnDone(scheduleFuture); onTurnD
one(end); onTurnStart; onTurnDone(executeFuture); onTurnDone(begin); onTurnDone(
end)'); | 332 }); |
| 242 })); | 333 |
| 243 | 334 |
| 244 it('should execute futures scheduled in onTurnStart before Futures scheduled
in run', async((Logger log) { | 335 it('should support assertInTurn', async(() { |
| 245 var doneFutureRan = false; | 336 var calls = ''; |
| 246 var startFutureRan = false; | 337 zone.onTurnDone = () { |
| 247 zone.onTurnStart = () { | 338 calls += 'done;'; |
| 248 log('onTurnStart(begin)'); | 339 zone.assertInTurn(); |
| 249 if (!startFutureRan) { | 340 }; |
| 250 log('onTurnStart(scheduleFuture)'); | 341 zone.run(() { |
| 251 new Future.value(null).then((_) { log('onTurnStart(executeFuture)'); }
); | 342 calls += 'sync;'; |
| 252 startFutureRan = true; | 343 zone.assertInTurn(); |
| 253 } | 344 scheduleMicrotask(() { |
| 254 log('onTurnStart(end)'); | 345 calls += 'async;'; |
| 255 }; | 346 zone.assertInTurn(); |
| 256 zone.onTurnDone = () { | 347 }); |
| 257 log('onTurnDone(begin)'); | 348 }); |
| 258 if (!doneFutureRan) { | 349 |
| 259 log('onTurnDone(scheduleFuture)'); | 350 microLeap(); |
| 260 new Future.value(null).then((_) { log('onTurnDone(executeFuture)'); })
; | 351 expect(calls).toEqual('sync;async;done;'); |
| 261 doneFutureRan = true; | 352 })); |
| 262 } | 353 |
| 263 log('onTurnDone(end)'); | 354 |
| 264 }; | 355 it('should assertInTurn outside of the zone', () { |
| 265 | 356 expect(async(() { |
| 266 zone.run(() { | 357 zone.assertInTurn(); |
| 267 log('run start'); | |
| 268 new Future.value(null) | |
| 269 .then((_) { | |
| 270 log('future then'); | |
| 271 new Future.value(null) | |
| 272 .then((_) { log('future foo'); }); | |
| 273 return new Future.value(null); | |
| 274 }) | |
| 275 .then((_) { | |
| 276 log('future bar'); | |
| 277 }); | |
| 278 log('run end'); | |
| 279 }); | |
| 280 microLeap(); | 358 microLeap(); |
| 281 | 359 })).toThrow('ssertion'); // Support both dart2js and the VM with half a wor
d. |
| 282 expect(log.result()).toEqual('onTurnStart(begin); onTurnStart(scheduleFutu
re); onTurnStart(end); run start; run end; onTurnStart(executeFuture); future th
en; future foo; future bar; onTurnDone(begin); onTurnDone(scheduleFuture); onTur
nDone(end); onTurnStart(begin); onTurnStart(end); onTurnDone(executeFuture); onT
urnDone(begin); onTurnDone(end)'); | 360 }); |
| 283 })); | 361 }); |
| 284 | |
| 285 | |
| 286 it('should call onTurnStart and onTurnDone before and after each turn, resp
ectively', async((Logger log) { | |
| 287 Completer a, b; | |
| 288 zone.run(() { | |
| 289 a = new Completer(); | |
| 290 b = new Completer(); | |
| 291 a.future.then((_) => log('a then')); | |
| 292 b.future.then((_) => log('b then')); | |
| 293 log('run start'); | |
| 294 }); | |
| 295 microLeap(); | |
| 296 zone.run(() { | |
| 297 a.complete(null); | |
| 298 }); | |
| 299 microLeap(); | |
| 300 zone.run(() { | |
| 301 b.complete(null); | |
| 302 }); | |
| 303 microLeap(); | |
| 304 | |
| 305 expect(log.result()).toEqual('onTurnStart; run start; onTurnDone; onTurnSt
art; a then; onTurnDone; onTurnStart; b then; onTurnDone'); | |
| 306 })); | |
| 307 | |
| 308 | |
| 309 it('should call onTurnStart and onTurnDone before and after (respectively) a
ll turns in a chain', async((Logger log) { | |
| 310 zone.run(() { | |
| 311 log('run start'); | |
| 312 scheduleMicrotask(() { | |
| 313 log('async1'); | |
| 314 scheduleMicrotask(() { | |
| 315 log('async2'); | |
| 316 }); | |
| 317 }); | |
| 318 log('run end'); | |
| 319 }); | |
| 320 microLeap(); | |
| 321 | |
| 322 expect(log.result()).toEqual('onTurnStart; run start; run end; async1; asy
nc2; onTurnDone'); | |
| 323 })); | |
| 324 | |
| 325 it('should call onTurnStart and onTurnDone for futures created outside of ru
n body', async((Logger log) { | |
| 326 var future = new Future.value(4).then((x) => new Future.value(x)); | |
| 327 zone.run(() { | |
| 328 future.then((_) => log('future then')); | |
| 329 log('zone run'); | |
| 330 }); | |
| 331 microLeap(); | |
| 332 | |
| 333 expect(log.result()).toEqual('onTurnStart; zone run; onTurnDone; onTurnSta
rt; future then; onTurnDone'); | |
| 334 })); | |
| 335 | |
| 336 | |
| 337 it('should call onTurnDone even if there was an exception in body', async((L
ogger log) { | |
| 338 zone.onError = (e, s, l) => log('onError'); | |
| 339 expect(() => zone.run(() { | |
| 340 log('zone run'); | |
| 341 throw 'zoneError'; | |
| 342 })).toThrow('zoneError'); | |
| 343 expect(() => zone.assertInTurn()).toThrow(); | |
| 344 expect(log.result()).toEqual('onTurnStart; zone run; onError; onTurnDone')
; | |
| 345 })); | |
| 346 | |
| 347 it('should call onTurnDone even if there was an exception in onTurnStart', a
sync((Logger log) { | |
| 348 zone.onError = (e, s, l) => log('onError'); | |
| 349 zone.onTurnStart = (){ | |
| 350 log('onTurnStart'); | |
| 351 throw 'zoneError'; | |
| 352 }; | |
| 353 expect(() => zone.run(() { | |
| 354 log('zone run'); | |
| 355 })).toThrow('zoneError'); | |
| 356 expect(() => zone.assertInTurn()).toThrow(); | |
| 357 expect(log.result()).toEqual('onTurnStart; onError; onTurnDone'); | |
| 358 })); | |
| 359 | |
| 360 | |
| 361 it('should call onTurnDone even if there was an exception in scheduleMicrota
sk', async((Logger log) { | |
| 362 zone.onError = (e, s, l) => log('onError'); | |
| 363 zone.run(() { | |
| 364 log('zone run'); | |
| 365 scheduleMicrotask(() { | |
| 366 log('scheduleMicrotask'); | |
| 367 throw new Error(); | |
| 368 }); | |
| 369 }); | |
| 370 | |
| 371 microLeap(); | |
| 372 | |
| 373 expect(() => zone.assertInTurn()).toThrow(); | |
| 374 expect(log.result()).toEqual('onTurnStart; zone run; scheduleMicrotask; on
Error; onTurnDone'); | |
| 375 })); | |
| 376 | |
| 377 it('should support assertInZone', async(() { | |
| 378 var calls = ''; | |
| 379 zone.onTurnStart = () { | |
| 380 zone.assertInZone(); | |
| 381 calls += 'start;'; | |
| 382 }; | |
| 383 zone.onTurnDone = () { | |
| 384 zone.assertInZone(); | |
| 385 calls += 'done;'; | |
| 386 }; | |
| 387 zone.run(() { | |
| 388 zone.assertInZone(); | |
| 389 calls += 'sync;'; | |
| 390 scheduleMicrotask(() { | |
| 391 zone.assertInZone(); | |
| 392 calls += 'async;'; | |
| 393 }); | |
| 394 }); | |
| 395 | |
| 396 microLeap(); | |
| 397 expect(calls).toEqual('start;sync;async;done;'); | |
| 398 })); | |
| 399 | |
| 400 it('should throw outside of the zone', () { | |
| 401 expect(async(() { | |
| 402 zone.assertInZone(); | |
| 403 microLeap(); | |
| 404 })).toThrow(); | |
| 405 }); | |
| 406 | |
| 407 | |
| 408 it('should support assertInTurn', async(() { | |
| 409 var calls = ''; | |
| 410 zone.onTurnStart = () { | |
| 411 zone.assertInTurn(); | |
| 412 calls += 'start;'; | |
| 413 }; | |
| 414 zone.onTurnDone = () { | |
| 415 calls += 'done;'; | |
| 416 zone.assertInTurn(); | |
| 417 }; | |
| 418 zone.run(() { | |
| 419 calls += 'sync;'; | |
| 420 zone.assertInTurn(); | |
| 421 scheduleMicrotask(() { | |
| 422 calls += 'async;'; | |
| 423 zone.assertInTurn(); | |
| 424 }); | |
| 425 }); | |
| 426 | |
| 427 microLeap(); | |
| 428 expect(calls).toEqual('start;sync;async;done;'); | |
| 429 })); | |
| 430 | |
| 431 | |
| 432 it('should assertInTurn outside of the zone', () { | |
| 433 expect(async(() { | |
| 434 zone.assertInTurn(); | |
| 435 microLeap(); | |
| 436 })).toThrow('ssertion'); // Support both dart2js and the VM with half a w
ord. | |
| 437 }); | |
| 438 }); | |
| 439 } | |
| OLD | NEW |