| Index: pkg/unittest/lib/unittest.dart
|
| diff --git a/pkg/unittest/lib/unittest.dart b/pkg/unittest/lib/unittest.dart
|
| index ec788778ecf751a8caf8cb0c07b00822ed88c801..7b134e96235dd72086c2d378d5d00fb6972da951 100644
|
| --- a/pkg/unittest/lib/unittest.dart
|
| +++ b/pkg/unittest/lib/unittest.dart
|
| @@ -173,6 +173,9 @@ import 'dart:math' show max;
|
| import 'matcher.dart';
|
| export 'matcher.dart';
|
|
|
| +import 'package:stack_trace/stack_trace.dart';
|
| +
|
| +import 'src/utils.dart';
|
| part 'src/config.dart';
|
| part 'src/test_case.dart';
|
|
|
| @@ -453,7 +456,7 @@ class _SpreadArgsHelper {
|
| testCase.error(
|
| 'Callback ${id}called ($actualCalls) after test case '
|
| '${testCase.description} has already been marked as '
|
| - '${testCase.result}.', '');
|
| + '${testCase.result}.');
|
| }
|
| return false;
|
| } else if (maxExpectedCalls >= 0 && actualCalls > maxExpectedCalls) {
|
| @@ -674,7 +677,7 @@ void _nextTestCase() {
|
| * Utility function that can be used to notify the test framework that an
|
| * error was caught outside of this library.
|
| */
|
| -void _reportTestError(String msg, String trace) {
|
| +void _reportTestError(String msg, trace) {
|
| if (_currentTestCaseIndex < testCases.length) {
|
| final testCase = testCases[_currentTestCaseIndex];
|
| testCase.error(msg, trace);
|
| @@ -751,7 +754,6 @@ void registerException(e, [trace]) {
|
| * Registers that an exception was caught for the current test.
|
| */
|
| void _registerException(TestCase testCase, e, [trace]) {
|
| - trace = trace == null ? '' : trace.toString();
|
| String message = (e is TestFailure) ? e.message : 'Caught $e';
|
| if (testCase.result == null) {
|
| testCase.fail(message, trace);
|
| @@ -864,85 +866,31 @@ void disableTest(int testId) => _setTestEnabledState(testId, false);
|
| typedef dynamic TestFunction();
|
|
|
| /**
|
| - * A flag that controls whether we hide unittest details in exception stacks.
|
| + * A flag that controls whether we hide unittest and core library details in
|
| + * exception stacks.
|
| + *
|
| * Useful to disable when debugging unittest or matcher customizations.
|
| */
|
| bool formatStacks = true;
|
|
|
| -// Stack formatting utility. Strips extraneous content from a stack trace.
|
| -// Stack frame lines are parsed with a regexp, which has been tested
|
| -// in Chrome, Firefox and the VM. If a line fails to be parsed it is
|
| -// included in the output to be conservative.
|
| -//
|
| -// The output stack consists of everything after the call to TestCase._run.
|
| -// If we see an 'expect' in the frame we will prune everything above that
|
| -// as well.
|
| -final _frameRegExp = new RegExp(
|
| - r'^\s*' // Skip leading spaces.
|
| - r'(?:' // Group of choices for the prefix.
|
| - r'(?:#\d+\s*)|' // Skip VM's #<frameNumber>.
|
| - r'(?:at )|' // Skip Firefox's 'at '.
|
| - r'(?:))' // Other environments have nothing here.
|
| - r'(.+)' // Extract the function/method.
|
| - r'\s*[@\(]' // Skip space and @ or (.
|
| - r'(' // This group of choices is for the source file.
|
| - r'(?:.+:\/\/.+\/[^:]*)|' // Handle file:// or http:// URLs.
|
| - r'(?:dart:[^:]*)|' // Handle dart:<lib>.
|
| - r'(?:package:[^:]*)' // Handle package:<path>
|
| - r'):([:\d]+)[\)]?$'); // Get the line number and optional column number.
|
| -
|
| -String _formatStack(stack) {
|
| - if (!formatStacks) return "$stack";
|
| - var lines;
|
| - if (stack is StackTrace) {
|
| - lines = stack.toString().split('\n');
|
| - } else if (stack is String) {
|
| - lines = stack.split('\n');
|
| +/** Returns a Trace object from a StackTrace object or a String. */
|
| +Trace _getTrace(stack) {
|
| + Trace trace;
|
| + if (stack == null) return null;
|
| + if (stack is String) {
|
| + trace = new Trace.parse(stack);
|
| + } else if (stack is StackTrace) {
|
| + trace = new Trace.from(stack);
|
| } else {
|
| - return stack.toString();
|
| + throw new Exception('Invalid stack type ${stack.runtimeType} for $stack.');
|
| }
|
|
|
| - // Calculate the max width of first column so we can
|
| - // pad to align the second columns.
|
| - int padding = lines.fold(0, (n, line) {
|
| - var match = _frameRegExp.firstMatch(line);
|
| - if (match == null) return n;
|
| - return max(n, match[1].length + 1);
|
| - });
|
| + if (!formatStacks) return trace;
|
|
|
| - // We remove all entries that have a location in unittest.
|
| - // We strip out anything before _nextBatch too.
|
| - var sb = new StringBuffer();
|
| - for (var i = 0; i < lines.length; i++) {
|
| - var line = lines[i];
|
| - if (line == '') continue;
|
| - var match = _frameRegExp.firstMatch(line);
|
| - if (match == null) {
|
| - sb.write(line);
|
| - sb.write('\n');
|
| - } else {
|
| - var member = match[1];
|
| - var location = match[2];
|
| - var position = match[3];
|
| - if (member.indexOf('TestCase._runTest') >= 0) {
|
| - // Don't include anything after this.
|
| - break;
|
| - } else if (member.indexOf('expect') >= 0) {
|
| - // It looks like this was an expect() failure;
|
| - // drop all the frames up to here.
|
| - sb.clear();
|
| - } else {
|
| - sb.write(member);
|
| - // Pad second column to a fixed position.
|
| - for (var j = 0; j <= padding - member.length; j++) {
|
| - sb.write(' ');
|
| - }
|
| - sb.write(location);
|
| - sb.write(' ');
|
| - sb.write(position);
|
| - sb.write('\n');
|
| - }
|
| - }
|
| - }
|
| - return sb.toString();
|
| + // Format the stack trace by removing everything above TestCase._runTest,
|
| + // which is usually going to be irrelevant. Also fold together unittest and
|
| + // core library calls so only the function the user called is visible.
|
| + return new Trace(trace.frames.takeWhile((frame) {
|
| + return frame.package != 'unittest' || frame.member != 'TestCase._runTest';
|
| + })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore);
|
| }
|
|
|