angular2
Version:
Angular 2 - a web framework for modern web apps
117 lines • 14.8 kB
JavaScript
import { global } from 'angular2/src/facade/lang';
import { BaseException } from 'angular2/src/facade/exceptions';
import { ListWrapper } from 'angular2/src/facade/collection';
var _scheduler;
var _microtasks = [];
var _pendingPeriodicTimers = [];
var _pendingTimers = [];
/**
* Wraps a function 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.
*
* @param fn
* @returns {Function} The function wrapped to be executed in the fakeAsync zone
*/
export function fakeAsync(fn) {
if (global.zone._inFakeAsyncZone) {
throw new Error('fakeAsync() calls can not be nested');
}
var fakeAsyncZone = global.zone.fork({
setTimeout: _setTimeout,
clearTimeout: _clearTimeout,
setInterval: _setInterval,
clearInterval: _clearInterval,
scheduleMicrotask: _scheduleMicrotask,
_inFakeAsyncZone: true
});
return function (...args) {
// TODO(tbosch): This class should already be part of the jasmine typings but it is not...
_scheduler = new jasmine.DelayedFunctionScheduler();
clearPendingTimers();
let res = fakeAsyncZone.run(() => {
let res = fn(...args);
flushMicrotasks();
return res;
});
if (_pendingPeriodicTimers.length > 0) {
throw new BaseException(`${_pendingPeriodicTimers.length} periodic timer(s) still in the queue.`);
}
if (_pendingTimers.length > 0) {
throw new BaseException(`${_pendingTimers.length} timer(s) still in the queue.`);
}
_scheduler = null;
ListWrapper.clear(_microtasks);
return res;
};
}
// TODO we should fix tick to dequeue the failed timer instead of relying on clearPendingTimers
export function clearPendingTimers() {
ListWrapper.clear(_microtasks);
ListWrapper.clear(_pendingPeriodicTimers);
ListWrapper.clear(_pendingTimers);
}
/**
* Simulates the asynchronous passage of time 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.
*
* @param {number} millis Number of millisecond, defaults to 0
*/
export function tick(millis = 0) {
_assertInFakeAsyncZone();
flushMicrotasks();
_scheduler.tick(millis);
}
/**
* Flush any pending microtasks.
*/
export function flushMicrotasks() {
_assertInFakeAsyncZone();
while (_microtasks.length > 0) {
var microtask = ListWrapper.removeAt(_microtasks, 0);
microtask();
}
}
function _setTimeout(fn, delay, ...args) {
var cb = _fnAndFlush(fn);
var id = _scheduler.scheduleFunction(cb, delay, args);
_pendingTimers.push(id);
_scheduler.scheduleFunction(_dequeueTimer(id), delay);
return id;
}
function _clearTimeout(id) {
_dequeueTimer(id);
return _scheduler.removeFunctionWithId(id);
}
function _setInterval(fn, interval, ...args) {
var cb = _fnAndFlush(fn);
var id = _scheduler.scheduleFunction(cb, interval, args, true);
_pendingPeriodicTimers.push(id);
return id;
}
function _clearInterval(id) {
ListWrapper.remove(_pendingPeriodicTimers, id);
return _scheduler.removeFunctionWithId(id);
}
function _fnAndFlush(fn) {
return (...args) => {
fn.apply(global, args);
flushMicrotasks();
};
}
function _scheduleMicrotask(microtask) {
_microtasks.push(microtask);
}
function _dequeueTimer(id) {
return function () { ListWrapper.remove(_pendingTimers, id); };
}
function _assertInFakeAsyncZone() {
if (!global.zone || !global.zone._inFakeAsyncZone) {
throw new Error('The code should be running in the fakeAsync zone to call this function');
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFrZV9hc3luYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImFuZ3VsYXIyL3NyYy90ZXN0aW5nL2Zha2VfYXN5bmMudHMiXSwibmFtZXMiOlsiZmFrZUFzeW5jIiwiY2xlYXJQZW5kaW5nVGltZXJzIiwidGljayIsImZsdXNoTWljcm90YXNrcyIsIl9zZXRUaW1lb3V0IiwiX2NsZWFyVGltZW91dCIsIl9zZXRJbnRlcnZhbCIsIl9jbGVhckludGVydmFsIiwiX2ZuQW5kRmx1c2giLCJfc2NoZWR1bGVNaWNyb3Rhc2siLCJfZGVxdWV1ZVRpbWVyIiwiX2Fzc2VydEluRmFrZUFzeW5jWm9uZSJdLCJtYXBwaW5ncyI6Ik9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSwwQkFBMEI7T0FDeEMsRUFBQyxhQUFhLEVBQW1CLE1BQU0sZ0NBQWdDO09BQ3ZFLEVBQUMsV0FBVyxFQUFDLE1BQU0sZ0NBQWdDO0FBRzFELElBQUksVUFBVSxDQUFDO0FBQ2YsSUFBSSxXQUFXLEdBQWUsRUFBRSxDQUFDO0FBQ2pDLElBQUksc0JBQXNCLEdBQWEsRUFBRSxDQUFDO0FBQzFDLElBQUksY0FBYyxHQUFhLEVBQUUsQ0FBQztBQU1sQzs7Ozs7Ozs7O0dBU0c7QUFDSCwwQkFBMEIsRUFBWTtJQUNwQ0EsRUFBRUEsQ0FBQ0EsQ0FBaUJBLE1BQU1BLENBQUNBLElBQUtBLENBQUNBLGdCQUFnQkEsQ0FBQ0EsQ0FBQ0EsQ0FBQ0E7UUFDbERBLE1BQU1BLElBQUlBLEtBQUtBLENBQUNBLHFDQUFxQ0EsQ0FBQ0EsQ0FBQ0E7SUFDekRBLENBQUNBO0lBRURBLElBQUlBLGFBQWFBLEdBQWtCQSxNQUFNQSxDQUFDQSxJQUFJQSxDQUFDQSxJQUFJQSxDQUFDQTtRQUNsREEsVUFBVUEsRUFBRUEsV0FBV0E7UUFDdkJBLFlBQVlBLEVBQUVBLGFBQWFBO1FBQzNCQSxXQUFXQSxFQUFFQSxZQUFZQTtRQUN6QkEsYUFBYUEsRUFBRUEsY0FBY0E7UUFDN0JBLGlCQUFpQkEsRUFBRUEsa0JBQWtCQTtR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QUFDQTtRQUNuRUEsTUFBTUEsSUFBSUEsS0FBS0EsQ0FBQ0Esd0VBQXdFQSxDQUFDQSxDQUFDQTtJQUM1RkEsQ0FBQ0E7QUFDSEEsQ0FBQ0EiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge2dsb2JhbH0gZnJvbSAnYW5ndWxhcjIvc3JjL2ZhY2FkZS9sYW5nJztcbmltcG9ydCB7QmFzZUV4Y2VwdGlvbiwgV3JhcHBlZEV4Y2VwdGlvbn0gZnJvbSAnYW5ndWxhcjIvc3JjL2ZhY2FkZS9leGNlcHRpb25zJztcbmltcG9ydCB7TGlzdFdyYXBwZXJ9IGZyb20gJ2FuZ3VsYXIyL3NyYy9mYWNhZGUvY29sbGVjdGlvbic7XG5pbXBvcnQge05nWm9uZVpvbmV9IGZyb20gJ2FuZ3VsYXIyL3NyYy9jb3JlL3pvbmUvbmdfem9uZSc7XG5cbnZhciBfc2NoZWR1bGVyO1xudmFyIF9taWNyb3Rhc2tzOiBGdW5jdGlvbltdID0gW107XG52YXIgX3BlbmRpbmdQZXJpb2RpY1RpbWVyczogbnVtYmVyW10gPSBbXTtcbnZhciBfcGVuZGluZ1RpbWVyczogbnVtYmVyW10gPSBbXTtcblxuaW50ZXJmYWNlIEZha2VBc3luY1pvbmUgZXh0ZW5kcyBOZ1pvbmVab25lIHtcbiAgX2luRmFrZUFzeW5jWm9uZTogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBXcmFwcyBhIGZ1bmN0aW9uIHRvIGJlIGV4ZWN1dGVkIGluIHRoZSBmYWtlQXN5bmMgem9uZTpcbiAqIC0gbWljcm90YXNrcyBhcmUgbWFudWFsbHkgZXhlY3V0ZWQgYnkgY2FsbGluZyBgZmx1c2hNaWNyb3Rhc2tzKClgLFxuICogLSB0aW1lcnMgYXJlIHN5bmNocm9ub3VzLCBgdGljaygpYCBzaW11bGF0ZXMgdGhlIGFzeW5jaHJvbm91cyBwYXNzYWdlIG9mIHRpbWUuXG4gKlxuICogSWYgdGhlcmUgYXJlIGFueSBwZW5kaW5nIHRpbWVycyBhdCB0aGUgZW5kIG9mIHRoZSBmdW5jdGlvbiwgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLlxuICpcbiAqIEBwYXJhbSBmblxuICogQHJldHVybnMge0Z1bmN0aW9ufSBUaGUgZnVuY3Rpb24gd3JhcHBlZCB0byBiZSBleGVjdXRlZCBpbiB0aGUgZmFrZUFzeW5jIHpvbmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZha2VBc3luYyhmbjogRnVuY3Rpb24pOiBGdW5jdGlvbiB7XG4gIGlmICgoPEZha2VBc3luY1pvbmU+Z2xvYmFsLnpvbmUpLl9pbkZha2VBc3luY1pvbmUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2Zha2VBc3luYygpIGNhbGxzIGNhbiBub3QgYmUgbmVzdGVkJyk7XG4gIH1cblxuICB2YXIgZmFrZUFzeW5jWm9uZSA9IDxGYWtlQXN5bmNab25lPmdsb2JhbC56b25lLmZvcmsoe1xuICAgIHNldFRpbWVvdXQ6IF9zZXRUaW1lb3V0LFxuICAgIGNsZWFyVGltZW91dDogX2NsZWFyVGltZW91dCxcbiAgICBzZXRJbnRlcnZhbDogX3NldEludGVydmFsLFxuICAgIGNsZWFySW50ZXJ2YWw6IF9jbGVhckludGVydmFsLFxuICAgIHNjaGVkdWxlTWljcm90YXNrOiBfc2NoZWR1bGVNaWNyb3Rhc2ssXG4gICAgX2luRmFrZUFzeW5jWm9uZTogdHJ1ZVxuICB9KTtcblxuICByZXR1cm4gZnVuY3Rpb24oLi4uYXJncykge1xuICAgIC8vIFRPRE8odGJvc2NoKTogVGhpcyBjbGFzcyBzaG91bGQgYWxyZWFkeSBiZSBwYXJ0IG9mIHRoZSBqYXNtaW5lIHR5cGluZ3MgYnV0IGl0IGlzIG5vdC4uLlxuICAgIF9zY2hlZHVsZXIgPSBuZXcgKDxhbnk+amFzbWluZSkuRGVsYXllZEZ1bmN0aW9uU2NoZWR1bGVyKCk7XG4gICAgY2xlYXJQZW5kaW5nVGltZXJzKCk7XG5cbiAgICBsZXQgcmVzID0gZmFrZUFzeW5jWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgbGV0IHJlcyA9IGZuKC4uLmFyZ3MpO1xuICAgICAgZmx1c2hNaWNyb3Rhc2tzKCk7XG4gICAgICByZXR1cm4gcmVzO1xuICAgIH0pO1xuXG4gICAgaWYgKF9wZW5kaW5nUGVyaW9kaWNUaW1lcnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IEJhc2VFeGNlcHRpb24oXG4gICAgICAgICAgYCR7X3BlbmRpbmdQZXJpb2RpY1RpbWVycy5sZW5ndGh9IHBlcmlvZGljIHRpbWVyKHMpIHN0aWxsIGluIHRoZSBxdWV1ZS5gKTtcbiAgICB9XG5cbiAgICBpZiAoX3BlbmRpbmdUaW1lcnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhyb3cgbmV3IEJhc2VFeGNlcHRpb24oYCR7X3BlbmRpbmdUaW1lcnMubGVuZ3RofSB0aW1lcihzKSBzdGlsbCBpbiB0aGUgcXVldWUuYCk7XG4gICAgfVxuXG4gICAgX3NjaGVkdWxlciA9IG51bGw7XG4gICAgTGlzdFdyYXBwZXIuY2xlYXIoX21pY3JvdGFza3MpO1xuXG4gICAgcmV0dXJuIHJlcztcbiAgfVxufVxuXG4vLyBUT0RPIHdlIHNob3VsZCBmaXggdGljayB0byBkZXF1ZXVlIHRoZSBmYWlsZWQgdGltZXIgaW5zdGVhZCBvZiByZWx5aW5nIG9uIGNsZWFyUGVuZGluZ1RpbWVyc1xuZXhwb3J0IGZ1bmN0aW9uIGNsZWFyUGVuZGluZ1RpbWVycygpOiB2b2lkIHtcbiAgTGlzdFdyYXBwZXIuY2xlYXIoX21pY3JvdGFza3MpO1xuICBMaXN0V3JhcHBlci5jbGVhcihfcGVuZGluZ1BlcmlvZGljVGltZXJzKTtcbiAgTGlzdFdyYXBwZXIuY2xlYXIoX3BlbmRpbmdUaW1lcnMpO1xufVxuXG5cbi8qKlxuICogU2ltdWxhdGVzIHRoZSBhc3luY2hyb25vdXMgcGFzc2FnZSBvZiB0aW1lIGZvciB0aGUgdGltZXJzIGluIHRoZSBmYWtlQXN5bmMgem9uZS5cbiAqXG4gKiBUaGUgbWljcm90YXNrcyBxdWV1ZSBpcyBkcmFpbmVkIGF0IHRoZSB2ZXJ5IHN0YXJ0IG9mIHRoaXMgZnVuY3Rpb24gYW5kIGFmdGVyIGFueSB0aW1lciBjYWxsYmFja1xuICogaGFzIGJlZW4gZXhlY3V0ZWQuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IG1pbGxpcyBOdW1iZXIgb2YgbWlsbGlzZWNvbmQsIGRlZmF1bHRzIHRvIDBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRpY2sobWlsbGlzOiBudW1iZXIgPSAwKTogdm9pZCB7XG4gIF9hc3NlcnRJbkZha2VBc3luY1pvbmUoKTtcbiAgZmx1c2hNaWNyb3Rhc2tzKCk7XG4gIF9zY2hlZHVsZXIudGljayhtaWxsaXMpO1xufVxuXG4vKipcbiAqIEZsdXNoIGFueSBwZW5kaW5nIG1pY3JvdGFza3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbHVzaE1pY3JvdGFza3MoKTogdm9pZCB7XG4gIF9hc3NlcnRJbkZha2VBc3luY1pvbmUoKTtcbiAgd2hpbGUgKF9taWNyb3Rhc2tzLmxlbmd0aCA+IDApIHtcbiAgICB2YXIgbWljcm90YXNrID0gTGlzdFdyYXBwZXIucmVtb3ZlQXQoX21pY3JvdGFza3MsIDApO1xuICAgIG1pY3JvdGFzaygpO1xuICB9XG59XG5cbmZ1bmN0aW9uIF9zZXRUaW1lb3V0KGZuOiBGdW5jdGlvbiwgZGVsYXk6IG51bWJlciwgLi4uYXJncyk6IG51bWJlciB7XG4gIHZhciBjYiA9IF9mbkFuZEZsdXNoKGZuKTtcbiAgdmFyIGlkID0gX3NjaGVkdWxlci5zY2hlZHVsZUZ1bmN0aW9uKGNiLCBkZWxheSwgYXJncyk7XG4gIF9wZW5kaW5nVGltZXJzLnB1c2goaWQpO1xuICBfc2NoZWR1bGVyLnNjaGVkdWxlRnVuY3Rpb24oX2RlcXVldWVUaW1lcihpZCksIGRlbGF5KTtcbiAgcmV0dXJuIGlkO1xufVxuXG5mdW5jdGlvbiBfY2xlYXJUaW1lb3V0KGlkOiBudW1iZXIpIHtcbiAgX2RlcXVldWVUaW1lcihpZCk7XG4gIHJldHVybiBfc2NoZWR1bGVyLnJlbW92ZUZ1bmN0aW9uV2l0aElkKGlkKTtcbn1cblxuZnVuY3Rpb24gX3NldEludGVydmFsKGZuOiBGdW5jdGlvbiwgaW50ZXJ2YWw6IG51bWJlciwgLi4uYXJncykge1xuICB2YXIgY2IgPSBfZm5BbmRGbHVzaChmbik7XG4gIHZhciBpZCA9IF9zY2hlZHVsZXIuc2NoZWR1bGVGdW5jdGlvbihjYiwgaW50ZXJ2YWwsIGFyZ3MsIHRydWUpO1xuICBfcGVuZGluZ1BlcmlvZGljVGltZXJzLnB1c2goaWQpO1xuICByZXR1cm4gaWQ7XG59XG5cbmZ1bmN0aW9uIF9jbGVhckludGVydmFsKGlkOiBudW1iZXIpIHtcbiAgTGlzdFdyYXBwZXIucmVtb3ZlKF9wZW5kaW5nUGVyaW9kaWNUaW1lcnMsIGlkKTtcbiAgcmV0dXJuIF9zY2hlZHVsZXIucmVtb3ZlRnVuY3Rpb25XaXRoSWQoaWQpO1xufVxuXG5mdW5jdGlvbiBfZm5BbmRGbHVzaChmbjogRnVuY3Rpb24pOiBGdW5jdGlvbiB7XG4gIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgIGZuLmFwcGx5KGdsb2JhbCwgYXJncyk7XG4gICAgZmx1c2hNaWNyb3Rhc2tzKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX3NjaGVkdWxlTWljcm90YXNrKG1pY3JvdGFzazogRnVuY3Rpb24pOiB2b2lkIHtcbiAgX21pY3JvdGFza3MucHVzaChtaWNyb3Rhc2spO1xufVxuXG5mdW5jdGlvbiBfZGVxdWV1ZVRpbWVyKGlkOiBudW1iZXIpOiBGdW5jdGlvbiB7XG4gIHJldHVybiBmdW5jdGlvbigpIHsgTGlzdFdyYXBwZXIucmVtb3ZlKF9wZW5kaW5nVGltZXJzLCBpZCk7IH1cbn1cblxuZnVuY3Rpb24gX2Fzc2VydEluRmFrZUFzeW5jWm9uZSgpOiB2b2lkIHtcbiAgaWYgKCFnbG9iYWwuem9uZSB8fCAhKDxGYWtlQXN5bmNab25lPmdsb2JhbC56b25lKS5faW5GYWtlQXN5bmNab25lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgY29kZSBzaG91bGQgYmUgcnVubmluZyBpbiB0aGUgZmFrZUFzeW5jIHpvbmUgdG8gY2FsbCB0aGlzIGZ1bmN0aW9uJyk7XG4gIH1cbn1cbiJdfQ==