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:async'; |
8 | 8 |
9 import '../../backend/live_test.dart'; | 9 import '../../backend/live_test.dart'; |
10 import '../../backend/state.dart'; | 10 import '../../backend/state.dart'; |
(...skipping 14 matching lines...) Expand all Loading... |
25 /// that test files can be run directly. | 25 /// that test files can be run directly. |
26 class NoIoCompactReporter { | 26 class NoIoCompactReporter { |
27 /// The terminal escape for green text, or the empty string if this is Windows | 27 /// The terminal escape for green text, or the empty string if this is Windows |
28 /// or not outputting to a terminal. | 28 /// or not outputting to a terminal. |
29 final String _green; | 29 final String _green; |
30 | 30 |
31 /// The terminal escape for red text, or the empty string if this is Windows | 31 /// The terminal escape for red text, or the empty string if this is Windows |
32 /// or not outputting to a terminal. | 32 /// or not outputting to a terminal. |
33 final String _red; | 33 final String _red; |
34 | 34 |
| 35 /// The terminal escape for yellow text, or the empty string if this is |
| 36 /// Windows or not outputting to a terminal. |
| 37 final String _yellow; |
| 38 |
35 /// The terminal escape for removing test coloring, or the empty string if | 39 /// The terminal escape for removing test coloring, or the empty string if |
36 /// this is Windows or not outputting to a terminal. | 40 /// this is Windows or not outputting to a terminal. |
37 final String _noColor; | 41 final String _noColor; |
38 | 42 |
39 /// The engine used to run the tests. | 43 /// The engine used to run the tests. |
40 final Engine _engine; | 44 final Engine _engine; |
41 | 45 |
42 /// Whether multiple test files are being run. | 46 /// Whether multiple test files are being run. |
43 final bool _multiplePaths; | 47 final bool _multiplePaths; |
44 | 48 |
45 /// Whether tests are being run on multiple platforms. | 49 /// Whether tests are being run on multiple platforms. |
46 final bool _multiplePlatforms; | 50 final bool _multiplePlatforms; |
47 | 51 |
48 /// A stopwatch that tracks the duration of the full run. | 52 /// A stopwatch that tracks the duration of the full run. |
49 final _stopwatch = new Stopwatch(); | 53 final _stopwatch = new Stopwatch(); |
50 | 54 |
51 /// The set of tests that have completed and been marked as passing. | 55 /// The set of tests that have completed and been marked as passing. |
52 final _passed = new Set<LiveTest>(); | 56 final _passed = new Set<LiveTest>(); |
53 | 57 |
| 58 /// The set of tests that have completed and been marked as skipped. |
| 59 final _skipped = new Set<LiveTest>(); |
| 60 |
54 /// The set of tests that have completed and been marked as failing or error. | 61 /// The set of tests that have completed and been marked as failing or error. |
55 final _failed = new Set<LiveTest>(); | 62 final _failed = new Set<LiveTest>(); |
56 | 63 |
57 /// The size of [_passed] last time a progress notification was printed. | 64 /// The size of [_passed] last time a progress notification was printed. |
58 int _lastProgressPassed; | 65 int _lastProgressPassed; |
59 | 66 |
| 67 /// The size of [_skipped] last time a progress notification was printed. |
| 68 int _lastProgressSkipped; |
| 69 |
60 /// The size of [_failed] last time a progress notification was printed. | 70 /// The size of [_failed] last time a progress notification was printed. |
61 int _lastProgressFailed; | 71 int _lastProgressFailed; |
62 | 72 |
63 /// The message printed for the last progress notification. | 73 /// The message printed for the last progress notification. |
64 String _lastProgressMessage; | 74 String _lastProgressMessage; |
65 | 75 |
66 /// Creates a [NoIoCompactReporter] that will run all tests in [suites]. | 76 /// Creates a [NoIoCompactReporter] that will run all tests in [suites]. |
67 /// | 77 /// |
68 /// If [color] is `true`, this will use terminal colors; if it's `false`, it | 78 /// If [color] is `true`, this will use terminal colors; if it's `false`, it |
69 /// won't. | 79 /// won't. |
70 NoIoCompactReporter(Iterable<Suite> suites, {bool color: true}) | 80 NoIoCompactReporter(Iterable<Suite> suites, {bool color: true}) |
71 : _multiplePaths = suites.map((suite) => suite.path).toSet().length > 1, | 81 : _multiplePaths = suites.map((suite) => suite.path).toSet().length > 1, |
72 _multiplePlatforms = | 82 _multiplePlatforms = |
73 suites.map((suite) => suite.platform).toSet().length > 1, | 83 suites.map((suite) => suite.platform).toSet().length > 1, |
74 _engine = new Engine(suites), | 84 _engine = new Engine(suites), |
75 _green = color ? '\u001b[32m' : '', | 85 _green = color ? '\u001b[32m' : '', |
76 _red = color ? '\u001b[31m' : '', | 86 _red = color ? '\u001b[31m' : '', |
| 87 _yellow = color ? '\u001b[33m' : '', |
77 _noColor = color ? '\u001b[0m' : '' { | 88 _noColor = color ? '\u001b[0m' : '' { |
78 _engine.onTestStarted.listen((liveTest) { | 89 _engine.onTestStarted.listen((liveTest) { |
79 liveTest.onStateChange.listen((state) { | 90 liveTest.onStateChange.listen((state) { |
80 if (state.status != Status.complete) return; | 91 if (state.status != Status.complete) return; |
81 if (state.result == Result.success) { | 92 |
82 _passed.add(liveTest); | 93 if (state.result != Result.success) { |
83 } else { | |
84 _passed.remove(liveTest); | 94 _passed.remove(liveTest); |
85 _failed.add(liveTest); | 95 _failed.add(liveTest); |
| 96 } else if (liveTest.test.metadata.skip) { |
| 97 _skipped.add(liveTest); |
| 98 } else { |
| 99 _passed.add(liveTest); |
86 } | 100 } |
| 101 |
87 _progressLine(_description(liveTest)); | 102 _progressLine(_description(liveTest)); |
| 103 |
| 104 if (liveTest.test.metadata.skip && |
| 105 liveTest.test.metadata.skipReason != null) { |
| 106 print(indent('${_yellow}Skip: ${liveTest.test.metadata.skipReason}' |
| 107 '$_noColor')); |
| 108 } |
88 }); | 109 }); |
89 | 110 |
90 liveTest.onError.listen((error) { | 111 liveTest.onError.listen((error) { |
91 if (liveTest.state.status != Status.complete) return; | 112 if (liveTest.state.status != Status.complete) return; |
92 | 113 |
93 _progressLine(_description(liveTest)); | 114 _progressLine(_description(liveTest)); |
94 print(indent(error.error.toString())); | 115 print(indent(error.error.toString())); |
95 print(indent(terseChain(error.stackTrace).toString())); | 116 print(indent(terseChain(error.stackTrace).toString())); |
96 }); | 117 }); |
97 | 118 |
(...skipping 14 matching lines...) Expand all Loading... |
112 "once."); | 133 "once."); |
113 } | 134 } |
114 | 135 |
115 if (_engine.liveTests.isEmpty) { | 136 if (_engine.liveTests.isEmpty) { |
116 print("No tests ran."); | 137 print("No tests ran."); |
117 return new Future.value(true); | 138 return new Future.value(true); |
118 } | 139 } |
119 | 140 |
120 _stopwatch.start(); | 141 _stopwatch.start(); |
121 return _engine.run().then((success) { | 142 return _engine.run().then((success) { |
122 if (success) { | 143 if (!success) { |
| 144 _progressLine('Some tests failed.', color: _red); |
| 145 } else if (_passed.isEmpty) { |
| 146 _progressLine("All tests skipped."); |
| 147 } else { |
123 _progressLine("All tests passed!"); | 148 _progressLine("All tests passed!"); |
124 } else { | |
125 _progressLine('Some tests failed.', color: _red); | |
126 } | 149 } |
127 | 150 |
128 return success; | 151 return success; |
129 }); | 152 }); |
130 } | 153 } |
131 | 154 |
132 /// Signals that the caller is done with any test output and the reporter | 155 /// Signals that the caller is done with any test output and the reporter |
133 /// should release any resources it has allocated. | 156 /// should release any resources it has allocated. |
134 Future close() => _engine.close(); | 157 Future close() => _engine.close(); |
135 | 158 |
136 /// Prints a line representing the current state of the tests. | 159 /// Prints a line representing the current state of the tests. |
137 /// | 160 /// |
138 /// [message] goes after the progress report, and may be truncated to fit the | 161 /// [message] goes after the progress report, and may be truncated to fit the |
139 /// entire line within [_lineLength]. If [color] is passed, it's used as the | 162 /// entire line within [_lineLength]. If [color] is passed, it's used as the |
140 /// color for [message]. | 163 /// color for [message]. |
141 void _progressLine(String message, {String color}) { | 164 void _progressLine(String message, {String color}) { |
142 // Print nothing if nothing has changed since the last progress line. | 165 // Print nothing if nothing has changed since the last progress line. |
143 if (_passed.length == _lastProgressPassed && | 166 if (_passed.length == _lastProgressPassed && |
| 167 _skipped.length == _lastProgressSkipped && |
144 _failed.length == _lastProgressFailed && | 168 _failed.length == _lastProgressFailed && |
145 message == _lastProgressMessage) { | 169 message == _lastProgressMessage) { |
146 return; | 170 return; |
147 } | 171 } |
148 | 172 |
149 _lastProgressPassed = _passed.length; | 173 _lastProgressPassed = _passed.length; |
| 174 _lastProgressSkipped = _skipped.length; |
150 _lastProgressFailed = _failed.length; | 175 _lastProgressFailed = _failed.length; |
151 _lastProgressMessage = message; | 176 _lastProgressMessage = message; |
152 | 177 |
153 if (color == null) color = ''; | 178 if (color == null) color = ''; |
154 var duration = _stopwatch.elapsed; | 179 var duration = _stopwatch.elapsed; |
155 var buffer = new StringBuffer(); | 180 var buffer = new StringBuffer(); |
156 | 181 |
157 // \r moves back to the beginning of the current line. | 182 // \r moves back to the beginning of the current line. |
158 buffer.write('\r${_timeString(duration)} '); | 183 buffer.write('\r${_timeString(duration)} '); |
159 buffer.write(_green); | 184 buffer.write(_green); |
160 buffer.write('+'); | 185 buffer.write('+'); |
161 buffer.write(_passed.length); | 186 buffer.write(_passed.length); |
162 buffer.write(_noColor); | 187 buffer.write(_noColor); |
163 | 188 |
| 189 if (_skipped.isNotEmpty) { |
| 190 buffer.write(_yellow); |
| 191 buffer.write(' ~'); |
| 192 buffer.write(_skipped.length); |
| 193 buffer.write(_noColor); |
| 194 } |
| 195 |
164 if (_failed.isNotEmpty) { | 196 if (_failed.isNotEmpty) { |
165 buffer.write(_red); | 197 buffer.write(_red); |
166 buffer.write(' -'); | 198 buffer.write(' -'); |
167 buffer.write(_failed.length); | 199 buffer.write(_failed.length); |
168 buffer.write(_noColor); | 200 buffer.write(_noColor); |
169 } | 201 } |
170 | 202 |
171 buffer.write(': '); | 203 buffer.write(': '); |
172 buffer.write(color); | 204 buffer.write(color); |
173 | 205 |
(...skipping 26 matching lines...) Expand all Loading... |
200 name = "${liveTest.suite.path}: $name"; | 232 name = "${liveTest.suite.path}: $name"; |
201 } | 233 } |
202 | 234 |
203 if (_multiplePlatforms && liveTest.suite.platform != null) { | 235 if (_multiplePlatforms && liveTest.suite.platform != null) { |
204 name = "[$liveTest.suite.platform] $name"; | 236 name = "[$liveTest.suite.platform] $name"; |
205 } | 237 } |
206 | 238 |
207 return name; | 239 return name; |
208 } | 240 } |
209 } | 241 } |
OLD | NEW |