Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(406)

Side by Side Diff: pkg/unittest/lib/unittest.dart

Issue 18892003: Roll forward "Use package:stack_trace in unittest." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Merge head. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/unittest/lib/src/utils.dart ('k') | pkg/unittest/pubspec.yaml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 /** 5 /**
6 * A library for writing dart unit tests. 6 * A library for writing dart unit tests.
7 * 7 *
8 * ## Installing ## 8 * ## Installing ##
9 * 9 *
10 * Use [pub][] to install this package. Add the following to your `pubspec.yaml` 10 * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 */ 166 */
167 library unittest; 167 library unittest;
168 168
169 import 'dart:async'; 169 import 'dart:async';
170 import 'dart:collection'; 170 import 'dart:collection';
171 import 'dart:isolate'; 171 import 'dart:isolate';
172 import 'dart:math' show max; 172 import 'dart:math' show max;
173 import 'matcher.dart'; 173 import 'matcher.dart';
174 export 'matcher.dart'; 174 export 'matcher.dart';
175 175
176 import 'package:stack_trace/stack_trace.dart';
177
178 import 'src/utils.dart';
176 part 'src/config.dart'; 179 part 'src/config.dart';
177 part 'src/test_case.dart'; 180 part 'src/test_case.dart';
178 181
179 Configuration _config; 182 Configuration _config;
180 183
181 /** 184 /**
182 * [Configuration] used by the unittest library. Note that if a 185 * [Configuration] used by the unittest library. Note that if a
183 * configuration has not been set, calling this getter will create 186 * configuration has not been set, calling this getter will create
184 * a default configuration. 187 * a default configuration.
185 */ 188 */
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 bool shouldCallBack() { 449 bool shouldCallBack() {
447 ++actualCalls; 450 ++actualCalls;
448 if (testCase.isComplete) { 451 if (testCase.isComplete) {
449 // Don't run if the test is done. We don't throw here as this is not 452 // Don't run if the test is done. We don't throw here as this is not
450 // the current test, but we do mark the old test as having an error 453 // the current test, but we do mark the old test as having an error
451 // if it previously passed. 454 // if it previously passed.
452 if (testCase.result == PASS) { 455 if (testCase.result == PASS) {
453 testCase.error( 456 testCase.error(
454 'Callback ${id}called ($actualCalls) after test case ' 457 'Callback ${id}called ($actualCalls) after test case '
455 '${testCase.description} has already been marked as ' 458 '${testCase.description} has already been marked as '
456 '${testCase.result}.', ''); 459 '${testCase.result}.');
457 } 460 }
458 return false; 461 return false;
459 } else if (maxExpectedCalls >= 0 && actualCalls > maxExpectedCalls) { 462 } else if (maxExpectedCalls >= 0 && actualCalls > maxExpectedCalls) {
460 throw new TestFailure('Callback ${id}called more times than expected ' 463 throw new TestFailure('Callback ${id}called more times than expected '
461 '($maxExpectedCalls).'); 464 '($maxExpectedCalls).');
462 } 465 }
463 return true; 466 return true;
464 } 467 }
465 468
466 void after() { 469 void after() {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 runAsync(() { 670 runAsync(() {
668 _currentTestCaseIndex++; 671 _currentTestCaseIndex++;
669 _nextBatch(); 672 _nextBatch();
670 }); 673 });
671 } 674 }
672 675
673 /** 676 /**
674 * Utility function that can be used to notify the test framework that an 677 * Utility function that can be used to notify the test framework that an
675 * error was caught outside of this library. 678 * error was caught outside of this library.
676 */ 679 */
677 void _reportTestError(String msg, String trace) { 680 void _reportTestError(String msg, trace) {
678 if (_currentTestCaseIndex < testCases.length) { 681 if (_currentTestCaseIndex < testCases.length) {
679 final testCase = testCases[_currentTestCaseIndex]; 682 final testCase = testCases[_currentTestCaseIndex];
680 testCase.error(msg, trace); 683 testCase.error(msg, trace);
681 } else { 684 } else {
682 _uncaughtErrorMessage = "$msg: $trace"; 685 _uncaughtErrorMessage = "$msg: $trace";
683 } 686 }
684 } 687 }
685 688
686 void rerunTests() { 689 void rerunTests() {
687 _uncaughtErrorMessage = null; 690 _uncaughtErrorMessage = null;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 * Registers that an exception was caught for the current test. 747 * Registers that an exception was caught for the current test.
745 */ 748 */
746 void registerException(e, [trace]) { 749 void registerException(e, [trace]) {
747 _registerException(currentTestCase, e, trace); 750 _registerException(currentTestCase, e, trace);
748 } 751 }
749 752
750 /** 753 /**
751 * Registers that an exception was caught for the current test. 754 * Registers that an exception was caught for the current test.
752 */ 755 */
753 void _registerException(TestCase testCase, e, [trace]) { 756 void _registerException(TestCase testCase, e, [trace]) {
754 trace = trace == null ? '' : trace.toString();
755 String message = (e is TestFailure) ? e.message : 'Caught $e'; 757 String message = (e is TestFailure) ? e.message : 'Caught $e';
756 if (testCase.result == null) { 758 if (testCase.result == null) {
757 testCase.fail(message, trace); 759 testCase.fail(message, trace);
758 } else { 760 } else {
759 testCase.error(message, trace); 761 testCase.error(message, trace);
760 } 762 }
761 } 763 }
762 764
763 /** 765 /**
764 * Runs a batch of tests, yielding whenever an asynchronous test starts 766 * Runs a batch of tests, yielding whenever an asynchronous test starts
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 /** Enable a test by ID. */ 859 /** Enable a test by ID. */
858 void enableTest(int testId) => _setTestEnabledState(testId, true); 860 void enableTest(int testId) => _setTestEnabledState(testId, true);
859 861
860 /** Disable a test by ID. */ 862 /** Disable a test by ID. */
861 void disableTest(int testId) => _setTestEnabledState(testId, false); 863 void disableTest(int testId) => _setTestEnabledState(testId, false);
862 864
863 /** Signature for a test function. */ 865 /** Signature for a test function. */
864 typedef dynamic TestFunction(); 866 typedef dynamic TestFunction();
865 867
866 /** 868 /**
867 * A flag that controls whether we hide unittest details in exception stacks. 869 * A flag that controls whether we hide unittest and core library details in
870 * exception stacks.
871 *
868 * Useful to disable when debugging unittest or matcher customizations. 872 * Useful to disable when debugging unittest or matcher customizations.
869 */ 873 */
870 bool formatStacks = true; 874 bool formatStacks = true;
871 875
872 // Stack formatting utility. Strips extraneous content from a stack trace. 876 /** Returns a Trace object from a StackTrace object or a String. */
873 // Stack frame lines are parsed with a regexp, which has been tested 877 Trace _getTrace(stack) {
874 // in Chrome, Firefox and the VM. If a line fails to be parsed it is 878 Trace trace;
875 // included in the output to be conservative. 879 if (stack == null) return null;
876 // 880 if (stack is String) {
877 // The output stack consists of everything after the call to TestCase._run. 881 trace = new Trace.parse(stack);
878 // If we see an 'expect' in the frame we will prune everything above that 882 } else if (stack is StackTrace) {
879 // as well. 883 trace = new Trace.from(stack);
880 final _frameRegExp = new RegExp(
881 r'^\s*' // Skip leading spaces.
882 r'(?:' // Group of choices for the prefix.
883 r'(?:#\d+\s*)|' // Skip VM's #<frameNumber>.
884 r'(?:at )|' // Skip Firefox's 'at '.
885 r'(?:))' // Other environments have nothing here.
886 r'(.+)' // Extract the function/method.
887 r'\s*[@\(]' // Skip space and @ or (.
888 r'(' // This group of choices is for the source file.
889 r'(?:.+:\/\/.+\/[^:]*)|' // Handle file:// or http:// URLs.
890 r'(?:dart:[^:]*)|' // Handle dart:<lib>.
891 r'(?:package:[^:]*)' // Handle package:<path>
892 r'):([:\d]+)[\)]?$'); // Get the line number and optional column number.
893
894 String _formatStack(stack) {
895 if (!formatStacks) return "$stack";
896 var lines;
897 if (stack is StackTrace) {
898 lines = stack.toString().split('\n');
899 } else if (stack is String) {
900 lines = stack.split('\n');
901 } else { 884 } else {
902 return stack.toString(); 885 throw new Exception('Invalid stack type ${stack.runtimeType} for $stack.');
903 } 886 }
904 887
905 // Calculate the max width of first column so we can 888 if (!formatStacks) return trace;
906 // pad to align the second columns.
907 int padding = lines.fold(0, (n, line) {
908 var match = _frameRegExp.firstMatch(line);
909 if (match == null) return n;
910 return max(n, match[1].length + 1);
911 });
912 889
913 // We remove all entries that have a location in unittest. 890 // Format the stack trace by removing everything above TestCase._runTest,
914 // We strip out anything before _nextBatch too. 891 // which is usually going to be irrelevant. Also fold together unittest and
915 var sb = new StringBuffer(); 892 // core library calls so only the function the user called is visible.
916 for (var i = 0; i < lines.length; i++) { 893 return new Trace(trace.frames.takeWhile((frame) {
917 var line = lines[i]; 894 return frame.package != 'unittest' || frame.member != 'TestCase._runTest';
918 if (line == '') continue; 895 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore);
919 var match = _frameRegExp.firstMatch(line);
920 if (match == null) {
921 sb.write(line);
922 sb.write('\n');
923 } else {
924 var member = match[1];
925 var location = match[2];
926 var position = match[3];
927 if (member.indexOf('TestCase._runTest') >= 0) {
928 // Don't include anything after this.
929 break;
930 } else if (member.indexOf('expect') >= 0) {
931 // It looks like this was an expect() failure;
932 // drop all the frames up to here.
933 sb.clear();
934 } else {
935 sb.write(member);
936 // Pad second column to a fixed position.
937 for (var j = 0; j <= padding - member.length; j++) {
938 sb.write(' ');
939 }
940 sb.write(location);
941 sb.write(' ');
942 sb.write(position);
943 sb.write('\n');
944 }
945 }
946 }
947 return sb.toString();
948 } 896 }
OLDNEW
« no previous file with comments | « pkg/unittest/lib/src/utils.dart ('k') | pkg/unittest/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698