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

Unified Diff: quiver/lib/testing/src/async/fake_async.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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
« no previous file with comments | « quiver/lib/testing/src/async/async.dart ('k') | quiver/lib/testing/src/equality/equality.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: quiver/lib/testing/src/async/fake_async.dart
diff --git a/quiver/lib/testing/src/async/fake_async.dart b/quiver/lib/testing/src/async/fake_async.dart
deleted file mode 100644
index eb14769718481cd38685405ce21f0468640ea5bb..0000000000000000000000000000000000000000
--- a/quiver/lib/testing/src/async/fake_async.dart
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 2014 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-part of quiver.testing.async;
-
-/// A mechanism to make time-dependent units testable.
-///
-/// Test code can be passed as a callback to [run], which causes it to be run in
-/// a [Zone] which fakes timer and microtask creation, such that they are run
-/// during calls to [elapse] which simulates the asynchronous passage of time.
-///
-/// The synchronous passage of time (blocking or expensive calls) can also be
-/// simulated using [elapseBlocking].
-///
-/// To allow the unit under test to tell time, it can receive a [Clock] as a
-/// dependency, and default it to [const Clock()] in production, but then use
-/// [clock] in test code.
-///
-/// Example:
-///
-/// test('testedFunc', () {
-/// new FakeAsync().run((async) {
-/// testedFunc(clock: async.getClock(initialTime));
-/// async.elapse(duration);
-/// expect(...)
-/// });
-/// });
-abstract class FakeAsync {
- factory FakeAsync() = _FakeAsync;
-
- FakeAsync._();
-
- /// Returns a fake [Clock] whose time can is elapsed by calls to [elapse] and
- /// [elapseBlocking].
- ///
- /// The returned clock starts at [initialTime], and calls to [elapse] and
- /// [elapseBlocking] advance the clock, even if they occured before the call
- /// to this method.
- ///
- /// The clock can be passed as a dependency to the unit under test.
- Clock getClock(DateTime initialTime);
-
- /// Simulates the asynchronous passage of time.
- ///
- /// **This should only be called from within the zone used by [run].**
- ///
- /// If [duration] is negative, the returned future completes with an
- /// [ArgumentError].
- ///
- /// If a previous call to [elapse] has not yet completed, throws a
- /// [StateError].
- ///
- /// Any Timers created within the zone used by [run] which are to expire
- /// at or before the new time after [duration] has elapsed are run.
- /// The microtask queue is processed surrounding each timer. When a timer is
- /// run, the [clock] will have been advanced by the timer's specified
- /// duration. Calls to [elapseBlocking] from within these timers and
- /// microtasks which cause the [clock] to elapse more than the specified
- /// [duration], can cause more timers to expire and thus be called.
- ///
- /// Once all expired timers are processed, the [clock] is advanced (if
- /// necessary) to the time this method was called + [duration].
- void elapse(Duration duration);
-
- /// Simulates the synchronous passage of time, resulting from blocking or
- /// expensive calls.
- ///
- /// Neither timers nor microtasks are run during this call. Upon return, the
- /// [clock] will have been advanced by [duration].
- ///
- /// If [duration] is negative, throws an [ArgumentError].
- void elapseBlocking(Duration duration);
-
- /// Runs [callback] in a [Zone] with fake timer and microtask scheduling.
- ///
- /// Uses
- /// [ZoneSpecification.createTimer], [ZoneSpecification.createPeriodicTimer],
- /// and [ZoneSpecification.scheduleMicrotask] to store callbacks for later
- /// execution within the zone via calls to [elapse].
- ///
- /// [callback] is called with `this` as argument.
- run(callback(FakeAsync self));
-
- /// Runs all remaining microtasks, including those scheduled as a result of
- /// running them, until there are no more microtasks scheduled.
- ///
- /// Does not run timers.
- void flushMicrotasks();
-
- /// Runs all timers until no timers remain (subject to [flushPeriodicTimers]
- /// option), including those scheduled as a result of running them.
- ///
- /// [timeout] lets you set the maximum amount of time the flushing will take.
- /// Throws a [StateError] if the [timeout] is exceeded. The default timeout
- /// is 1 hour. [timeout] is relative to the elapsed time.
- void flushTimers({Duration timeout: const Duration(hours: 1),
- bool flushPeriodicTimers: true});
-
- /// The number of created periodic timers that have not been canceled.
- int get periodicTimerCount;
-
- /// The number of pending non periodic timers that have not been canceled.
- int get nonPeriodicTimerCount;
-
- /// The number of pending microtasks.
- int get microtaskCount;
-}
-
-class _FakeAsync extends FakeAsync {
- Duration _elapsed = Duration.ZERO;
- Duration _elapsingTo;
- Queue<Function> _microtasks = new Queue();
- Set<_FakeTimer> _timers = new Set<_FakeTimer>();
-
- _FakeAsync() : super._() {
- _elapsed;
- }
-
- @override
- Clock getClock(DateTime initialTime) =>
- new Clock(() => initialTime.add(_elapsed));
-
- @override
- void elapse(Duration duration) {
- if (duration.inMicroseconds < 0) {
- throw new ArgumentError('Cannot call elapse with negative duration');
- }
- if (_elapsingTo != null) {
- throw new StateError('Cannot elapse until previous elapse is complete.');
- }
- _elapsingTo = _elapsed + duration;
- _drainTimersWhile((_FakeTimer next) => next._nextCall <= _elapsingTo);
- _elapseTo(_elapsingTo);
- _elapsingTo = null;
- }
-
- @override
- void elapseBlocking(Duration duration) {
- if (duration.inMicroseconds < 0) {
- throw new ArgumentError('Cannot call elapse with negative duration');
- }
- _elapsed += duration;
- if (_elapsingTo != null && _elapsed > _elapsingTo) {
- _elapsingTo = _elapsed;
- }
- }
-
- @override
- void flushMicrotasks() {
- _drainMicrotasks();
- }
-
- @override
- void flushTimers({Duration timeout: const Duration(hours: 1),
- bool flushPeriodicTimers: true}) {
- final absoluteTimeout = _elapsed + timeout;
- _drainTimersWhile((_FakeTimer timer) {
- if (timer._nextCall > absoluteTimeout) {
- throw new StateError(
- 'Exceeded timeout ${timeout} while flushing timers');
- }
- if (flushPeriodicTimers) {
- return _timers.isNotEmpty;
- } else {
- // translation: keep draining while non-periodic timers exist
- return _timers.any((_FakeTimer timer) => !timer._isPeriodic);
- }
- });
- }
-
- @override
- run(callback(FakeAsync self)) {
- if (_zone == null) {
- _zone = Zone.current.fork(specification: _zoneSpec);
- }
- return _zone.runGuarded(() => callback(this));
- }
- Zone _zone;
-
- @override
- int get periodicTimerCount =>
- _timers.where((_FakeTimer timer) => timer._isPeriodic).length;
-
- @override
- int get nonPeriodicTimerCount =>
- _timers.where((_FakeTimer timer) => !timer._isPeriodic).length;
-
- @override
- int get microtaskCount => _microtasks.length;
-
- ZoneSpecification get _zoneSpec => new ZoneSpecification(
- createTimer: (_, __, ___, Duration duration, Function callback) {
- return _createTimer(duration, callback, false);
- }, createPeriodicTimer: (_, __, ___, Duration duration, Function callback) {
- return _createTimer(duration, callback, true);
- }, scheduleMicrotask: (_, __, ___, Function microtask) {
- _microtasks.add(microtask);
- });
-
- _drainTimersWhile(bool predicate(_FakeTimer)) {
- _drainMicrotasks();
- _FakeTimer next;
- while ((next = _getNextTimer()) != null && predicate(next)) {
- _runTimer(next);
- _drainMicrotasks();
- }
- }
-
- _elapseTo(Duration to) {
- if (to > _elapsed) {
- _elapsed = to;
- }
- }
-
- Timer _createTimer(Duration duration, Function callback, bool isPeriodic) {
- var timer = new _FakeTimer._(duration, callback, isPeriodic, this);
- _timers.add(timer);
- return timer;
- }
-
- _FakeTimer _getNextTimer() {
- return min(_timers,
- (timer1, timer2) => timer1._nextCall.compareTo(timer2._nextCall));
- }
-
- _runTimer(_FakeTimer timer) {
- assert(timer.isActive);
- _elapseTo(timer._nextCall);
- if (timer._isPeriodic) {
- timer._callback(timer);
- timer._nextCall += timer._duration;
- } else {
- timer._callback();
- _timers.remove(timer);
- }
- }
-
- _drainMicrotasks() {
- while (_microtasks.isNotEmpty) {
- _microtasks.removeFirst()();
- }
- }
-
- _hasTimer(_FakeTimer timer) => _timers.contains(timer);
-
- _cancelTimer(_FakeTimer timer) => _timers.remove(timer);
-}
-
-class _FakeTimer implements Timer {
- final Duration _duration;
- final Function _callback;
- final bool _isPeriodic;
- final _FakeAsync _time;
- Duration _nextCall;
-
- // TODO: In browser JavaScript, timers can only run every 4 milliseconds once
- // sufficiently nested:
- // http://www.w3.org/TR/html5/webappapis.html#timer-nesting-level
- // Without some sort of delay this can lead to infinitely looping timers.
- // What do the dart VM and dart2js timers do here?
- static const _minDuration = Duration.ZERO;
-
- _FakeTimer._(Duration duration, this._callback, this._isPeriodic, this._time)
- : _duration = duration < _minDuration ? _minDuration : duration {
- _nextCall = _time._elapsed + _duration;
- }
-
- bool get isActive => _time._hasTimer(this);
-
- cancel() => _time._cancelTimer(this);
-}
« no previous file with comments | « quiver/lib/testing/src/async/async.dart ('k') | quiver/lib/testing/src/equality/equality.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698