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

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

Issue 23011047: Migrate stack filtering change to new configfuration class. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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 | « no previous file | pkg/unittest/lib/src/simple_configuration.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011, 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 part of unittest;
6
7 // A custom failure handler for [expect] that routes expect failures
8 // to the config.
9 class _ExpectFailureHandler extends DefaultFailureHandler {
10 Configuration _config;
11
12 _ExpectFailureHandler(this._config) : super();
13
14 void fail(String reason) {
15 _config.onExpectFailure(reason);
16 }
17 }
18
19 /**
20 * Hooks to configure the unittest library for different platforms. This class
21 * implements the API in a platform-independent way. Tests that want to take
22 * advantage of the platform can create a subclass and override methods from
23 * this class.
24 */
25
26 class Configuration {
27 // The VM won't shut down if a receive port is open. Use this to make sure
28 // we correctly wait for asynchronous tests.
29 ReceivePort _receivePort;
30
31 /**
32 * Subclasses can override this with something useful for diagnostics.
33 * Particularly useful in cases where we have parent/child configurations
34 * such as layout tests.
35 */
36 final String name = 'Configuration';
37
38 /**
39 * If true, then tests are started automatically (otherwise [runTests]
40 * must be called explicitly after the tests are set up.
41 */
42 final bool autoStart = true;
43
44 /**
45 * If true (the default), throw an exception at the end if any tests failed.
46 */
47 bool throwOnTestFailures = true;
48
49 /**
50 * If true (the default), then tests will stop after the first failed
51 * [expect]. If false, failed [expect]s will not cause the test
52 * to stop (other exceptions will still terminate the test).
53 */
54 bool stopTestOnExpectFailure = true;
55
56 // If stopTestOnExpectFailure is false, we need to capture failures, which
57 // we do with this List.
58 final _testLogBuffer = <Pair<String, StackTrace>>[];
59
60 /**
61 * The constructor sets up a failure handler for [expect] that redirects
62 * [expect] failures to [onExpectFailure].
63 */
64 Configuration() {
65 configureExpectFailureHandler(new _ExpectFailureHandler(this));
66 }
67 /**
68 * Called as soon as the unittest framework becomes initialized. This is done
69 * even before tests are added to the test framework. It might be used to
70 * determine/debug errors that occur before the test harness starts executing.
71 * It is also used to tell the vm or browser that tests are going to be run
72 * asynchronously and that the process should wait until they are done.
73 */
74 void onInit() {
75 // For Dart internal tests, we don't want stack frame filtering.
76 // We turn it off here in the default config, but by default turn
77 // it back on in the vm and html configs.
78 filterStacks = false;
79 _receivePort = new ReceivePort();
80 _postMessage('unittest-suite-wait-for-done');
81 }
82
83 /** Called as soon as the unittest framework starts running. */
84 void onStart() {}
85
86 /**
87 * Called when each test starts. Useful to show intermediate progress on
88 * a test suite. Derived classes should call this first before their own
89 * override code.
90 */
91 void onTestStart(TestCase testCase) {
92 assert(testCase != null);
93 _testLogBuffer.clear();
94 }
95
96 /**
97 * Called when each test is first completed. Useful to show intermediate
98 * progress on a test suite. Derived classes should call this first
99 * before their own override code.
100 */
101 void onTestResult(TestCase testCase) {
102 assert(testCase != null);
103 if (!stopTestOnExpectFailure && _testLogBuffer.length > 0) {
104 // Write the message/stack pairs up to the last pairs.
105 var reason = new StringBuffer();
106 for (var reasonAndTrace in
107 _testLogBuffer.take(_testLogBuffer.length - 1)) {
108 reason.write(reasonAndTrace.first);
109 reason.write('\n');
110 reason.write(reasonAndTrace.last);
111 reason.write('\n');
112 }
113 var lastReasonAndTrace = _testLogBuffer.last;
114 // Write the last message.
115 reason.write(lastReasonAndTrace.first);
116 if (testCase.result == PASS) {
117 testCase._result = FAIL;
118 testCase._message = reason.toString();
119 // Use the last stack as the overall failure stack.
120 testCase._stackTrace = lastReasonAndTrace.last;
121 } else {
122 // Add the last stack to the message; we have a further stack
123 // caused by some other failure.
124 reason.write(lastReasonAndTrace.last);
125 reason.write('\n');
126 // Add the existing reason to the end of the expect log to
127 // create the final message.
128 testCase._message = '${reason.toString()}\n${testCase._message}';
129 }
130 }
131 }
132
133 /**
134 * Called when an already completed test changes state; for example a test
135 * that was marked as passing may later be marked as being in error because
136 * it still had callbacks being invoked.
137 */
138 void onTestResultChanged(TestCase testCase) {
139 assert(testCase != null);
140 }
141
142 /**
143 * Handles the logging of messages by a test case. The default in
144 * this base configuration is to call print();
145 */
146 void onLogMessage(TestCase testCase, String message) {
147 print(message);
148 }
149
150 /**
151 * Handles failures from expect(). The default in
152 * this base configuration is to throw an exception;
153 */
154 void onExpectFailure(String reason) {
155 if (stopTestOnExpectFailure) {
156 throw new TestFailure(reason);
157 } else {
158 try {
159 throw '';
160 } catch (_, stack) {
161 var trace = _getTrace(stack);
162 if (trace == null) trace = stack;
163 _testLogBuffer.add(new Pair<String, StackTrace>(reason, trace));
164 }
165 }
166 }
167
168 /**
169 * Format a test result.
170 */
171 String formatResult(TestCase testCase) {
172 var result = new StringBuffer();
173 result.write(testCase.result.toUpperCase());
174 result.write(": ");
175 result.write(testCase.description);
176 result.write("\n");
177
178 if (testCase.message != '') {
179 result.write(indent(testCase.message));
180 result.write("\n");
181 }
182
183 if (testCase.stackTrace != null) {
184 result.write(indent(testCase.stackTrace.toString()));
185 result.write("\n");
186 }
187 return result.toString();
188 }
189
190 /**
191 * Called with the result of all test cases. The default implementation prints
192 * the result summary using the built-in [print] command. Browser tests
193 * commonly override this to reformat the output.
194 *
195 * When [uncaughtError] is not null, it contains an error that occured outside
196 * of tests (e.g. setting up the test).
197 */
198 void onSummary(int passed, int failed, int errors, List<TestCase> results,
199 String uncaughtError) {
200 // Print each test's result.
201 for (final t in results) {
202 print(formatResult(t).trim());
203 }
204
205 // Show the summary.
206 print('');
207
208 if (passed == 0 && failed == 0 && errors == 0 && uncaughtError == null) {
209 print('No tests found.');
210 // This is considered a failure too.
211 } else if (failed == 0 && errors == 0 && uncaughtError == null) {
212 print('All $passed tests passed.');
213 } else {
214 if (uncaughtError != null) {
215 print('Top-level uncaught error: $uncaughtError');
216 }
217 print('$passed PASSED, $failed FAILED, $errors ERRORS');
218 }
219 }
220
221 /**
222 * Called when the unittest framework is done running. [success] indicates
223 * whether all tests passed successfully.
224 */
225 void onDone(bool success) {
226 if (success) {
227 _postMessage('unittest-suite-success');
228 _receivePort.close();
229 } else {
230 _receivePort.close();
231 if (throwOnTestFailures) {
232 throw new Exception('Some tests failed.');
233 }
234 }
235 }
236
237 /** Handle errors that happen outside the tests. */
238 // TODO(vsm): figure out how to expose the stack trace here
239 // Currently e.message works in dartium, but not in dartc.
240 void handleExternalError(e, String message, [stack]) =>
241 _reportTestError('$message\nCaught $e', stack);
242
243 _postMessage(String message) {
244 // In dart2js browser tests, the JavaScript-based test controller
245 // intercepts calls to print and listens for "secret" messages.
246 print(message);
247 }
248 }
OLDNEW
« no previous file with comments | « no previous file | pkg/unittest/lib/src/simple_configuration.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698