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

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

Issue 20115007: Added a way to let the outer event loop run periodically so that things like (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/test/breath_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) 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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 193
194 /** Separator used between group names and test names. */ 194 /** Separator used between group names and test names. */
195 String groupSep = ' '; 195 String groupSep = ' ';
196 196
197 final List<TestCase> _testCases = new List<TestCase>(); 197 final List<TestCase> _testCases = new List<TestCase>();
198 198
199 /** Tests executed in this suite. */ 199 /** Tests executed in this suite. */
200 final List<TestCase> testCases = new UnmodifiableListView<TestCase>(_testCases); 200 final List<TestCase> testCases = new UnmodifiableListView<TestCase>(_testCases);
201 201
202 /** 202 /**
203 * Interval (in msecs) after which synchronous tests will insert an async
204 * delay to allow DOM or other updates.
205 */
206 const int BREATH_INTERVAL = 200;
207
208 /**
203 * The set of tests to run can be restricted by using [solo_test] and 209 * The set of tests to run can be restricted by using [solo_test] and
204 * [solo_group]. 210 * [solo_group].
205 * As groups can be nested we use a counter to keep track of the nest level 211 * As groups can be nested we use a counter to keep track of the nest level
206 * of soloing, and a flag to tell if we have seen any solo tests. 212 * of soloing, and a flag to tell if we have seen any solo tests.
207 */ 213 */
208 int _soloNestingLevel = 0; 214 int _soloNestingLevel = 0;
209 bool _soloTestSeen = false; 215 bool _soloTestSeen = false;
210 216
211 /** 217 /**
212 * Setup and teardown functions for a group and its parents, the latter 218 * Setup and teardown functions for a group and its parents, the latter
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 TestCase get currentTestCase => 292 TestCase get currentTestCase =>
287 (_currentTestCaseIndex >= 0 && _currentTestCaseIndex < testCases.length) 293 (_currentTestCaseIndex >= 0 && _currentTestCaseIndex < testCases.length)
288 ? testCases[_currentTestCaseIndex] 294 ? testCases[_currentTestCaseIndex]
289 : null; 295 : null;
290 296
291 /** Whether the framework is in an initialized state. */ 297 /** Whether the framework is in an initialized state. */
292 bool _initialized = false; 298 bool _initialized = false;
293 299
294 String _uncaughtErrorMessage = null; 300 String _uncaughtErrorMessage = null;
295 301
302 /** Time since we last gave non-sync code a chance to be scheduled. */
303 int _lastBreath = new DateTime.now().millisecondsSinceEpoch;
304
296 /** Test case result strings. */ 305 /** Test case result strings. */
297 // TODO(gram) we should change these constants to use a different string 306 // TODO(gram) we should change these constants to use a different string
298 // (so that writing 'FAIL' in the middle of a test doesn't 307 // (so that writing 'FAIL' in the middle of a test doesn't
299 // imply that the test fails). We can't do it without also changing 308 // imply that the test fails). We can't do it without also changing
300 // the testrunner and test.dart though. 309 // the testrunner and test.dart though.
301 const PASS = 'pass'; 310 const PASS = 'pass';
302 const FAIL = 'fail'; 311 const FAIL = 'fail';
303 const ERROR = 'error'; 312 const ERROR = 'error';
304 313
305 /** 314 /**
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 * [setUp] and [tearDown] should be called within the [group] before any 646 * [setUp] and [tearDown] should be called within the [group] before any
638 * calls to [test]. The [teardownTest] function can be asynchronous; in this 647 * calls to [test]. The [teardownTest] function can be asynchronous; in this
639 * case it must return a [Future]. 648 * case it must return a [Future].
640 */ 649 */
641 void tearDown(Function teardownTest) { 650 void tearDown(Function teardownTest) {
642 _currentContext.testTeardown = teardownTest; 651 _currentContext.testTeardown = teardownTest;
643 } 652 }
644 653
645 /** Advance to the next test case. */ 654 /** Advance to the next test case. */
646 void _nextTestCase() { 655 void _nextTestCase() {
647 runAsync(() { 656 _currentTestCaseIndex++;
648 _currentTestCaseIndex++; 657 _runTest();
649 _nextBatch();
650 });
651 } 658 }
652 659
653 /** 660 /**
654 * Utility function that can be used to notify the test framework that an 661 * Utility function that can be used to notify the test framework that an
655 * error was caught outside of this library. 662 * error was caught outside of this library.
656 */ 663 */
657 void _reportTestError(String msg, trace) { 664 void _reportTestError(String msg, trace) {
658 if (_currentTestCaseIndex < testCases.length) { 665 if (_currentTestCaseIndex < testCases.length) {
659 final testCase = testCases[_currentTestCaseIndex]; 666 final testCase = testCases[_currentTestCaseIndex];
660 testCase.error(msg, trace); 667 testCase.error(msg, trace);
(...skipping 23 matching lines...) Expand all
684 } else if (testFilter is Function) { 691 } else if (testFilter is Function) {
685 filterFunction = testFilter; 692 filterFunction = testFilter;
686 } 693 }
687 _testCases.retainWhere(filterFunction); 694 _testCases.retainWhere(filterFunction);
688 } 695 }
689 696
690 /** Runs all queued tests, one at a time. */ 697 /** Runs all queued tests, one at a time. */
691 void runTests() { 698 void runTests() {
692 _ensureInitialized(false); 699 _ensureInitialized(false);
693 _currentTestCaseIndex = 0; 700 _currentTestCaseIndex = 0;
694
695 _config.onStart(); 701 _config.onStart();
696 702 _runTest();
Siggi Cherem (dart-lang) 2013/07/25 00:50:42 I think this one needs to still call runAsync?
697 runAsync(() {
698 _nextBatch();
699 });
700 } 703 }
701 704
702 /** 705 /**
703 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, it is 706 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, it is
704 * passed to the corresponding test. 707 * passed to the corresponding test.
705 * 708 *
706 * The value returned by [tryBody] (if any) is returned by [guardAsync]. 709 * The value returned by [tryBody] (if any) is returned by [guardAsync].
707 */ 710 */
708 guardAsync(Function tryBody) { 711 guardAsync(Function tryBody) {
709 return _guardAsync(tryBody, null, currentTestCase); 712 return _guardAsync(tryBody, null, currentTestCase);
(...skipping 23 matching lines...) Expand all
733 void _registerException(TestCase testCase, e, [trace]) { 736 void _registerException(TestCase testCase, e, [trace]) {
734 String message = (e is TestFailure) ? e.message : 'Caught $e'; 737 String message = (e is TestFailure) ? e.message : 'Caught $e';
735 if (testCase.result == null) { 738 if (testCase.result == null) {
736 testCase.fail(message, trace); 739 testCase.fail(message, trace);
737 } else { 740 } else {
738 testCase.error(message, trace); 741 testCase.error(message, trace);
739 } 742 }
740 } 743 }
741 744
742 /** 745 /**
743 * Runs a batch of tests, yielding whenever an asynchronous test starts 746 * Runs the next test.
744 * running. Tests will resume executing when such asynchronous test calls
745 * [done] or if it fails with an exception.
746 */ 747 */
747 void _nextBatch() { 748 void _runTest() {
748 while (true) { 749 if (_currentTestCaseIndex >= testCases.length) {
749 if (_currentTestCaseIndex >= testCases.length) { 750 _completeTests();
750 _completeTests(); 751 } else {
751 break;
752 }
753 final testCase = testCases[_currentTestCaseIndex]; 752 final testCase = testCases[_currentTestCaseIndex];
754 var f = _guardAsync(testCase._run, null, testCase); 753 var f = _guardAsync(testCase._run, null, testCase);
755 if (f != null) { 754 f.whenComplete(() {
756 f.whenComplete(() { 755 var now = new DateTime.now().millisecondsSinceEpoch;
757 _nextTestCase(); // Schedule the next test. 756 if ((now - _lastBreath) >= BREATH_INTERVAL) {
758 }); 757 _lastBreath = now;
759 break; 758 Timer.run(_nextTestCase);
760 } 759 } else {
761 _currentTestCaseIndex++; 760 runAsync(_nextTestCase); // Schedule the next test.
761 }
762 });
762 } 763 }
763 } 764 }
764 765
765 /** Publish results on the page and notify controller. */ 766 /** Publish results on the page and notify controller. */
766 void _completeTests() { 767 void _completeTests() {
767 if (!_initialized) return; 768 if (!_initialized) return;
768 int passed = 0; 769 int passed = 0;
769 int failed = 0; 770 int failed = 0;
770 int errors = 0; 771 int errors = 0;
771 772
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 865
865 if (!formatStacks) return trace; 866 if (!formatStacks) return trace;
866 867
867 // Format the stack trace by removing everything above TestCase._runTest, 868 // Format the stack trace by removing everything above TestCase._runTest,
868 // which is usually going to be irrelevant. Also fold together unittest and 869 // which is usually going to be irrelevant. Also fold together unittest and
869 // core library calls so only the function the user called is visible. 870 // core library calls so only the function the user called is visible.
870 return new Trace(trace.frames.takeWhile((frame) { 871 return new Trace(trace.frames.takeWhile((frame) {
871 return frame.package != 'unittest' || frame.member != 'TestCase._runTest'; 872 return frame.package != 'unittest' || frame.member != 'TestCase._runTest';
872 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore); 873 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore);
873 } 874 }
OLDNEW
« no previous file with comments | « no previous file | pkg/unittest/test/breath_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698