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 _printStackTrace(testCase.stackTrace); | 44 if (testCase.stackTrace != null) { |
| 45 print(_indent(testCase.stackTrace.toString())); |
| 46 } |
45 | 47 |
46 super.onTestResult(testCase); | 48 super.onTestResult(testCase); |
47 } | 49 } |
48 | 50 |
49 void onSummary(int passed, int failed, int errors, List<TestCase> results, | 51 void onSummary(int passed, int failed, int errors, List<TestCase> results, |
50 String uncaughtError) { | 52 String uncaughtError) { |
51 var success = false; | 53 var success = false; |
52 if (uncaughtError != null) { | 54 if (uncaughtError != null) { |
53 print('Top-level uncaught error: $uncaughtError'); | 55 print('Top-level uncaught error: $uncaughtError'); |
54 } else if (errors != 0) { | 56 } else if (errors != 0) { |
55 print('${_green}$passed${_none} passed, ${_red}$failed${_none} failed, ' | 57 print('${_green}$passed${_none} passed, ${_red}$failed${_none} failed, ' |
56 '${_magenta}$errors${_none} errors.'); | 58 '${_magenta}$errors${_none} errors.'); |
57 } else if (failed != 0) { | 59 } else if (failed != 0) { |
58 print('${_green}$passed${_none} passed, ${_red}$failed${_none} ' | 60 print('${_green}$passed${_none} passed, ${_red}$failed${_none} ' |
59 'failed.'); | 61 'failed.'); |
60 } else if (passed == 0) { | 62 } else if (passed == 0) { |
61 print('No tests found.'); | 63 print('No tests found.'); |
62 } else { | 64 } else { |
63 print('All ${_green}$passed${_none} tests passed!'); | 65 print('All ${_green}$passed${_none} tests passed!'); |
64 success = true; | 66 success = true; |
65 } | 67 } |
66 } | 68 } |
67 | 69 |
68 void onDone(bool success) { | 70 void onDone(bool success) { |
69 if (!success) exit(1); | 71 if (!success) exit(1); |
70 } | 72 } |
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), " "); | |
111 } | 73 } |
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 |