Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(105)

Unified Diff: third_party/pkg/angular/lib/mock/zone.dart

Issue 124053002: Adding Angular and dependent packages for testing (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/pkg/angular/lib/mock/zone.dart
diff --git a/third_party/pkg/angular/lib/mock/zone.dart b/third_party/pkg/angular/lib/mock/zone.dart
new file mode 100644
index 0000000000000000000000000000000000000000..8e3fb22726779e4282f03dd7d7183a01b7a55493
--- /dev/null
+++ b/third_party/pkg/angular/lib/mock/zone.dart
@@ -0,0 +1,213 @@
+library angular.mock_zone;
+
+import 'dart:async' as dart_async;
+
+List<Function> _asyncQueue = [];
+List<_TimerSpec> _timerQueue = [];
+List _asyncErrors = [];
+bool _noMoreAsync = false;
+
+/**
+ * Runs any queued up async calls and any async calls queued with
+ * running microLeap. Example:
+ *
+ * it('should run async code', async(() {
+ * var thenRan = false;
+ * new Future.value('s').then((_) { thenRan = true; });
+ * expect(thenRan).toBe(false);
+ * microLeap();
+ * expect(thenRan).toBe(true);
+ * }));
+ *
+ * it('should run chained thens', async(() {
+ * var log = [];
+ * new Future.value('s')
+ * .then((_) { log.add('firstThen'); })
+ * .then((_) { log.add('2ndThen'); });
+ * expect(log.join(' ')).toEqual('');
+ * microLeap();
+ * expect(log.join(' ')).toEqual('firstThen 2ndThen');
+ * }));
+ *
+ */
+microLeap() {
+ while (!_asyncQueue.isEmpty) {
+ // copy the queue as it may change.
+ var toRun = new List.from(_asyncQueue);
+ _asyncQueue = [];
+ // TODO: Support the case where multiple exceptions are thrown.
+ // e.g. with a throwNextException() method.
+ assert(_asyncErrors.isEmpty);
+ toRun.forEach((fn) => fn());
+ if (!_asyncErrors.isEmpty) {
+ var e = _asyncErrors.removeAt(0);
+ throw ['Async error', e[0], e[1]];
+ }
+ }
+}
+
+/**
+ * Simulates a clock tick by running any scheduled timers. Can only be used
+ * in [async] tests.Clock tick will call [microLeap] to process the microtask
+ * queue before each timer callback.
+ *
+ * Note: microtasks scheduled form the last timer are not going to be processed.
+ *
+ * Example:
+ *
+ * it('should run queued timer after sufficient clock ticks', async(() {
+ * bool timerRan = false;
+ * new Timer(new Duration(milliseconds: 10), () => timerRan = true);
+ *
+ * clockTick(milliseconds: 9);
+ * expect(timerRan).toBeFalsy();
+ * clockTick(milliseconds: 1);
+ * expect(timerRan).toBeTruthy();
+ * }));
+ *
+ * it('should run periodic timer', async(() {
+ * int timerRan = 0;
+ * new Timer.periodic(new Duration(milliseconds: 10), (_) => timerRan++);
+ *
+ * clockTick(milliseconds: 9);
+ * expect(timerRan).toBe(0);
+ * clockTick(milliseconds: 1);
+ * expect(timerRan).toBe(1);
+ * clockTick(milliseconds: 30);
+ * expect(timerRan).toBe(4);
+ * }));
+ */
+clockTick({int days: 0,
+ int hours: 0,
+ int minutes: 0,
+ int seconds: 0,
+ int milliseconds: 0,
+ int microseconds: 0}) {
+ var tickDuration = new Duration(days: days, hours: hours, minutes: minutes,
+ seconds: seconds, milliseconds: milliseconds, microseconds: microseconds);
+
+ var queue = _timerQueue;
+ var remainingTimers = [];
+ _timerQueue = [];
+ queue.forEach((_TimerSpec spec) {
+ if (!spec.isActive) return; // Skip over inactive timers.
+ if (spec.periodic) {
+ // We always add back the periodic timer unless it's cancelled.
+ remainingTimers.add(spec);
+
+ // Ignore ZERO duration ticks for periodic timers.
+ if (tickDuration == Duration.ZERO) return;
+
+ spec.elapsed += tickDuration;
+ // Run the timer as many times as the timer priod fits into the tick.
+ while (spec.elapsed >= spec.duration) {
+ spec.elapsed -= spec.duration;
+ microLeap();
+ spec.fn(spec);
+ }
+ } else {
+ spec.duration -= tickDuration;
+ if (spec.duration <= Duration.ZERO) {
+ microLeap();
+ spec.fn();
+ } else {
+ remainingTimers.add(spec);
+ }
+ }
+ });
+ // Remaining timers should come before anything else scheduled after them.
+ _timerQueue.insertAll(0, remainingTimers);
+}
+
+/**
+* Causes scheduleMicrotask calls to throw exceptions.
+*
+* This function is useful while debugging async tests: the exception
+* is thrown from the scheduleMicrotask call-site instead later in the test.
+*/
+noMoreAsync() {
+ _noMoreAsync = true;
+}
+
+/**
+ * Captures all scheduleMicrotask calls inside of a function.
+ *
+ * Typically used within a test:
+ *
+ * it('should be async', async(() {
+ * ...
+ * }));
+ */
+async(Function fn) =>
+ () {
+ _noMoreAsync = false;
+ _asyncErrors = [];
+ _timerQueue = [];
+ var zoneSpec = new dart_async.ZoneSpecification(
+ scheduleMicrotask: (_, __, ___, asyncFn) {
+ if (_noMoreAsync) {
+ throw ['scheduleMicrotask called after noMoreAsync()'];
+ } else {
+ _asyncQueue.add(asyncFn);
+ }
+ },
+ createTimer: (_, __, ____, Duration duration, void f()) =>
+ _createTimer(f, duration, false),
+ createPeriodicTimer:
+ (_, __, ___, Duration period, void f(dart_async.Timer timer)) =>
+ _createTimer(f, period, true),
+ handleUncaughtError: (_, __, ___, e, s) => _asyncErrors.add([e, s])
+ );
+ dart_async.runZoned(() {
+ fn();
+ microLeap();
+ }, zoneSpecification: zoneSpec);
+
+ _asyncErrors.forEach((e) {
+ throw "During runZoned: ${e[0]}. Stack:\n${e[1]}";
+ });
+
+ if (!_timerQueue.isEmpty && _timerQueue.any((_TimerSpec spec) => spec.isActive)) {
+ throw ["${_timerQueue.where((_TimerSpec spec) => spec.isActive).length} "
+ "active timer(s) are still in the queue."];
+ }
+};
+
+_createTimer(Function fn, Duration duration, bool periodic) {
+ var timer = new _TimerSpec(fn, duration, periodic);
+ _timerQueue.add(timer);
+ return timer;
+}
+
+/**
+ * Enforces synchronous code. Any calls to scheduleMicrotask inside of 'sync'
+ * will throw an exception.
+ */
+sync(Function fn) => () {
+ dart_async.runZoned(fn, zoneSpecification: new dart_async.ZoneSpecification(
+ scheduleMicrotask: (_, __, ___, asyncFn) {
+ throw ['scheduleMicrotask called from sync function.'];
+ },
+ createTimer: (_, __, ____, Duration duration, void f()) {
+ throw ['Timer created from sync function.'];
+ },
+ createPeriodicTimer:
+ (_, __, ___, Duration period, void f(dart_async.Timer timer)) {
+ throw ['periodic Timer created from sync function.'];
+ }
+ ));
+};
+
+class _TimerSpec implements dart_async.Timer {
+ Function fn;
+ Duration duration;
+ Duration elapsed = Duration.ZERO;
+ bool periodic;
+ bool isActive = true;
+
+ _TimerSpec(this.fn, this.duration, this.periodic);
+
+ void cancel() {
+ isActive = false;
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698