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

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 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 runAsync(() {
648 _currentTestCaseIndex++; 657 _currentTestCaseIndex++;
649 _nextBatch(); 658 _nextTest();
650 }); 659 });
651 } 660 }
652 661
653 /** 662 /**
654 * Utility function that can be used to notify the test framework that an 663 * Utility function that can be used to notify the test framework that an
655 * error was caught outside of this library. 664 * error was caught outside of this library.
656 */ 665 */
657 void _reportTestError(String msg, trace) { 666 void _reportTestError(String msg, trace) {
658 if (_currentTestCaseIndex < testCases.length) { 667 if (_currentTestCaseIndex < testCases.length) {
659 final testCase = testCases[_currentTestCaseIndex]; 668 final testCase = testCases[_currentTestCaseIndex];
(...skipping 28 matching lines...) Expand all
688 } 697 }
689 698
690 /** Runs all queued tests, one at a time. */ 699 /** Runs all queued tests, one at a time. */
691 void runTests() { 700 void runTests() {
692 _ensureInitialized(false); 701 _ensureInitialized(false);
693 _currentTestCaseIndex = 0; 702 _currentTestCaseIndex = 0;
694 703
695 _config.onStart(); 704 _config.onStart();
696 705
697 runAsync(() { 706 runAsync(() {
698 _nextBatch(); 707 _nextTest();
699 }); 708 });
700 } 709 }
701 710
702 /** 711 /**
703 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, it is 712 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, it is
704 * passed to the corresponding test. 713 * passed to the corresponding test.
705 * 714 *
706 * The value returned by [tryBody] (if any) is returned by [guardAsync]. 715 * The value returned by [tryBody] (if any) is returned by [guardAsync].
707 */ 716 */
708 guardAsync(Function tryBody) { 717 guardAsync(Function tryBody) {
(...skipping 24 matching lines...) Expand all
733 void _registerException(TestCase testCase, e, [trace]) { 742 void _registerException(TestCase testCase, e, [trace]) {
734 String message = (e is TestFailure) ? e.message : 'Caught $e'; 743 String message = (e is TestFailure) ? e.message : 'Caught $e';
735 if (testCase.result == null) { 744 if (testCase.result == null) {
736 testCase.fail(message, trace); 745 testCase.fail(message, trace);
737 } else { 746 } else {
738 testCase.error(message, trace); 747 testCase.error(message, trace);
739 } 748 }
740 } 749 }
741 750
742 /** 751 /**
743 * Runs a batch of tests, yielding whenever an asynchronous test starts 752 * 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 */ 753 */
747 void _nextBatch() { 754 void _nextTest() {
748 while (true) { 755 if (_currentTestCaseIndex >= testCases.length) {
749 if (_currentTestCaseIndex >= testCases.length) { 756 _completeTests();
750 _completeTests(); 757 } else {
751 break;
752 }
753 final testCase = testCases[_currentTestCaseIndex]; 758 final testCase = testCases[_currentTestCaseIndex];
754 var f = _guardAsync(testCase._run, null, testCase); 759 var f = _guardAsync(testCase._run, null, testCase);
755 if (f != null) { 760 f.whenComplete(() {
756 f.whenComplete(() { 761 var now = new DateTime.now().millisecondsSinceEpoch;
762 if ((now - _lastBreath) >= BREATH_INTERVAL) {
Siggi Cherem (dart-lang) 2013/07/24 23:34:06 consider moving this test up to _nextTestCase? the
gram 2013/07/24 23:54:52 _nextTestCase first increments the counter so ther
Siggi Cherem (dart-lang) 2013/07/25 00:13:09 basically it seems strange that we do runAsync on
gram 2013/07/25 00:33:22 Done.
763 _lastBreath = now;
764 new Future(_nextTestCase);
Siggi Cherem (dart-lang) 2013/07/24 23:34:06 isn't this the same as runAsync(_nextTestCase). I
gram 2013/07/24 23:54:52 Done.
765 } else {
757 _nextTestCase(); // Schedule the next test. 766 _nextTestCase(); // Schedule the next test.
758 }); 767 }
759 break; 768 });
760 }
761 _currentTestCaseIndex++;
762 } 769 }
763 } 770 }
764 771
765 /** Publish results on the page and notify controller. */ 772 /** Publish results on the page and notify controller. */
766 void _completeTests() { 773 void _completeTests() {
767 if (!_initialized) return; 774 if (!_initialized) return;
768 int passed = 0; 775 int passed = 0;
769 int failed = 0; 776 int failed = 0;
770 int errors = 0; 777 int errors = 0;
771 778
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 871
865 if (!formatStacks) return trace; 872 if (!formatStacks) return trace;
866 873
867 // Format the stack trace by removing everything above TestCase._runTest, 874 // Format the stack trace by removing everything above TestCase._runTest,
868 // which is usually going to be irrelevant. Also fold together unittest and 875 // 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. 876 // core library calls so only the function the user called is visible.
870 return new Trace(trace.frames.takeWhile((frame) { 877 return new Trace(trace.frames.takeWhile((frame) {
871 return frame.package != 'unittest' || frame.member != 'TestCase._runTest'; 878 return frame.package != 'unittest' || frame.member != 'TestCase._runTest';
872 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore); 879 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore);
873 } 880 }
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