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

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

Issue 10335007: First pass at a generic reusable command line option parser. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 7 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 | « lib/args/utils.dart ('k') | tests/lib/args/args_test.dart » ('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) 2011, the Dart project authors. Please see the AUTHORS file 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 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 * ##Concepts## 8 * ##Concepts##
9 * 9 *
10 * * Tests: Tests are specified via the top-level function [test], they can be 10 * * Tests: Tests are specified via the top-level function [test], they can be
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 * }); 113 * });
114 * // indicate that the asynchronous callback was invoked. 114 * // indicate that the asynchronous callback was invoked.
115 * async.complete(); 115 * async.complete();
116 * }), 0); 116 * }), 0);
117 * }); 117 * });
118 * 118 *
119 */ 119 */
120 #library('unittest'); 120 #library('unittest');
121 121
122 #import('dart:isolate'); 122 #import('dart:isolate');
123 #import('../args/args.dart');
Bob Nystrom 2012/05/02 21:48:55 Oops! This is temp code. Don't worry about anythin
Bob Nystrom 2012/05/02 21:52:42 And, actually now that I look at it, the rest of t
123 124
124 #source('config.dart'); 125 #source('config.dart');
125 #source('expectation.dart'); 126 #source('expectation.dart');
126 #source('test_case.dart'); 127 #source('test_case.dart');
127 128
128 /** [Configuration] used by the unittest library. */ 129 /** [Configuration] used by the unittest library. */
129 Configuration _config = null; 130 Configuration _config = null;
130 131
131 /** Set the [Configuration] used by the unittest library. */ 132 /** Set the [Configuration] used by the unittest library. */
132 void configure(Configuration config) { 133 void configure(Configuration config) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 */ 166 */
166 final _UNCAUGHT_ERROR = 3; 167 final _UNCAUGHT_ERROR = 3;
167 168
168 int _state = _UNINITIALIZED; 169 int _state = _UNINITIALIZED;
169 String _uncaughtErrorMessage = null; 170 String _uncaughtErrorMessage = null;
170 171
171 final _PASS = 'pass'; 172 final _PASS = 'pass';
172 final _FAIL = 'fail'; 173 final _FAIL = 'fail';
173 final _ERROR = 'error'; 174 final _ERROR = 'error';
174 175
176 /** If set, then all other test cases will be ignored. */
177 TestCase _soloTest;
178
175 /** Creates an expectation for the given value. */ 179 /** Creates an expectation for the given value. */
176 Expectation expect(value) => new Expectation(value); 180 Expectation expect(value) => new Expectation(value);
177 181
178 /** Evaluates the given function and validates that it throws an exception. */ 182 /** Evaluates the given function and validates that it throws an exception. */
179 void expectThrow(function) { 183 void expectThrow(function, [bool callback(exception)]) {
180 bool threw = false; 184 bool threw = false;
181 try { 185 try {
182 function(); 186 function();
183 } catch (var e) { 187 } catch (var e) {
184 threw = true; 188 threw = true;
189
190 // Also let the callback look at it.
191 if (callback != null) {
192 var result = callback(e);
193
194 // If the callback explicitly returned false, treat that like an
195 // expectation too. (If it returns null, though, don't.)
196 if (result == false) {
197 _fail('Exception:\n$e\ndid not match expectation.');
198 }
199 }
185 } 200 }
186 Expect.equals(true, threw, 'Expected exception but none was thrown.'); 201
202 if (threw != true) _fail('An expected exception was not thrown.');
187 } 203 }
188 204
189 /** 205 /**
190 * Creates a new test case with the given description and body. The 206 * Creates a new test case with the given description and body. The
191 * description will include the descriptions of any surrounding group() 207 * description will include the descriptions of any surrounding group()
192 * calls. 208 * calls.
193 */ 209 */
194 void test(String spec, TestFunction body) { 210 void test(String spec, TestFunction body) {
195 ensureInitialized(); 211 ensureInitialized();
196 212
(...skipping 12 matching lines...) Expand all
209 final testCase = new TestCase( 225 final testCase = new TestCase(
210 _tests.length + 1, _fullSpec(spec), body, callbacks); 226 _tests.length + 1, _fullSpec(spec), body, callbacks);
211 _tests.add(testCase); 227 _tests.add(testCase);
212 228
213 if (callbacks < 1) { 229 if (callbacks < 1) {
214 testCase.error( 230 testCase.error(
215 'Async tests must wait for at least one callback ', ''); 231 'Async tests must wait for at least one callback ', '');
216 } 232 }
217 } 233 }
218 234
235 /**
236 * Creates a new test case with the given description and body. The
237 * description will include the descriptions of any surrounding group()
238 * calls.
239 *
240 * "solo_" means that this will be the only test that is run. All other tests
241 * will be skipped. This is a convenience function to let you quickly isolate
242 * a single test by adding "solo_" before it to temporarily disable all other
243 * tests.
244 */
245 void solo_test(String spec, TestFunction body) {
246 ensureInitialized();
247
248 _soloTest = new TestCase(_tests.length + 1, _fullSpec(spec), body, 0);
249 _tests.add(_soloTest);
250 }
251
219 /** Sentinel value for [_SpreadArgsHelper]. */ 252 /** Sentinel value for [_SpreadArgsHelper]. */
220 class _Sentinel { 253 class _Sentinel {
221 const _Sentinel(); 254 const _Sentinel();
222 } 255 }
223 256
224 // TODO(sigmund): make a singleton const field when frog supports passing those 257 // TODO(sigmund): make a singleton const field when frog supports passing those
225 // as default values to named arguments. 258 // as default values to named arguments.
226 final _sentinel = const _Sentinel(); 259 final _sentinel = const _Sentinel();
227 260
228 /** Simulates spread arguments using named arguments. */ 261 /** Simulates spread arguments using named arguments. */
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 final port = new ReceivePort(); 434 final port = new ReceivePort();
402 port.receive((msg, reply) { 435 port.receive((msg, reply) {
403 callback(); 436 callback();
404 port.close(); 437 port.close();
405 }); 438 });
406 port.toSendPort().send(null, null); 439 port.toSendPort().send(null, null);
407 } 440 }
408 441
409 /** Runs all queued tests, one at a time. */ 442 /** Runs all queued tests, one at a time. */
410 _runTests() { 443 _runTests() {
444 // If we are soloing a test, remove all the others.
445 if (_soloTest != null) {
446 _tests = _tests.filter((t) => t == _soloTest);
447 }
448
411 _config.onStart(); 449 _config.onStart();
412 450
413 _defer(() { 451 _defer(() {
414 assert (_currentTest == 0); 452 assert (_currentTest == 0);
415 _testRunner(); 453 _testRunner();
416 }); 454 });
417 } 455 }
418 456
419 /** 457 /**
420 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, update 458 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, update
421 * the [_currentTest] status accordingly. 459 * the [_currentTest] status accordingly.
422 */ 460 */
423 _guard(tryBody, [finallyBody]) { 461 _guard(tryBody, [finallyBody]) {
424 try { 462 try {
425 return tryBody(); 463 return tryBody();
426 } catch (ExpectException e, var trace) { 464 } catch (ExpectException e, var trace) {
427 if (_state != _UNCAUGHT_ERROR) { 465 if (_state != _UNCAUGHT_ERROR) {
428 _tests[_currentTest].fail(e.message, 466 _tests[_currentTest].fail(e.message,
429 trace == null ? '' : trace.toString()); 467 trace == null ? '' : trace.toString());
430 } 468 }
431 } catch (var e, var trace) { 469 } catch (var e, var trace) {
432 if (_state != _UNCAUGHT_ERROR) { 470 if (_state == _RUNNING_TEST) {
471 // If a random exception is thrown from within a test, we consider that
472 // a test failure too. A test case implicitly has an expectation that it
473 // will run to completion without an uncaught exception being thrown.
474 _tests[_currentTest].fail('Caught $e',
475 trace == null ? '' : trace.toString());
476 } else if (_state != _UNCAUGHT_ERROR) {
433 _tests[_currentTest].error('Caught $e', 477 _tests[_currentTest].error('Caught $e',
434 trace == null ? '' : trace.toString()); 478 trace == null ? '' : trace.toString());
435 } 479 }
436 } finally { 480 } finally {
437 _state = _READY; 481 _state = _READY;
438 if (finallyBody != null) finallyBody(); 482 if (finallyBody != null) finallyBody();
439 } 483 }
440 } 484 }
441 485
442 /** 486 /**
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 530
487 _config.onDone(testsPassed_, testsFailed_, testsErrors_, _tests, 531 _config.onDone(testsPassed_, testsFailed_, testsErrors_, _tests,
488 _uncaughtErrorMessage); 532 _uncaughtErrorMessage);
489 } 533 }
490 534
491 String _fullSpec(String spec) { 535 String _fullSpec(String spec) {
492 if (spec === null) return '$_currentGroup'; 536 if (spec === null) return '$_currentGroup';
493 return _currentGroup != '' ? '$_currentGroup $spec' : spec; 537 return _currentGroup != '' ? '$_currentGroup $spec' : spec;
494 } 538 }
495 539
540 void _fail(String message) {
541 throw new ExpectException(message);
542 }
543
496 /** 544 /**
497 * Lazily initializes the test library if not already initialized. 545 * Lazily initializes the test library if not already initialized.
498 */ 546 */
499 ensureInitialized() { 547 ensureInitialized() {
500 if (_state != _UNINITIALIZED) return; 548 if (_state != _UNINITIALIZED) return;
501 549
502 _tests = <TestCase>[]; 550 _tests = <TestCase>[];
503 _currentGroup = ''; 551 _currentGroup = '';
504 _state = _READY; 552 _state = _READY;
505 _testRunner = _nextBatch; 553 _testRunner = _nextBatch;
506 554
507 if (_config == null) { 555 if (_config == null) {
508 _config = new Configuration(); 556 _config = new Configuration();
509 } 557 }
510 _config.onInit(); 558 _config.onInit();
511 559
512 // Immediately queue the suite up. It will run after a timeout (i.e. after 560 // Immediately queue the suite up. It will run after a timeout (i.e. after
513 // main() has returned). 561 // main() has returned).
514 _defer(_runTests); 562 _defer(_runTests);
515 } 563 }
516 564
517 /** Signature for a test function. */ 565 /** Signature for a test function. */
518 typedef void TestFunction(); 566 typedef void TestFunction();
OLDNEW
« no previous file with comments | « lib/args/utils.dart ('k') | tests/lib/args/args_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698