Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 library command_line_config; | |
| 6 | |
| 7 import 'dart:io'; | |
| 8 | |
| 9 import '../../../pkg/unittest/lib/unittest.dart'; | |
| 10 | |
| 11 const _GREEN = '\u001b[32m'; | |
| 12 const _RED = '\u001b[31m'; | |
| 13 const _MAGENTA = '\u001b[35m'; | |
| 14 const _NONE = '\u001b[0m'; | |
| 15 | |
| 16 /// A custom unittest configuration for running the pub tests from the | |
| 17 /// command-line and generating human-friendly output. | |
| 18 class CommandLineConfiguration extends Configuration { | |
| 19 void onInit() { | |
| 20 // Do nothing. Overridden to prevent the base class from printing. | |
| 21 } | |
| 22 | |
| 23 String _padLeft(String string, int length) { | |
|
nweiz
2013/01/18 03:35:06
Style nit: this probably belongs down near _indent
Bob Nystrom
2013/01/18 21:11:32
Done.
| |
| 24 if (string.length >= length) return string; | |
| 25 | |
| 26 var result = new StringBuffer(); | |
| 27 result.add(string); | |
| 28 for (var i = 0; i < length - string.length; i++) { | |
| 29 result.add(' '); | |
| 30 } | |
| 31 | |
| 32 return result.toString(); | |
| 33 } | |
| 34 | |
| 35 void onTestResult(TestCase testCase) { | |
| 36 var result; | |
| 37 switch (testCase.result) { | |
| 38 case PASS: result = '${_GREEN}\u2713${_NONE}'; break; | |
|
nweiz
2013/01/18 03:35:06
It would be nice to have constants for the pass an
Bob Nystrom
2013/01/18 21:11:32
Done.
| |
| 39 case FAIL: result = '${_RED}\u2717${_NONE}'; break; | |
| 40 case ERROR: result = '${_MAGENTA}?${_NONE}'; break; | |
| 41 } | |
| 42 print('$result ${testCase.description}'); | |
| 43 | |
| 44 if (testCase.message != '') { | |
| 45 print(_indent(testCase.message)); | |
| 46 } | |
| 47 | |
| 48 if (testCase.stackTrace != null && testCase.stackTrace != '') { | |
|
nweiz
2013/01/18 03:35:06
It would be nice to short-circuit here rather than
Bob Nystrom
2013/01/18 21:11:32
Done.
| |
| 49 // Clean up the stack trace. | |
| 50 var regex = new RegExp(r'\#\d+\s+(.*) \(file:///([^)]+)\)'); | |
|
nweiz
2013/01/18 03:35:06
I don't think "#" needs to be escaped.
Also, "reg
Bob Nystrom
2013/01/18 21:11:32
Done.
| |
| 51 var stack = []; | |
| 52 for (var line in testCase.stackTrace.split('\n')) { | |
| 53 if (line.trim() == '') continue; | |
| 54 | |
| 55 var match = regex.firstMatch(line); | |
| 56 if (match == null) throw "Couldn't clean up stack trace line '$line'."; | |
|
nweiz
2013/01/18 03:35:06
Throwing here seems like it would be really annoyi
Bob Nystrom
2013/01/18 21:11:32
It's mostly just to get our attention to tweak the
| |
| 57 stack.add([match[2], match[1]]); | |
|
nweiz
2013/01/18 03:35:06
We do have a Pair class...
Bob Nystrom
2013/01/18 21:11:32
Done.
| |
| 58 } | |
| 59 | |
| 60 // Find the common prefixes of the paths. | |
| 61 if (stack.length > 0) { | |
|
nweiz
2013/01/18 03:35:06
Another place it might be nice to short-circuit.
Bob Nystrom
2013/01/18 21:11:32
Done.
| |
| 62 var common = 0; | |
| 63 while (true) { | |
| 64 var matching = true; | |
| 65 // TODO(bob): Handle empty stack. | |
| 66 var c = stack[0][0][common]; | |
|
nweiz
2013/01/18 03:35:06
I like ".first" better than "[0]". Also below.
Bob Nystrom
2013/01/18 21:11:32
Done.
| |
| 67 for (var pair in stack) { | |
| 68 if (pair[0].length <= common || pair[0][common] != c) { | |
| 69 matching = false; | |
| 70 break; | |
| 71 } | |
| 72 } | |
| 73 | |
| 74 if (!matching) break; | |
| 75 common++; | |
| 76 } | |
|
nweiz
2013/01/18 03:35:06
I'd probably factor this out into a "commonPrefix"
Bob Nystrom
2013/01/18 21:11:32
Pulled all of the stack clean up into a separate m
| |
| 77 | |
| 78 // Remove them. | |
| 79 if (common > 0) { | |
| 80 for (var pair in stack) { | |
| 81 pair[0] = pair[0].substring(common); | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 // Figure out the longest path so we know how much to pad. | |
| 86 int longest = 0; | |
| 87 for (var pair in stack) { | |
| 88 if (pair[0].length > longest) longest = pair[0].length; | |
| 89 } | |
|
nweiz
2013/01/18 03:35:06
"stack.map((pair) => pair.first.length).max()" wou
Bob Nystrom
2013/01/18 21:11:32
Done.
| |
| 90 | |
| 91 // Print out the stack trace nicely formatted. | |
| 92 for (var pair in stack) { | |
| 93 print(' ${_padLeft(pair[0], longest)} ${pair[1]}'); | |
| 94 } | |
| 95 } | |
| 96 print(''); | |
| 97 } | |
| 98 | |
| 99 currentTestCase = null; | |
| 100 } | |
| 101 | |
| 102 void onSummary(int passed, int failed, int errors, List<TestCase> results, | |
| 103 String uncaughtError) { | |
| 104 var success = false; | |
| 105 if (uncaughtError != null) { | |
| 106 print('Top-level uncaught error: $uncaughtError'); | |
| 107 } else if (errors != 0) { | |
| 108 print('${_GREEN}$passed${_NONE} passed, ${_RED}$failed${_NONE} failed, ' | |
| 109 '${_MAGENTA}$errors${_NONE} errors.'); | |
| 110 } else if (failed != 0) { | |
| 111 print('${_GREEN}$passed${_NONE} passed, ${_RED}$failed${_NONE} ' | |
| 112 'failed.'); | |
| 113 } else if (passed == 0) { | |
| 114 print('No tests found.'); | |
| 115 } else { | |
| 116 print('All ${_GREEN}$passed${_NONE} tests passed!'); | |
| 117 success = true; | |
| 118 } | |
| 119 } | |
| 120 | |
| 121 void onDone(bool success) { | |
| 122 if (!success) exit(1); | |
| 123 } | |
| 124 | |
| 125 String _indent(String str) { | |
| 126 // TODO(nweiz): Use this simpler code once issue 2980 is fixed. | |
|
nweiz
2013/01/18 03:35:06
That bug has been open for a long time.
Bob Nystrom
2013/01/18 21:11:32
<shrug>
| |
| 127 // return str.replaceAll(new RegExp("^", multiLine: true), " "); | |
| 128 return Strings.join(str.split("\n").mappedBy((line) => " $line"), "\n"); | |
| 129 } | |
| 130 } | |
| OLD | NEW |