Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion modules/angular2/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ dependencies:
logging: '>=0.9.0 <0.11.0'
source_span: '^1.0.0'
stack_trace: '^1.1.1'
quiver: '^0.21.3+1'
dev_dependencies:
guinness: "^0.1.17"
guinness: '^0.1.17'
transformers:
- angular2
- $dart2js:
Expand Down
15 changes: 13 additions & 2 deletions modules/angular2/src/facade/async.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,19 @@ class PromiseWrapper {

static _Completer completer() => new _Completer(new Completer());

static void setTimeout(fn(), int millis) {
new Timer(new Duration(milliseconds: millis), fn);
// TODO(vic): create a TimerWrapper
static Timer setTimeout(fn(), int millis)
=> new Timer(new Duration(milliseconds: millis), fn);
static void clearTimeout(Timer timer) {
timer.cancel();
}

static Timer setInterval(fn(), int millis) {
var interval = new Duration(milliseconds: millis);
return new Timer.periodic(interval, (Timer timer) { fn(); });
}
static void clearInterval(Timer timer) {
timer.cancel();
}

static bool isPromise(maybePromise) {
Expand Down
7 changes: 6 additions & 1 deletion modules/angular2/src/facade/async.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ export class PromiseWrapper {
return {promise: p, resolve: resolve, reject: reject};
}

static setTimeout(fn: Function, millis: int) { global.setTimeout(fn, millis); }
// TODO(vicb): create a TimerWrapper
static setTimeout(fn: Function, millis: int): int { return global.setTimeout(fn, millis); }
static clearTimeout(id: int): void { global.clearTimeout(id); }

static setInterval(fn: Function, millis: int): int { return global.setInterval(fn, millis); }
static clearInterval(id: int): void { global.clearInterval(id); }

static isPromise(maybePromise): boolean { return maybePromise instanceof Promise; }
}
Expand Down
74 changes: 74 additions & 0 deletions modules/angular2/src/test_lib/fake_async.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
library test_lib.fake_async;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use 80-character line length in Dart files


import 'dart:async' show runZoned, ZoneSpecification;
import 'package:quiver/testing/async.dart' as quiver;
import 'package:angular2/src/facade/lang.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.
*
* 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(() {
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();
return Function.apply(fn , args);
} 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);
}

/**
* 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');
}
}
131 changes: 131 additions & 0 deletions modules/angular2/src/test_lib/fake_async.es6
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import {BaseException, global} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection';

var _scheduler;
var _microtasks:List<Function> = [];
var _pendingPeriodicTimers: List<number> = [];
var _pendingTimers: List<number> = [];
var _error = null;

/**
* 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: Function): Function {
// TODO(vicb) re-enable once the jasmine patch from zone.js is applied
//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) {
_scheduler = global.jasmine.DelayedFunctionScheduler();
ListWrapper.clear(_microtasks);
ListWrapper.clear(_pendingPeriodicTimers);
ListWrapper.clear(_pendingTimers);

var res = fakeAsyncZone.run(() => {
var res = fn(...args);
});

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;
}
}

/**
* 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: number = 0): void {
_assertInFakeAsyncZone();
flushMicrotasks();
_scheduler.tick(millis);
}

/**
* Flush any pending microtasks.
*/
export function flushMicrotasks(): void {
_assertInFakeAsyncZone();
while (_microtasks.length > 0) {
var microtask = ListWrapper.removeAt(_microtasks, 0);
microtask();
}
}

function _setTimeout(fn: Function, delay: number, ...args): number {
var cb = _fnAndFlush(fn);
var id = _scheduler.scheduleFunction(cb, delay, args);
ListWrapper.push(_pendingTimers, id);
_scheduler.scheduleFunction(_dequeueTimer(id), delay);
return id;
}

function _clearTimeout(id: number) {
_dequeueTimer(id);
return _scheduler.removeFunctionWithId(id);
}

function _setInterval(fn: Function, interval: number, ...args) {
var cb = _fnAndFlush(fn);
var id = _scheduler.scheduleFunction(cb, interval, args, true);
_pendingPeriodicTimers.push(id);
return id;
}

function _clearInterval(id: number) {
ListWrapper.remove(_pendingPeriodicTimers, id);
return _scheduler.removeFunctionWithId(id);
}

function _fnAndFlush(fn: Function): void {
return () => {
fn.apply(global, arguments);
flushMicrotasks();
}
}

function _scheduleMicrotask(microtask: Function): void {
ListWrapper.push(_microtasks, microtask);
}

function _dequeueTimer(id: number): Function {
return function() {
ListWrapper.remove(_pendingTimers, id);
}
}

function _assertInFakeAsyncZone(): void {
if (!global.zone._inFakeAsyncZone) {
throw new Error('The code should be running in the fakeAsync zone to call this function');
}
}

2 changes: 2 additions & 0 deletions modules/angular2/src/test_lib/lang_utils.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
library test_lib.lang_utils;

import 'dart:mirrors';

Type getTypeOf(instance) => instance.runtimeType;
Expand Down
Loading