| 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 import 'dart:math' as math; |  | 
| 9 |  | 
| 10 import 'package:pathos/path.dart' as path; |  | 
| 11 import 'package:unittest/unittest.dart'; |  | 
| 12 import '../lib/src/utils.dart'; |  | 
| 13 |  | 
| 14 /// Pretty Unicode characters! |  | 
| 15 final _checkbox = getSpecial('\u2713', 'PASS'); |  | 
| 16 final _ballotX  = getSpecial('\u2717', 'FAIL'); |  | 
| 17 final _lambda   = getSpecial('\u03bb', '<fn>'); |  | 
| 18 |  | 
| 19 final _green = getSpecial('\u001b[32m'); |  | 
| 20 final _red = getSpecial('\u001b[31m'); |  | 
| 21 final _magenta = getSpecial('\u001b[35m'); |  | 
| 22 final _none = getSpecial('\u001b[0m'); |  | 
| 23 |  | 
| 24 /// A custom unittest configuration for running the pub tests from the |  | 
| 25 /// command-line and generating human-friendly output. |  | 
| 26 class CommandLineConfiguration extends Configuration { |  | 
| 27   void onInit() { |  | 
| 28     // Do nothing. Overridden to prevent the base class from printing. |  | 
| 29   } |  | 
| 30 |  | 
| 31   void onTestResult(TestCase testCase) { |  | 
| 32     var result; |  | 
| 33     switch (testCase.result) { |  | 
| 34       case PASS: result = '$_green$_checkbox$_none'; break; |  | 
| 35       case FAIL: result = '$_red$_ballotX$_none'; break; |  | 
| 36       case ERROR: result = '$_magenta?$_none'; break; |  | 
| 37     } |  | 
| 38     print('$result ${testCase.description}'); |  | 
| 39 |  | 
| 40     if (testCase.message != '') { |  | 
| 41       print(_indent(testCase.message)); |  | 
| 42     } |  | 
| 43 |  | 
| 44     _printStackTrace(testCase.stackTrace); |  | 
| 45 |  | 
| 46     super.onTestResult(testCase); |  | 
| 47   } |  | 
| 48 |  | 
| 49   void onSummary(int passed, int failed, int errors, List<TestCase> results, |  | 
| 50       String uncaughtError) { |  | 
| 51     var success = false; |  | 
| 52     if (uncaughtError != null) { |  | 
| 53       print('Top-level uncaught error: $uncaughtError'); |  | 
| 54     } else if (errors != 0) { |  | 
| 55       print('${_green}$passed${_none} passed, ${_red}$failed${_none} failed, ' |  | 
| 56             '${_magenta}$errors${_none} errors.'); |  | 
| 57     } else if (failed != 0) { |  | 
| 58       print('${_green}$passed${_none} passed, ${_red}$failed${_none} ' |  | 
| 59             'failed.'); |  | 
| 60     } else if (passed == 0) { |  | 
| 61       print('No tests found.'); |  | 
| 62     } else { |  | 
| 63       print('All ${_green}$passed${_none} tests passed!'); |  | 
| 64       success = true; |  | 
| 65     } |  | 
| 66   } |  | 
| 67 |  | 
| 68   void onDone(bool success) { |  | 
| 69     if (!success) exit(1); |  | 
| 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), "  "); |  | 
| 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 | 
|---|