OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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 command_line_config; | 5 library command_line_config; |
6 | 6 |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 import 'dart:math' as math; | 8 import 'dart:math' as math; |
9 | 9 |
10 import 'package:pathos/path.dart' as path; | 10 import 'package:pathos/path.dart' as path; |
(...skipping 23 matching lines...) Expand all Loading... |
34 case PASS: result = '$_green$_checkbox$_none'; break; | 34 case PASS: result = '$_green$_checkbox$_none'; break; |
35 case FAIL: result = '$_red$_ballotX$_none'; break; | 35 case FAIL: result = '$_red$_ballotX$_none'; break; |
36 case ERROR: result = '$_magenta?$_none'; break; | 36 case ERROR: result = '$_magenta?$_none'; break; |
37 } | 37 } |
38 print('$result ${testCase.description}'); | 38 print('$result ${testCase.description}'); |
39 | 39 |
40 if (testCase.message != '') { | 40 if (testCase.message != '') { |
41 print(_indent(testCase.message)); | 41 print(_indent(testCase.message)); |
42 } | 42 } |
43 | 43 |
44 if (testCase.stackTrace != null) { | 44 _printStackTrace(testCase.stackTrace); |
45 print(_indent(testCase.stackTrace.toString())); | |
46 } | |
47 | 45 |
48 super.onTestResult(testCase); | 46 super.onTestResult(testCase); |
49 } | 47 } |
50 | 48 |
51 void onSummary(int passed, int failed, int errors, List<TestCase> results, | 49 void onSummary(int passed, int failed, int errors, List<TestCase> results, |
52 String uncaughtError) { | 50 String uncaughtError) { |
53 var success = false; | 51 var success = false; |
54 if (uncaughtError != null) { | 52 if (uncaughtError != null) { |
55 print('Top-level uncaught error: $uncaughtError'); | 53 print('Top-level uncaught error: $uncaughtError'); |
56 } else if (errors != 0) { | 54 } else if (errors != 0) { |
57 print('${_green}$passed${_none} passed, ${_red}$failed${_none} failed, ' | 55 print('${_green}$passed${_none} passed, ${_red}$failed${_none} failed, ' |
58 '${_magenta}$errors${_none} errors.'); | 56 '${_magenta}$errors${_none} errors.'); |
59 } else if (failed != 0) { | 57 } else if (failed != 0) { |
60 print('${_green}$passed${_none} passed, ${_red}$failed${_none} ' | 58 print('${_green}$passed${_none} passed, ${_red}$failed${_none} ' |
61 'failed.'); | 59 'failed.'); |
62 } else if (passed == 0) { | 60 } else if (passed == 0) { |
63 print('No tests found.'); | 61 print('No tests found.'); |
64 } else { | 62 } else { |
65 print('All ${_green}$passed${_none} tests passed!'); | 63 print('All ${_green}$passed${_none} tests passed!'); |
66 success = true; | 64 success = true; |
67 } | 65 } |
68 } | 66 } |
69 | 67 |
70 void onDone(bool success) { | 68 void onDone(bool success) { |
71 if (!success) exit(1); | 69 if (!success) exit(1); |
72 } | 70 } |
| 71 |
| 72 void _printStackTrace(String stackTrace) { |
| 73 if (stackTrace == null || stackTrace == '') return; |
| 74 |
| 75 print(''); |
| 76 |
| 77 // Parse out each stack entry. |
| 78 var stack = []; |
| 79 for (var line in stackTrace.split('\n')) { |
| 80 if (line.trim() == '') continue; |
| 81 stack.add(new _StackFrame(line)); |
| 82 } |
| 83 |
| 84 if (stack.length == 0) return; |
| 85 |
| 86 // Figure out the longest path so we know how much to pad. |
| 87 int longest = stack.map((frame) => frame.location.length).reduce(math.max); |
| 88 |
| 89 // Print out the stack trace nicely formatted. |
| 90 for (var frame in stack) { |
| 91 print(' ${_padLeft(frame.location, longest)} ${frame.member}'); |
| 92 } |
| 93 |
| 94 print(''); |
| 95 } |
| 96 |
| 97 String _padLeft(String string, int length) { |
| 98 if (string.length >= length) return string; |
| 99 |
| 100 var result = new StringBuffer(); |
| 101 result.write(string); |
| 102 for (var i = 0; i < length - string.length; i++) { |
| 103 result.write(' '); |
| 104 } |
| 105 |
| 106 return result.toString(); |
| 107 } |
| 108 |
| 109 String _indent(String str) => |
| 110 str.replaceAll(new RegExp("^", multiLine: true), " "); |
73 } | 111 } |
| 112 |
| 113 class _StackFrame { |
| 114 static final fileRegExp = new RegExp( |
| 115 r'#\d+\s+(.*) \(file://(/.+):(\d+):(\d+)\)'); |
| 116 static final coreRegExp = new RegExp(r'#\d+\s+(.*) \((.+):(\d+):(\d+)\)'); |
| 117 |
| 118 /// If `true`, then this stack frame is for a library built into Dart and |
| 119 /// not a regular file path. |
| 120 final bool isCore; |
| 121 |
| 122 /// The path to the library or the library name if a core library. |
| 123 String library; |
| 124 |
| 125 /// The line number. |
| 126 final String line; |
| 127 |
| 128 /// The column number. |
| 129 final String column; |
| 130 |
| 131 /// The member where the error occurred. |
| 132 final String member; |
| 133 |
| 134 /// A formatted description of the code location. |
| 135 String get location => '$library $line:$column'; |
| 136 |
| 137 _StackFrame._(this.isCore, this.library, this.line, this.column, this.member); |
| 138 |
| 139 factory _StackFrame(String text) { |
| 140 var match = fileRegExp.firstMatch(text); |
| 141 var isCore = false; |
| 142 |
| 143 if (match == null) { |
| 144 match = coreRegExp.firstMatch(text); |
| 145 if (match == null) { |
| 146 throw new FormatException("Couldn't parse stack trace line '$text'."); |
| 147 } |
| 148 isCore = true; |
| 149 } |
| 150 |
| 151 var library = match[2]; |
| 152 if (!isCore) { |
| 153 // Make the library path relative to the entrypoint. |
| 154 library = path.relative(library); |
| 155 } |
| 156 |
| 157 var member = match[1].replaceAll("<anonymous closure>", _lambda); |
| 158 return new _StackFrame._(isCore, library, match[3], match[4], member); |
| 159 } |
| 160 } |
OLD | NEW |