104 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| library testing.fake_async;
 | |
| 
 | |
| import 'dart:async' show runZoned, ZoneSpecification;
 | |
| import 'package:quiver/testing/async.dart' as quiver;
 | |
| import 'package:angular2/src/facade/exceptions.dart' show BaseException;
 | |
| 
 | |
| 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.
 | |
|  *
 | |
|  * Can be used to wrap inject() calls.
 | |
|  *
 | |
|  * Returns a `Function` that wraps [fn].
 | |
|  */
 | |
| Function fakeAsync(Function fn) {
 | |
|   if (_fakeAsync != null) {
 | |
|     throw 'fakeAsync() calls can not be nested';
 | |
|   }
 | |
| 
 | |
|   return ([a0 = _u,
 | |
|            a1 = _u,
 | |
|            a2 = _u,
 | |
|            a3 = _u,
 | |
|            a4 = _u,
 | |
|            a5 = _u,
 | |
|            a6 = _u,
 | |
|            a7 = _u,
 | |
|            a8 = _u,
 | |
|            a9 = _u]) {
 | |
|     // runZoned() to install a custom exception handler that re-throws
 | |
|     return runZoned(() {
 | |
|       return new quiver.FakeAsync().run((quiver.FakeAsync async) {
 | |
|         try {
 | |
|           _fakeAsync = async;
 | |
|           List args = [a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]
 | |
|               .takeWhile((a) => a != _u)
 | |
|               .toList();
 | |
|           var res = Function.apply(fn, args);
 | |
|           _fakeAsync.flushMicrotasks();
 | |
| 
 | |
|           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.');
 | |
|           }
 | |
| 
 | |
|           return res;
 | |
|         } finally {
 | |
|           _fakeAsync = null;
 | |
|         }
 | |
|       });
 | |
|     },
 | |
|         zoneSpecification: new ZoneSpecification(
 | |
|             handleUncaughtError: (self, parent, zone, error, stackTrace) =>
 | |
|                 throw error));
 | |
|   };
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * 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);
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * This is not needed in Dart. Because quiver correctly removes a timer when
 | |
|  * it throws an exception.
 | |
|  */
 | |
| void clearPendingTimers() {}
 | |
| 
 | |
| /**
 | |
|  * 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');
 | |
|   }
 | |
| }
 |