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...) 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...) 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 |