angular-cn/modules/@angular/core/testing/fake_async.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');
}
}