| Index: utils/tests/pub/command_line_config.dart
|
| diff --git a/utils/tests/pub/command_line_config.dart b/utils/tests/pub/command_line_config.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6b61a45510651ed1b598aec4f0b938c1fd061651
|
| --- /dev/null
|
| +++ b/utils/tests/pub/command_line_config.dart
|
| @@ -0,0 +1,139 @@
|
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library command_line_config;
|
| +
|
| +import 'dart:io';
|
| +
|
| +import '../../../pkg/unittest/lib/unittest.dart';
|
| +import '../../pub/utils.dart';
|
| +
|
| +const _GREEN = '\u001b[32m';
|
| +const _RED = '\u001b[31m';
|
| +const _MAGENTA = '\u001b[35m';
|
| +const _NONE = '\u001b[0m';
|
| +
|
| +/// Pretty Unicode characters!
|
| +const _CHECKBOX = '\u2713';
|
| +const _BALLOT_X = '\u2717';
|
| +
|
| +/// A custom unittest configuration for running the pub tests from the
|
| +/// command-line and generating human-friendly output.
|
| +class CommandLineConfiguration extends Configuration {
|
| + void onInit() {
|
| + // Do nothing. Overridden to prevent the base class from printing.
|
| + }
|
| +
|
| + void onTestResult(TestCase testCase) {
|
| + var result;
|
| + switch (testCase.result) {
|
| + case PASS: result = '$_GREEN$_CHECKBOX$_NONE'; break;
|
| + case FAIL: result = '$_RED$_BALLOT_X$_NONE'; break;
|
| + case ERROR: result = '$_MAGENTA?$_NONE'; break;
|
| + }
|
| + print('$result ${testCase.description}');
|
| +
|
| + if (testCase.message != '') {
|
| + print(_indent(testCase.message));
|
| + }
|
| +
|
| + _printStackTrace(testCase.stackTrace);
|
| +
|
| + currentTestCase = null;
|
| + }
|
| +
|
| + void onSummary(int passed, int failed, int errors, List<TestCase> results,
|
| + String uncaughtError) {
|
| + var success = false;
|
| + if (uncaughtError != null) {
|
| + print('Top-level uncaught error: $uncaughtError');
|
| + } else if (errors != 0) {
|
| + print('${_GREEN}$passed${_NONE} passed, ${_RED}$failed${_NONE} failed, '
|
| + '${_MAGENTA}$errors${_NONE} errors.');
|
| + } else if (failed != 0) {
|
| + print('${_GREEN}$passed${_NONE} passed, ${_RED}$failed${_NONE} '
|
| + 'failed.');
|
| + } else if (passed == 0) {
|
| + print('No tests found.');
|
| + } else {
|
| + print('All ${_GREEN}$passed${_NONE} tests passed!');
|
| + success = true;
|
| + }
|
| + }
|
| +
|
| + void onDone(bool success) {
|
| + if (!success) exit(1);
|
| + }
|
| +
|
| + void _printStackTrace(String stackTrace) {
|
| + if (stackTrace == null || stackTrace == '') return;
|
| +
|
| + // Parse out each stack entry.
|
| + var regexp = new RegExp(r'#\d+\s+(.*) \(file:///([^)]+)\)');
|
| + var stack = [];
|
| + for (var line in stackTrace.split('\n')) {
|
| + if (line.trim() == '') continue;
|
| +
|
| + var match = regexp.firstMatch(line);
|
| + if (match == null) throw "Couldn't clean up stack trace line '$line'.";
|
| + stack.add(new Pair(match[2], match[1]));
|
| + }
|
| +
|
| + if (stack.length == 0) return;
|
| +
|
| + // Find the common prefixes of the paths.
|
| + var common = 0;
|
| + while (true) {
|
| + var matching = true;
|
| + // TODO(bob): Handle empty stack.
|
| + var c = stack[0].first[common];
|
| + for (var pair in stack) {
|
| + if (pair.first.length <= common || pair.first[common] != c) {
|
| + matching = false;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (!matching) break;
|
| + common++;
|
| + }
|
| +
|
| + // Remove them.
|
| + if (common > 0) {
|
| + for (var pair in stack) {
|
| + pair.first = pair.first.substring(common);
|
| + }
|
| + }
|
| +
|
| + // Figure out the longest path so we know how much to pad.
|
| + int longest = stack.mappedBy((pair) => pair.first.length).max();
|
| +
|
| + // Print out the stack trace nicely formatted.
|
| + for (var pair in stack) {
|
| + var path = pair.first;
|
| + path = path.replaceFirst(':', ' ');
|
| + print(' ${_padLeft(path, longest)} ${pair.last}');
|
| + }
|
| +
|
| + print('');
|
| + }
|
| +
|
| + String _padLeft(String string, int length) {
|
| + if (string.length >= length) return string;
|
| +
|
| + var result = new StringBuffer();
|
| + result.add(string);
|
| + for (var i = 0; i < length - string.length; i++) {
|
| + result.add(' ');
|
| + }
|
| +
|
| + return result.toString();
|
| + }
|
| +
|
| + String _indent(String str) {
|
| + // TODO(nweiz): Use this simpler code once issue 2980 is fixed.
|
| + // return str.replaceAll(new RegExp("^", multiLine: true), " ");
|
| + return Strings.join(str.split("\n").mappedBy((line) => " $line"), "\n");
|
| + }
|
| +}
|
|
|