| Index: lib/src/runner/reporter/compact.dart
|
| diff --git a/lib/src/runner/reporter/compact.dart b/lib/src/runner/reporter/compact.dart
|
| index 52356969523773954986aaf2b65dd4612235e1ef..9b8b9616a6a5516b791d6030c171c35f4c3ce36b 100644
|
| --- a/lib/src/runner/reporter/compact.dart
|
| +++ b/lib/src/runner/reporter/compact.dart
|
| @@ -15,6 +15,7 @@ import '../../utils.dart' as utils;
|
| import '../engine.dart';
|
| import '../load_exception.dart';
|
| import '../load_suite.dart';
|
| +import '../reporter.dart';
|
|
|
| /// The maximum console line length.
|
| ///
|
| @@ -23,7 +24,7 @@ const _lineLength = 100;
|
|
|
| /// A reporter that prints test results to the console in a single
|
| /// continuously-updating line.
|
| -class CompactReporter {
|
| +class CompactReporter implements Reporter {
|
| /// Whether the reporter should emit terminal color escapes.
|
| final bool _color;
|
|
|
| @@ -66,8 +67,11 @@ class CompactReporter {
|
| /// A stopwatch that tracks the duration of the full run.
|
| final _stopwatch = new Stopwatch();
|
|
|
| - /// A timer that triggers printing updated time information.
|
| - Timer _timer;
|
| + /// Whether we've started [_stopwatch].
|
| + ///
|
| + /// We can't just use `_stopwatch.isRunning` because the stopwatch is stopped
|
| + /// when the reporter is paused.
|
| + var _stopwatchStarted = false;
|
|
|
| /// The size of `_engine.passed` last time a progress notification was
|
| /// printed.
|
| @@ -94,6 +98,12 @@ class CompactReporter {
|
| // Whether a newline has been printed since the last progress line.
|
| var _printedNewline = true;
|
|
|
| + /// Whether the reporter is paused.
|
| + var _paused = false;
|
| +
|
| + /// The set of all subscriptions to various streams.
|
| + final _subscriptions = new Set<StreamSubscription>();
|
| +
|
| /// Watches the tests run by [engine] and prints their results to the
|
| /// terminal.
|
| ///
|
| @@ -102,9 +112,10 @@ class CompactReporter {
|
| /// If [printPath] is `true`, this will print the path name as part of the
|
| /// test description. Likewise, if [printPlatform] is `true`, this will print
|
| /// the platform as part of the test description.
|
| - static void watch(Engine engine, {bool color: true, bool verboseTrace: false,
|
| - bool printPath: true, bool printPlatform: true}) {
|
| - new CompactReporter._(
|
| + static CompactReporter watch(Engine engine, {bool color: true,
|
| + bool verboseTrace: false, bool printPath: true,
|
| + bool printPlatform: true}) {
|
| + return new CompactReporter._(
|
| engine,
|
| color: color,
|
| verboseTrace: verboseTrace,
|
| @@ -124,17 +135,52 @@ class CompactReporter {
|
| _gray = color ? '\u001b[1;30m' : '',
|
| _bold = color ? '\u001b[1m' : '',
|
| _noColor = color ? '\u001b[0m' : '' {
|
| - _engine.onTestStarted.listen(_onTestStarted);
|
| - _engine.success.then(_onDone);
|
| + _subscriptions.add(_engine.onTestStarted.listen(_onTestStarted));
|
| +
|
| + /// Convert the future to a stream so that the subscription can be paused or
|
| + /// canceled.
|
| + _subscriptions.add(_engine.success.asStream().listen(_onDone));
|
| + }
|
| +
|
| + void pause() {
|
| + if (_paused) return;
|
| + _paused = true;
|
| +
|
| + if (!_printedNewline) print('');
|
| + _printedNewline = true;
|
| + _stopwatch.stop();
|
| +
|
| + for (var subscription in _subscriptions) {
|
| + subscription.pause();
|
| + }
|
| + }
|
| +
|
| + void resume() {
|
| + if (!_paused) return;
|
| + _paused = false;
|
| +
|
| + if (_stopwatchStarted) _stopwatch.start();
|
| +
|
| + for (var subscription in _subscriptions) {
|
| + subscription.resume();
|
| + }
|
| + }
|
| +
|
| + void cancel() {
|
| + for (var subscription in _subscriptions) {
|
| + subscription.cancel();
|
| + }
|
| + _subscriptions.clear();
|
| }
|
|
|
| /// A callback called when the engine begins running [liveTest].
|
| void _onTestStarted(LiveTest liveTest) {
|
| - if (_timer == null) {
|
| + if (!_stopwatchStarted) {
|
| + _stopwatchStarted = true;
|
| _stopwatch.start();
|
| /// Keep updating the time even when nothing else is happening.
|
| - _timer = new Timer.periodic(new Duration(seconds: 1),
|
| - (_) => _progressLine(_lastProgressMessage));
|
| + _subscriptions.add(new Stream.periodic(new Duration(seconds: 1))
|
| + .listen((_) => _progressLine(_lastProgressMessage)));
|
| }
|
|
|
| // If this is the first test to start, print a progress line so the user
|
| @@ -144,18 +190,19 @@ class CompactReporter {
|
| _progressLine(_description(liveTest));
|
| }
|
|
|
| - liveTest.onStateChange.listen((state) => _onStateChange(liveTest, state));
|
| + _subscriptions.add(liveTest.onStateChange
|
| + .listen((state) => _onStateChange(liveTest, state)));
|
|
|
| - liveTest.onError.listen((error) =>
|
| - _onError(liveTest, error.error, error.stackTrace));
|
| + _subscriptions.add(liveTest.onError.listen((error) =>
|
| + _onError(liveTest, error.error, error.stackTrace)));
|
|
|
| - liveTest.onPrint.listen((line) {
|
| + _subscriptions.add(liveTest.onPrint.listen((line) {
|
| _progressLine(_description(liveTest), truncate: false);
|
| if (!_printedNewline) print('');
|
| _printedNewline = true;
|
|
|
| print(line);
|
| - });
|
| + }));
|
| }
|
|
|
| /// A callback called when [liveTest]'s state becomes [state].
|
| @@ -210,8 +257,7 @@ class CompactReporter {
|
| /// [success] will be `true` if all tests passed, `false` if some tests
|
| /// failed, and `null` if the engine was closed prematurely.
|
| void _onDone(bool success) {
|
| - if (_timer != null) _timer.cancel();
|
| - _timer = null;
|
| + cancel();
|
| _stopwatch.stop();
|
|
|
| // A null success value indicates that the engine was closed before the
|
|
|