| 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 unittest.runner.reporter.compact; | 5 library unittest.runner.reporter.compact; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io'; | 8 import 'dart:io'; |
| 9 | 9 |
| 10 import '../../backend/live_test.dart'; | 10 import '../../backend/live_test.dart'; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 /// If [color] is `true`, this will use terminal colors; if it's `false`, it | 65 /// If [color] is `true`, this will use terminal colors; if it's `false`, it |
| 66 /// won't. | 66 /// won't. |
| 67 CompactReporter(Iterable<Suite> suites, {bool color: true}) | 67 CompactReporter(Iterable<Suite> suites, {bool color: true}) |
| 68 : _multiplePaths = suites.map((suite) => suite.path).toSet().length > 1, | 68 : _multiplePaths = suites.map((suite) => suite.path).toSet().length > 1, |
| 69 _multiplePlatforms = | 69 _multiplePlatforms = |
| 70 suites.map((suite) => suite.platform).toSet().length > 1, | 70 suites.map((suite) => suite.platform).toSet().length > 1, |
| 71 _engine = new Engine(suites), | 71 _engine = new Engine(suites), |
| 72 _green = color ? '\u001b[32m' : '', | 72 _green = color ? '\u001b[32m' : '', |
| 73 _red = color ? '\u001b[31m' : '', | 73 _red = color ? '\u001b[31m' : '', |
| 74 _noColor = color ? '\u001b[0m' : '' { | 74 _noColor = color ? '\u001b[0m' : '' { |
| 75 // Whether a newline has been printed since the last progress line. |
| 76 var printedNewline = false; |
| 75 _engine.onTestStarted.listen((liveTest) { | 77 _engine.onTestStarted.listen((liveTest) { |
| 76 _progressLine(_description(liveTest)); | 78 _progressLine(_description(liveTest)); |
| 77 liveTest.onStateChange.listen((state) { | 79 liveTest.onStateChange.listen((state) { |
| 78 if (state.status != Status.complete) return; | 80 if (state.status != Status.complete) return; |
| 79 if (state.result == Result.success) { | 81 if (state.result == Result.success) { |
| 80 _passed.add(liveTest); | 82 _passed.add(liveTest); |
| 81 } else { | 83 } else { |
| 82 _passed.remove(liveTest); | 84 _passed.remove(liveTest); |
| 83 _failed.add(liveTest); | 85 _failed.add(liveTest); |
| 84 } | 86 } |
| 85 _progressLine(_description(liveTest)); | 87 _progressLine(_description(liveTest)); |
| 88 printedNewline = false; |
| 86 }); | 89 }); |
| 87 | 90 |
| 88 liveTest.onError.listen((error) { | 91 liveTest.onError.listen((error) { |
| 89 if (liveTest.state.status != Status.complete) return; | 92 if (liveTest.state.status != Status.complete) return; |
| 90 | 93 |
| 91 _progressLine(_description(liveTest)); | 94 _progressLine(_description(liveTest)); |
| 92 print(''); | 95 if (!printedNewline) print(''); |
| 96 printedNewline = true; |
| 97 |
| 93 print(indent(error.error.toString())); | 98 print(indent(error.error.toString())); |
| 94 print(indent(terseChain(error.stackTrace).toString())); | 99 print(indent(terseChain(error.stackTrace).toString())); |
| 95 }); | 100 }); |
| 101 |
| 102 liveTest.onPrint.listen((line) { |
| 103 _progressLine(_description(liveTest)); |
| 104 if (!printedNewline) print(''); |
| 105 printedNewline = true; |
| 106 |
| 107 print(line); |
| 108 }); |
| 96 }); | 109 }); |
| 97 } | 110 } |
| 98 | 111 |
| 99 /// Runs all tests in all provided suites. | 112 /// Runs all tests in all provided suites. |
| 100 /// | 113 /// |
| 101 /// This returns `true` if all tests succeed, and `false` otherwise. It will | 114 /// This returns `true` if all tests succeed, and `false` otherwise. It will |
| 102 /// only return once all tests have finished running. | 115 /// only return once all tests have finished running. |
| 103 Future<bool> run() { | 116 Future<bool> run() { |
| 104 if (_stopwatch.isRunning) { | 117 if (_stopwatch.isRunning) { |
| 105 throw new StateError("CompactReporter.run() may not be called more than " | 118 throw new StateError("CompactReporter.run() may not be called more than " |
| (...skipping 21 matching lines...) Expand all Loading... |
| 127 | 140 |
| 128 /// Signals that the caller is done with any test output and the reporter | 141 /// Signals that the caller is done with any test output and the reporter |
| 129 /// should release any resources it has allocated. | 142 /// should release any resources it has allocated. |
| 130 Future close() => _engine.close(); | 143 Future close() => _engine.close(); |
| 131 | 144 |
| 132 /// Prints a line representing the current state of the tests. | 145 /// Prints a line representing the current state of the tests. |
| 133 /// | 146 /// |
| 134 /// [message] goes after the progress report, and may be truncated to fit the | 147 /// [message] goes after the progress report, and may be truncated to fit the |
| 135 /// entire line within [_lineLength]. If [color] is passed, it's used as the | 148 /// entire line within [_lineLength]. If [color] is passed, it's used as the |
| 136 /// color for [message]. | 149 /// color for [message]. |
| 137 void _progressLine(String message, {String color}) { | 150 bool _progressLine(String message, {String color}) { |
| 138 // Print nothing if nothing has changed since the last progress line. | 151 // Print nothing if nothing has changed since the last progress line. |
| 139 if (_passed.length == _lastProgressPassed && | 152 if (_passed.length == _lastProgressPassed && |
| 140 _failed.length == _lastProgressFailed && | 153 _failed.length == _lastProgressFailed && |
| 141 message == _lastProgressMessage) { | 154 message == _lastProgressMessage) { |
| 142 return; | 155 return false; |
| 143 } | 156 } |
| 144 | 157 |
| 145 _lastProgressPassed = _passed.length; | 158 _lastProgressPassed = _passed.length; |
| 146 _lastProgressFailed = _failed.length; | 159 _lastProgressFailed = _failed.length; |
| 147 _lastProgressMessage = message; | 160 _lastProgressMessage = message; |
| 148 | 161 |
| 149 if (color == null) color = ''; | 162 if (color == null) color = ''; |
| 150 var duration = _stopwatch.elapsed; | 163 var duration = _stopwatch.elapsed; |
| 151 var buffer = new StringBuffer(); | 164 var buffer = new StringBuffer(); |
| 152 | 165 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 173 var nonVisible = 1 + _green.length + _noColor.length + color.length + | 186 var nonVisible = 1 + _green.length + _noColor.length + color.length + |
| 174 (_failed.isEmpty ? 0 : _red.length + _noColor.length); | 187 (_failed.isEmpty ? 0 : _red.length + _noColor.length); |
| 175 var length = buffer.length - nonVisible; | 188 var length = buffer.length - nonVisible; |
| 176 buffer.write(truncate(message, _lineLength - length)); | 189 buffer.write(truncate(message, _lineLength - length)); |
| 177 buffer.write(_noColor); | 190 buffer.write(_noColor); |
| 178 | 191 |
| 179 // Pad the rest of the line so that it looks erased. | 192 // Pad the rest of the line so that it looks erased. |
| 180 length = buffer.length - nonVisible - _noColor.length; | 193 length = buffer.length - nonVisible - _noColor.length; |
| 181 buffer.write(' ' * (_lineLength - length)); | 194 buffer.write(' ' * (_lineLength - length)); |
| 182 stdout.write(buffer.toString()); | 195 stdout.write(buffer.toString()); |
| 196 return true; |
| 183 } | 197 } |
| 184 | 198 |
| 185 /// Returns a representation of [duration] as `MM:SS`. | 199 /// Returns a representation of [duration] as `MM:SS`. |
| 186 String _timeString(Duration duration) { | 200 String _timeString(Duration duration) { |
| 187 return "${duration.inMinutes.toString().padLeft(2, '0')}:" | 201 return "${duration.inMinutes.toString().padLeft(2, '0')}:" |
| 188 "${(duration.inSeconds % 60).toString().padLeft(2, '0')}"; | 202 "${(duration.inSeconds % 60).toString().padLeft(2, '0')}"; |
| 189 } | 203 } |
| 190 | 204 |
| 191 /// Returns a description of [liveTest]. | 205 /// Returns a description of [liveTest]. |
| 192 /// | 206 /// |
| 193 /// This differs from the test's own description in that it may also include | 207 /// This differs from the test's own description in that it may also include |
| 194 /// the suite's name. | 208 /// the suite's name. |
| 195 String _description(LiveTest liveTest) { | 209 String _description(LiveTest liveTest) { |
| 196 var name = liveTest.test.name; | 210 var name = liveTest.test.name; |
| 197 | 211 |
| 198 if (_multiplePaths && liveTest.suite.path != null) { | 212 if (_multiplePaths && liveTest.suite.path != null) { |
| 199 name = "${liveTest.suite.path}: $name"; | 213 name = "${liveTest.suite.path}: $name"; |
| 200 } | 214 } |
| 201 | 215 |
| 202 if (_multiplePlatforms && liveTest.suite.platform != null) { | 216 if (_multiplePlatforms && liveTest.suite.platform != null) { |
| 203 name = "[${liveTest.suite.platform}] $name"; | 217 name = "[${liveTest.suite.platform}] $name"; |
| 204 } | 218 } |
| 205 | 219 |
| 206 return name; | 220 return name; |
| 207 } | 221 } |
| 208 } | 222 } |
| OLD | NEW |