| 
									
										
										
										
											2015-10-13 00:29:13 -07:00
										 |  |  | library testing.fake_async; | 
					
						
							| 
									
										
										
										
											2015-05-12 16:28:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import 'dart:async' show runZoned, ZoneSpecification; | 
					
						
							|  |  |  | import 'package:quiver/testing/async.dart' as quiver; | 
					
						
							| 
									
										
										
										
											2015-11-06 17:34:07 -08:00
										 |  |  | import 'package:angular2/src/facade/exceptions.dart' show BaseException; | 
					
						
							| 
									
										
										
										
											2015-05-12 16:28:57 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | const _u = const Object(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | quiver.FakeAsync _fakeAsync = null; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Wraps the [fn] to be executed in the fakeAsync zone: | 
					
						
							|  |  |  |  * - microtasks are manually executed by calling [flushMicrotasks], | 
					
						
							|  |  |  |  * - timers are synchronous, [tick] simulates the asynchronous passage of time. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * If there are any pending timers at the end of the function, an exception | 
					
						
							|  |  |  |  * will be thrown. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2016-04-18 16:04:35 -07:00
										 |  |  |  * Can be used to wrap inject() calls. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2015-05-12 16:28:57 +02:00
										 |  |  |  * Returns a `Function` that wraps [fn]. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2016-04-26 13:06:50 -07:00
										 |  |  | Function fakeAsync(Function fn) { | 
					
						
							| 
									
										
										
										
											2015-05-12 16:28:57 +02:00
										 |  |  |   if (_fakeAsync != null) { | 
					
						
							|  |  |  |     throw 'fakeAsync() calls can not be nested'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-18 16:04:35 -07:00
										 |  |  |   return ([a0 = _u, | 
					
						
							|  |  |  |            a1 = _u, | 
					
						
							|  |  |  |            a2 = _u, | 
					
						
							|  |  |  |            a3 = _u, | 
					
						
							|  |  |  |            a4 = _u, | 
					
						
							|  |  |  |            a5 = _u, | 
					
						
							|  |  |  |            a6 = _u, | 
					
						
							|  |  |  |            a7 = _u, | 
					
						
							|  |  |  |            a8 = _u, | 
					
						
							|  |  |  |            a9 = _u]) { | 
					
						
							| 
									
										
										
										
											2015-05-12 16:28:57 +02:00
										 |  |  |     // runZoned() to install a custom exception handler that re-throws
 | 
					
						
							|  |  |  |     return runZoned(() { | 
					
						
							| 
									
										
										
										
											2015-06-02 19:55:03 +02:00
										 |  |  |       return new quiver.FakeAsync().run((quiver.FakeAsync async) { | 
					
						
							| 
									
										
										
										
											2015-05-12 16:28:57 +02:00
										 |  |  |         try { | 
					
						
							|  |  |  |           _fakeAsync = async; | 
					
						
							| 
									
										
										
										
											2015-08-04 12:05:30 -07:00
										 |  |  |           List args = [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9] | 
					
						
							|  |  |  |               .takeWhile((a) => a != _u) | 
					
						
							|  |  |  |               .toList(); | 
					
						
							| 
									
										
										
										
											2016-04-26 13:06:50 -07:00
										 |  |  |           var res = Function.apply(fn, args); | 
					
						
							| 
									
										
										
										
											2015-06-02 19:55:03 +02:00
										 |  |  |           _fakeAsync.flushMicrotasks(); | 
					
						
							| 
									
										
										
										
											2015-05-29 08:20:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |           if (async.periodicTimerCount > 0) { | 
					
						
							|  |  |  |             throw new BaseException('${async.periodicTimerCount} periodic ' | 
					
						
							|  |  |  |                 'timer(s) still in the queue.'); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (async.nonPeriodicTimerCount > 0) { | 
					
						
							|  |  |  |             throw new BaseException('${async.nonPeriodicTimerCount} timer(s) ' | 
					
						
							|  |  |  |                 'still in the queue.'); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-02 19:55:03 +02:00
										 |  |  |           return res; | 
					
						
							| 
									
										
										
										
											2015-05-12 16:28:57 +02:00
										 |  |  |         } finally { | 
					
						
							|  |  |  |           _fakeAsync = null; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }, | 
					
						
							| 
									
										
										
										
											2015-05-29 10:42:47 -07:00
										 |  |  |         zoneSpecification: new ZoneSpecification( | 
					
						
							|  |  |  |             handleUncaughtError: (self, parent, zone, error, stackTrace) => | 
					
						
							|  |  |  |                 throw error)); | 
					
						
							| 
									
										
										
										
											2015-05-12 16:28:57 +02:00
										 |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Simulates the asynchronous passage of [millis] milliseconds for the timers | 
					
						
							|  |  |  |  * in the fakeAsync zone. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The microtasks queue is drained at the very start of this function and after | 
					
						
							|  |  |  |  * any timer callback has been executed. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void tick([int millis = 0]) { | 
					
						
							|  |  |  |   _assertInFakeAsyncZone(); | 
					
						
							|  |  |  |   var duration = new Duration(milliseconds: millis); | 
					
						
							|  |  |  |   _fakeAsync.elapse(duration); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-07-27 15:47:42 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * This is not needed in Dart. Because quiver correctly removes a timer when | 
					
						
							|  |  |  |  * it throws an exception. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-08-04 12:05:30 -07:00
										 |  |  | void clearPendingTimers() {} | 
					
						
							| 
									
										
										
										
											2015-07-27 15:47:42 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-12 16:28:57 +02:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Flush any pending microtasks. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void flushMicrotasks() { | 
					
						
							|  |  |  |   _assertInFakeAsyncZone(); | 
					
						
							|  |  |  |   _fakeAsync.flushMicrotasks(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void _assertInFakeAsyncZone() { | 
					
						
							|  |  |  |   if (_fakeAsync == null) { | 
					
						
							|  |  |  |     throw new BaseException('The code should be running in the fakeAsync zone ' | 
					
						
							|  |  |  |         'to call this function'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |