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

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

Issue 22883008: starting to work on unit test config interface (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: more cleanup 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
OLDNEW
1 // Copyright (c) 2011, 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 part of unittest; 5 part of unittest;
6 6
7 // A custom failure handler for [expect] that routes expect failures 7 // A custom failure handler for [expect] that routes expect failures
8 // to the config. 8 // to the config.
9 class _ExpectFailureHandler extends DefaultFailureHandler { 9 class _ExpectFailureHandler extends DefaultFailureHandler {
10 Configuration _config; 10 final SimpleConfiguration _config;
11 11
12 _ExpectFailureHandler(this._config) : super(); 12 _ExpectFailureHandler(this._config);
13 13
14 void fail(String reason) { 14 void fail(String reason) {
15 _config.onExpectFailure(reason); 15 _config.onExpectFailure(reason);
16 } 16 }
17 } 17 }
18 18
19 /** 19 /**
20 * Hooks to configure the unittest library for different platforms. This class 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 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 22 * advantage of the platform can create a subclass and override methods from
23 * this class. 23 * this class.
24 */ 24 */
25 25 class SimpleConfiguration implements Configuration {
26 class Configuration {
27 // The VM won't shut down if a receive port is open. Use this to make sure 26 // The VM won't shut down if a receive port is open. Use this to make sure
28 // we correctly wait for asynchronous tests. 27 // we correctly wait for asynchronous tests.
29 ReceivePort _receivePort; 28 ReceivePort _receivePort;
30 29
31 /** 30 /**
32 * Subclasses can override this with something useful for diagnostics. 31 * Subclasses can override this with something useful for diagnostics.
33 * Particularly useful in cases where we have parent/child configurations 32 * Particularly useful in cases where we have parent/child configurations
34 * such as layout tests. 33 * such as layout tests.
35 */ 34 */
36 final String name = 'Configuration'; 35 final String name = 'Configuration';
37 36
38 /** 37 bool get autoStart => true;
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 38
44 /** 39 /**
45 * If true (the default), throw an exception at the end if any tests failed. 40 * If true (the default), throw an exception at the end if any tests failed.
46 */ 41 */
47 bool throwOnTestFailures = true; 42 bool throwOnTestFailures = true;
48 43
49 /** 44 /**
50 * If true (the default), then tests will stop after the first failed 45 * If true (the default), then tests will stop after the first failed
51 * [expect]. If false, failed [expect]s will not cause the test 46 * [expect]. If false, failed [expect]s will not cause the test
52 * to stop (other exceptions will still terminate the test). 47 * to stop (other exceptions will still terminate the test).
53 */ 48 */
54 bool stopTestOnExpectFailure = true; 49 bool stopTestOnExpectFailure = true;
55 50
56 // If stopTestOnExpectFailure is false, we need to capture failures, which 51 // If stopTestOnExpectFailure is false, we need to capture failures, which
57 // we do with this List. 52 // we do with this List.
58 final _testLogBuffer = <Pair<String, Trace>>[]; 53 final _testLogBuffer = <Pair<String, Trace>>[];
59 54
60 /** 55 /**
61 * The constructor sets up a failure handler for [expect] that redirects 56 * The constructor sets up a failure handler for [expect] that redirects
62 * [expect] failures to [onExpectFailure]. 57 * [expect] failures to [onExpectFailure].
63 */ 58 */
64 Configuration() { 59 SimpleConfiguration() {
65 configureExpectFailureHandler(new _ExpectFailureHandler(this)); 60 configureExpectFailureHandler(new _ExpectFailureHandler(this));
66 } 61 }
67 /** 62
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() { 63 void onInit() {
75 _receivePort = new ReceivePort(); 64 _receivePort = new ReceivePort();
76 _postMessage('unittest-suite-wait-for-done'); 65 _postMessage('unittest-suite-wait-for-done');
77 } 66 }
78 67
79 /** Called as soon as the unittest framework starts running. */
80 void onStart() {} 68 void onStart() {}
81 69
82 /** 70 /**
83 * Called when each test starts. Useful to show intermediate progress on 71 * Called when each test starts. Useful to show intermediate progress on
84 * a test suite. Derived classes should call this first before their own 72 * a test suite. Derived classes should call this first before their own
85 * override code. 73 * override code.
86 */ 74 */
87 void onTestStart(TestCase testCase) { 75 void onTestStart(TestCase testCase) {
88 assert(testCase != null); 76 assert(testCase != null);
89 _testLogBuffer.clear(); 77 _testLogBuffer.clear();
90 } 78 }
91 79
92 /** 80 /**
93 * Called when each test is first completed. Useful to show intermediate 81 * Called when each test is first completed. Useful to show intermediate
94 * progress on a test suite. Derived classes should call this first 82 * progress on a test suite. Derived classes should call this first
95 * before their own override code. 83 * before their own override code.
96 */ 84 */
97 void onTestResult(TestCase testCase) { 85 void onTestResult(TestCase testCase) {
98 assert(testCase != null); 86 assert(testCase != null);
99 if (!stopTestOnExpectFailure && _testLogBuffer.length > 0) { 87 if (!stopTestOnExpectFailure && _testLogBuffer.length > 0) {
100 // Write the message/stack pairs up to the last pairs. 88 // Write the message/stack pairs up to the last pairs.
101 var reason = new StringBuffer(); 89 var reason = new StringBuffer();
102 for (var reasonAndTrace in 90 for (var reasonAndTrace in
103 _testLogBuffer.take(_testLogBuffer.length - 1)) { 91 _testLogBuffer.take(_testLogBuffer.length - 1)) {
104 reason.write(reasonAndTrace.first); 92 reason.write(reasonAndTrace.first);
105 reason.write('\n'); 93 reason.write('\n');
106 reason.write(reasonAndTrace.last); 94 reason.write(reasonAndTrace.last);
107 reason.write('\n'); 95 reason.write('\n');
108 } 96 }
109 var lastReasonAndTrace = _testLogBuffer.last; 97 var lastReasonAndTrace = _testLogBuffer.last;
110 // Write the last message. 98 // Write the last message.
111 reason.write(lastReasonAndTrace.first); 99 reason.write(lastReasonAndTrace.first);
112 if (testCase.result == PASS) { 100 if (testCase.result == PASS) {
113 testCase._result = FAIL; 101 testCase._result = FAIL;
114 testCase._message = reason.toString(); 102 testCase._message = reason.toString();
115 // Use the last stack as the overall failure stack. 103 // Use the last stack as the overall failure stack.
116 testCase._stackTrace = lastReasonAndTrace.last; 104 testCase._stackTrace = lastReasonAndTrace.last;
117 } else { 105 } else {
118 // Add the last stack to the message; we have a further stack 106 // Add the last stack to the message; we have a further stack
119 // caused by some other failure. 107 // caused by some other failure.
120 reason.write(lastReasonAndTrace.last); 108 reason.write(lastReasonAndTrace.last);
121 reason.write('\n'); 109 reason.write('\n');
122 // Add the existing reason to the end of the expect log to 110 // Add the existing reason to the end of the expect log to
123 // create the final message. 111 // create the final message.
124 testCase._message = '${reason.toString()}\n${testCase._message}'; 112 testCase._message = '${reason.toString()}\n${testCase._message}';
125 } 113 }
126 } 114 }
127 } 115 }
128 116
129 /**
130 * Called when an already completed test changes state; for example a test
131 * that was marked as passing may later be marked as being in error because
132 * it still had callbacks being invoked.
133 */
134 void onTestResultChanged(TestCase testCase) { 117 void onTestResultChanged(TestCase testCase) {
135 assert(testCase != null); 118 assert(testCase != null);
136 } 119 }
137 120
138 /** 121 /**
139 * Handles the logging of messages by a test case. The default in 122 * Handles the logging of messages by a test case. The default in
140 * this base configuration is to call print(); 123 * this base configuration is to call print();
141 */ 124 */
142 void onLogMessage(TestCase testCase, String message) { 125 void onLogMessage(TestCase testCase, String message) {
143 print(message); 126 print(message);
144 } 127 }
145 128
146 /** 129 /**
147 * Handles failures from expect(). The default in 130 * Handles failures from expect(). The default in
148 * this base configuration is to throw an exception; 131 * this base configuration is to throw an exception;
149 */ 132 */
150 void onExpectFailure(String reason) { 133 void onExpectFailure(String reason) {
151 if (stopTestOnExpectFailure) { 134 if (stopTestOnExpectFailure) {
152 throw new TestFailure(reason); 135 throw new TestFailure(reason);
153 } else { 136 } else {
154 try { 137 try {
155 throw ''; 138 throw '';
156 } catch (_, stack) { 139 } catch (_, stack) {
157 _testLogBuffer.add( 140 _testLogBuffer.add(
158 new Pair<String, Trace>(reason, new Trace.from(stack))); 141 new Pair<String, Trace>(reason, new Trace.from(stack)));
159 } 142 }
160 } 143 }
161 } 144 }
162 145
163 /** 146 /**
164 * Format a test result. 147 * Format a test result.
165 */ 148 */
166 String formatResult(TestCase testCase) { 149 String formatResult(TestCase testCase) {
167 var result = new StringBuffer(); 150 var result = new StringBuffer();
168 result.write(testCase.result.toUpperCase()); 151 result.write(testCase.result.toUpperCase());
169 result.write(": "); 152 result.write(": ");
170 result.write(testCase.description); 153 result.write(testCase.description);
171 result.write("\n"); 154 result.write("\n");
172 155
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 } else if (failed == 0 && errors == 0 && uncaughtError == null) { 189 } else if (failed == 0 && errors == 0 && uncaughtError == null) {
207 print('All $passed tests passed.'); 190 print('All $passed tests passed.');
208 } else { 191 } else {
209 if (uncaughtError != null) { 192 if (uncaughtError != null) {
210 print('Top-level uncaught error: $uncaughtError'); 193 print('Top-level uncaught error: $uncaughtError');
211 } 194 }
212 print('$passed PASSED, $failed FAILED, $errors ERRORS'); 195 print('$passed PASSED, $failed FAILED, $errors ERRORS');
213 } 196 }
214 } 197 }
215 198
216 /**
217 * Called when the unittest framework is done running. [success] indicates
218 * whether all tests passed successfully.
219 */
220 void onDone(bool success) { 199 void onDone(bool success) {
221 if (success) { 200 if (success) {
222 _postMessage('unittest-suite-success'); 201 _postMessage('unittest-suite-success');
223 _receivePort.close(); 202 _receivePort.close();
224 } else { 203 } else {
225 _receivePort.close(); 204 _receivePort.close();
226 if (throwOnTestFailures) { 205 if (throwOnTestFailures) {
227 throw new Exception('Some tests failed.'); 206 throw new Exception('Some tests failed.');
228 } 207 }
229 } 208 }
230 } 209 }
231 210
232 /** Handle errors that happen outside the tests. */ 211 void _postMessage(String message) {
233 // TODO(vsm): figure out how to expose the stack trace here
234 // Currently e.message works in dartium, but not in dartc.
235 void handleExternalError(e, String message, [stack]) =>
236 _reportTestError('$message\nCaught $e', stack);
237
238 _postMessage(String message) {
239 // In dart2js browser tests, the JavaScript-based test controller 212 // In dart2js browser tests, the JavaScript-based test controller
240 // intercepts calls to print and listens for "secret" messages. 213 // intercepts calls to print and listens for "secret" messages.
241 print(message); 214 print(message);
242 } 215 }
243 } 216 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698