| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library test.runner.reporter.no_io_compact; | 5 library test.runner.reporter.no_io_compact; |
| 6 | 6 |
| 7 import 'dart:async'; |
| 7 import 'dart:isolate'; | 8 import 'dart:isolate'; |
| 8 | 9 |
| 9 import '../../backend/live_test.dart'; | 10 import '../../backend/live_test.dart'; |
| 10 import '../../backend/state.dart'; | 11 import '../../backend/state.dart'; |
| 11 import '../../utils.dart'; | 12 import '../../utils.dart'; |
| 12 import '../engine.dart'; | 13 import '../engine.dart'; |
| 13 import '../load_exception.dart'; | 14 import '../load_exception.dart'; |
| 14 import '../load_suite.dart'; | 15 import '../load_suite.dart'; |
| 16 import '../reporter.dart'; |
| 15 | 17 |
| 16 /// The maximum console line length. | 18 /// The maximum console line length. |
| 17 /// | 19 /// |
| 18 /// Lines longer than this will be cropped. | 20 /// Lines longer than this will be cropped. |
| 19 const _lineLength = 100; | 21 const _lineLength = 100; |
| 20 | 22 |
| 21 /// A reporter that prints each test on its own line. | 23 /// A reporter that prints each test on its own line. |
| 22 /// | 24 /// |
| 23 /// This is currently used in place of [CompactReporter] by `lib/test.dart`, | 25 /// This is currently used in place of [CompactReporter] by `lib/test.dart`, |
| 24 /// which can't transitively import `dart:io` but still needs access to a runner | 26 /// which can't transitively import `dart:io` but still needs access to a runner |
| 25 /// so that test files can be run directly. This means that until issue 6943 is | 27 /// so that test files can be run directly. This means that until issue 6943 is |
| 26 /// fixed, this must not import `dart:io`. | 28 /// fixed, this must not import `dart:io`. |
| 27 class ExpandedReporter { | 29 class ExpandedReporter implements Reporter { |
| 28 /// Whether the reporter should emit terminal color escapes. | 30 /// Whether the reporter should emit terminal color escapes. |
| 29 final bool _color; | 31 final bool _color; |
| 30 | 32 |
| 31 /// The terminal escape for green text, or the empty string if this is Windows | 33 /// The terminal escape for green text, or the empty string if this is Windows |
| 32 /// or not outputting to a terminal. | 34 /// or not outputting to a terminal. |
| 33 final String _green; | 35 final String _green; |
| 34 | 36 |
| 35 /// The terminal escape for red text, or the empty string if this is Windows | 37 /// The terminal escape for red text, or the empty string if this is Windows |
| 36 /// or not outputting to a terminal. | 38 /// or not outputting to a terminal. |
| 37 final String _red; | 39 final String _red; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 60 | 62 |
| 61 /// Whether the path to each test's suite should be printed. | 63 /// Whether the path to each test's suite should be printed. |
| 62 final bool _printPath; | 64 final bool _printPath; |
| 63 | 65 |
| 64 /// Whether the platform each test is running on should be printed. | 66 /// Whether the platform each test is running on should be printed. |
| 65 final bool _printPlatform; | 67 final bool _printPlatform; |
| 66 | 68 |
| 67 /// A stopwatch that tracks the duration of the full run. | 69 /// A stopwatch that tracks the duration of the full run. |
| 68 final _stopwatch = new Stopwatch(); | 70 final _stopwatch = new Stopwatch(); |
| 69 | 71 |
| 72 /// Whether we've started [_stopwatch]. |
| 73 /// |
| 74 /// We can't just use `_stopwatch.isRunning` because the stopwatch is stopped |
| 75 /// when the reporter is paused. |
| 76 var _stopwatchStarted = false; |
| 77 |
| 70 /// The size of `_engine.passed` last time a progress notification was | 78 /// The size of `_engine.passed` last time a progress notification was |
| 71 /// printed. | 79 /// printed. |
| 72 int _lastProgressPassed; | 80 int _lastProgressPassed; |
| 73 | 81 |
| 74 /// The size of `_engine.skipped` last time a progress notification was | 82 /// The size of `_engine.skipped` last time a progress notification was |
| 75 /// printed. | 83 /// printed. |
| 76 int _lastProgressSkipped; | 84 int _lastProgressSkipped; |
| 77 | 85 |
| 78 /// The size of `_engine.failed` last time a progress notification was | 86 /// The size of `_engine.failed` last time a progress notification was |
| 79 /// printed. | 87 /// printed. |
| 80 int _lastProgressFailed; | 88 int _lastProgressFailed; |
| 81 | 89 |
| 82 /// The message printed for the last progress notification. | 90 /// The message printed for the last progress notification. |
| 83 String _lastProgressMessage; | 91 String _lastProgressMessage; |
| 84 | 92 |
| 93 /// Whether the reporter is paused. |
| 94 var _paused = false; |
| 95 |
| 96 /// The set of all subscriptions to various streams. |
| 97 final _subscriptions = new Set<StreamSubscription>(); |
| 98 |
| 85 /// Watches the tests run by [engine] and prints their results to the | 99 /// Watches the tests run by [engine] and prints their results to the |
| 86 /// terminal. | 100 /// terminal. |
| 87 /// | 101 /// |
| 88 /// If [color] is `true`, this will use terminal colors; if it's `false`, it | 102 /// If [color] is `true`, this will use terminal colors; if it's `false`, it |
| 89 /// won't. If [verboseTrace] is `true`, this will print core library frames. | 103 /// won't. If [verboseTrace] is `true`, this will print core library frames. |
| 90 /// If [printPath] is `true`, this will print the path name as part of the | 104 /// If [printPath] is `true`, this will print the path name as part of the |
| 91 /// test description. Likewise, if [printPlatform] is `true`, this will print | 105 /// test description. Likewise, if [printPlatform] is `true`, this will print |
| 92 /// the platform as part of the test description. | 106 /// the platform as part of the test description. |
| 93 static void watch(Engine engine, {bool color: true, bool verboseTrace: false, | 107 static ExpandedReporter watch(Engine engine, {bool color: true, |
| 94 bool printPath: true, bool printPlatform: true}) { | 108 bool verboseTrace: false, bool printPath: true, |
| 95 new ExpandedReporter._( | 109 bool printPlatform: true}) { |
| 110 return new ExpandedReporter._( |
| 96 engine, | 111 engine, |
| 97 color: color, | 112 color: color, |
| 98 verboseTrace: verboseTrace, | 113 verboseTrace: verboseTrace, |
| 99 printPath: printPath, | 114 printPath: printPath, |
| 100 printPlatform: printPlatform); | 115 printPlatform: printPlatform); |
| 101 } | 116 } |
| 102 | 117 |
| 103 ExpandedReporter._(this._engine, {bool color: true, bool verboseTrace: false, | 118 ExpandedReporter._(this._engine, {bool color: true, bool verboseTrace: false, |
| 104 bool printPath: true, bool printPlatform: true}) | 119 bool printPath: true, bool printPlatform: true}) |
| 105 : _verboseTrace = verboseTrace, | 120 : _verboseTrace = verboseTrace, |
| 106 _printPath = printPath, | 121 _printPath = printPath, |
| 107 _printPlatform = printPlatform, | 122 _printPlatform = printPlatform, |
| 108 _color = color, | 123 _color = color, |
| 109 _green = color ? '\u001b[32m' : '', | 124 _green = color ? '\u001b[32m' : '', |
| 110 _red = color ? '\u001b[31m' : '', | 125 _red = color ? '\u001b[31m' : '', |
| 111 _yellow = color ? '\u001b[33m' : '', | 126 _yellow = color ? '\u001b[33m' : '', |
| 112 _gray = color ? '\u001b[1;30m' : '', | 127 _gray = color ? '\u001b[1;30m' : '', |
| 113 _bold = color ? '\u001b[1m' : '', | 128 _bold = color ? '\u001b[1m' : '', |
| 114 _noColor = color ? '\u001b[0m' : '' { | 129 _noColor = color ? '\u001b[0m' : '' { |
| 115 _engine.onTestStarted.listen(_onTestStarted); | 130 _subscriptions.add(_engine.onTestStarted.listen(_onTestStarted)); |
| 116 _engine.success.then(_onDone); | 131 |
| 132 /// Convert the future to a stream so that the subscription can be paused or |
| 133 /// canceled. |
| 134 _subscriptions.add(_engine.success.asStream().listen(_onDone)); |
| 135 } |
| 136 |
| 137 void pause() { |
| 138 if (_paused) return; |
| 139 _paused = true; |
| 140 |
| 141 _stopwatch.stop(); |
| 142 |
| 143 for (var subscription in _subscriptions) { |
| 144 subscription.pause(); |
| 145 } |
| 146 } |
| 147 |
| 148 void resume() { |
| 149 if (!_paused) return; |
| 150 if (_stopwatchStarted) _stopwatch.start(); |
| 151 |
| 152 for (var subscription in _subscriptions) { |
| 153 subscription.resume(); |
| 154 } |
| 155 } |
| 156 |
| 157 void cancel() { |
| 158 for (var subscription in _subscriptions) { |
| 159 subscription.cancel(); |
| 160 } |
| 161 _subscriptions.clear(); |
| 117 } | 162 } |
| 118 | 163 |
| 119 /// A callback called when the engine begins running [liveTest]. | 164 /// A callback called when the engine begins running [liveTest]. |
| 120 void _onTestStarted(LiveTest liveTest) { | 165 void _onTestStarted(LiveTest liveTest) { |
| 121 if (liveTest.suite is! LoadSuite) { | 166 if (liveTest.suite is! LoadSuite) { |
| 122 if (!_stopwatch.isRunning) _stopwatch.start(); | 167 if (!_stopwatch.isRunning) _stopwatch.start(); |
| 123 | 168 |
| 124 // If this is the first non-load test to start, print a progress line so | 169 // If this is the first non-load test to start, print a progress line so |
| 125 // the user knows what's running. | 170 // the user knows what's running. |
| 126 if (_engine.active.length == 1) _progressLine(_description(liveTest)); | 171 if (_engine.active.length == 1) _progressLine(_description(liveTest)); |
| 127 | 172 |
| 128 // The engine surfaces load tests when there are no other tests running, | 173 // The engine surfaces load tests when there are no other tests running, |
| 129 // but because the expanded reporter's output is always visible, we don't | 174 // but because the expanded reporter's output is always visible, we don't |
| 130 // emit information about them unless they fail. | 175 // emit information about them unless they fail. |
| 131 liveTest.onStateChange.listen((state) => _onStateChange(liveTest, state)); | 176 _subscriptions.add(liveTest.onStateChange |
| 177 .listen((state) => _onStateChange(liveTest, state))); |
| 132 } else if (_engine.active.length == 1 && | 178 } else if (_engine.active.length == 1 && |
| 133 _engine.active.first == liveTest && | 179 _engine.active.first == liveTest && |
| 134 liveTest.test.name.startsWith("compiling ")) { | 180 liveTest.test.name.startsWith("compiling ")) { |
| 135 // Print a progress line for load tests that come from compiling JS, since | 181 // Print a progress line for load tests that come from compiling JS, since |
| 136 // that takes a long time. | 182 // that takes a long time. |
| 137 _progressLine(_description(liveTest)); | 183 _progressLine(_description(liveTest)); |
| 138 } | 184 } |
| 139 | 185 |
| 140 liveTest.onError.listen((error) => | 186 _subscriptions.add(liveTest.onError.listen((error) => |
| 141 _onError(liveTest, error.error, error.stackTrace)); | 187 _onError(liveTest, error.error, error.stackTrace))); |
| 142 | 188 |
| 143 liveTest.onPrint.listen((line) { | 189 _subscriptions.add(liveTest.onPrint.listen((line) { |
| 144 _progressLine(_description(liveTest)); | 190 _progressLine(_description(liveTest)); |
| 145 print(line); | 191 print(line); |
| 146 }); | 192 })); |
| 147 } | 193 } |
| 148 | 194 |
| 149 /// A callback called when [liveTest]'s state becomes [state]. | 195 /// A callback called when [liveTest]'s state becomes [state]. |
| 150 void _onStateChange(LiveTest liveTest, State state) { | 196 void _onStateChange(LiveTest liveTest, State state) { |
| 151 if (state.status != Status.complete) return; | 197 if (state.status != Status.complete) return; |
| 152 | 198 |
| 153 if (liveTest.test.metadata.skip && | 199 if (liveTest.test.metadata.skip && |
| 154 liveTest.test.metadata.skipReason != null) { | 200 liveTest.test.metadata.skipReason != null) { |
| 155 _progressLine(_description(liveTest)); | 201 _progressLine(_description(liveTest)); |
| 156 print(indent('${_yellow}Skip: ${liveTest.test.metadata.skipReason}' | 202 print(indent('${_yellow}Skip: ${liveTest.test.metadata.skipReason}' |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 | 323 |
| 278 if (_printPlatform && liveTest.suite.platform != null) { | 324 if (_printPlatform && liveTest.suite.platform != null) { |
| 279 name = "[${liveTest.suite.platform.name}] $name"; | 325 name = "[${liveTest.suite.platform.name}] $name"; |
| 280 } | 326 } |
| 281 | 327 |
| 282 if (liveTest.suite is LoadSuite) name = "$_bold$_gray$name$_noColor"; | 328 if (liveTest.suite is LoadSuite) name = "$_bold$_gray$name$_noColor"; |
| 283 | 329 |
| 284 return name; | 330 return name; |
| 285 } | 331 } |
| 286 } | 332 } |
| OLD | NEW |