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

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

Issue 142023005: throw when group or test is called while unittest system is running (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: updated version file Created 6 years, 10 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/pubspec.yaml » ('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 * Support for writing Dart unit tests. 6 * Support for writing Dart unit tests.
7 * 7 *
8 * For information on installing and importing this library, see the 8 * For information on installing and importing this library, see the
9 * [unittest package on pub.dartlang.org] 9 * [unittest package on pub.dartlang.org]
10 * (http://pub.dartlang.org/packages/unittest). 10 * (http://pub.dartlang.org/packages/unittest).
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 _testTeardown = parentTeardown; 272 _testTeardown = parentTeardown;
273 } 273 }
274 } 274 }
275 275
276 // We use a 'dummy' context for the top level to eliminate null 276 // We use a 'dummy' context for the top level to eliminate null
277 // checks when querying the context. This allows us to easily 277 // checks when querying the context. This allows us to easily
278 // support top-level setUp/tearDown functions as well. 278 // support top-level setUp/tearDown functions as well.
279 final _rootContext = new _GroupContext(); 279 final _rootContext = new _GroupContext();
280 _GroupContext _currentContext = _rootContext; 280 _GroupContext _currentContext = _rootContext;
281 281
282 int _currentTestCaseIndex = 0; 282 int _currentTestCaseIndex = -1;
283 283
284 /** [TestCase] currently being executed. */ 284 /** [TestCase] currently being executed. */
285 TestCase get currentTestCase => 285 TestCase get currentTestCase =>
286 (_currentTestCaseIndex >= 0 && _currentTestCaseIndex < testCases.length) 286 (_currentTestCaseIndex >= 0 && _currentTestCaseIndex < testCases.length)
287 ? testCases[_currentTestCaseIndex] 287 ? testCases[_currentTestCaseIndex]
288 : null; 288 : null;
289 289
290 /** Whether the framework is in an initialized state. */ 290 /** Whether the framework is in an initialized state. */
291 bool _initialized = false; 291 bool _initialized = false;
292 292
(...skipping 13 matching lines...) Expand all
306 const FAIL = 'fail'; 306 const FAIL = 'fail';
307 /// Result string for an test case with an error. 307 /// Result string for an test case with an error.
308 const ERROR = 'error'; 308 const ERROR = 'error';
309 309
310 /** 310 /**
311 * Creates a new test case with the given description and body. The 311 * Creates a new test case with the given description and body. The
312 * description will include the descriptions of any surrounding group() 312 * description will include the descriptions of any surrounding group()
313 * calls. 313 * calls.
314 */ 314 */
315 void test(String spec, TestFunction body) { 315 void test(String spec, TestFunction body) {
316 _requireNotRunning();
316 ensureInitialized(); 317 ensureInitialized();
317 if (!_soloTestSeen || _soloNestingLevel > 0) { 318 if (!_soloTestSeen || _soloNestingLevel > 0) {
318 var testcase = new TestCase._internal(testCases.length + 1, _fullSpec(spec), 319 var testcase = new TestCase._internal(testCases.length + 1, _fullSpec(spec),
319 body); 320 body);
320 _testCases.add(testcase); 321 _testCases.add(testcase);
321 } 322 }
322 } 323 }
323 324
324 /** Convenience function for skipping a test. */ 325 /** Convenience function for skipping a test. */
325 void skip_test(String spec, TestFunction body){} 326 void skip_test(String spec, TestFunction body){}
326 327
327 /** 328 /**
328 * Creates a new test case with the given description and body. The 329 * Creates a new test case with the given description and body. The
329 * description will include the descriptions of any surrounding group() 330 * description will include the descriptions of any surrounding group()
330 * calls. 331 * calls.
331 * 332 *
332 * If we use [solo_test] (or [solo_group]) instead of test, then all non-solo 333 * If we use [solo_test] (or [solo_group]) instead of test, then all non-solo
333 * tests will be disabled. Note that if we use [solo_group], all tests in 334 * tests will be disabled. Note that if we use [solo_group], all tests in
334 * the group will be enabled, regardless of whether they use [test] or 335 * the group will be enabled, regardless of whether they use [test] or
335 * [solo_test], or whether they are in a nested [group] vs [solo_group]. Put 336 * [solo_test], or whether they are in a nested [group] vs [solo_group]. Put
336 * another way, if there are any calls to [solo_test] or [solo_group] in a test 337 * another way, if there are any calls to [solo_test] or [solo_group] in a test
337 * file, all tests that are not inside a [solo_group] will be disabled unless 338 * file, all tests that are not inside a [solo_group] will be disabled unless
338 * they are [solo_test]s. 339 * they are [solo_test]s.
339 * 340 *
340 * [skip_test] and [skip_group] take precedence over soloing, by virtue of the 341 * [skip_test] and [skip_group] take precedence over soloing, by virtue of the
341 * fact that they are effectively no-ops. 342 * fact that they are effectively no-ops.
342 */ 343 */
343 void solo_test(String spec, TestFunction body) { 344 void solo_test(String spec, TestFunction body) {
345 _requireNotRunning();
344 ensureInitialized(); 346 ensureInitialized();
345 if (!_soloTestSeen) { 347 if (!_soloTestSeen) {
346 _soloTestSeen = true; 348 _soloTestSeen = true;
347 // This is the first solo-ed test. Discard all tests up to now. 349 // This is the first solo-ed test. Discard all tests up to now.
348 _testCases.clear(); 350 _testCases.clear();
349 } 351 }
350 ++_soloNestingLevel; 352 ++_soloNestingLevel;
351 try { 353 try {
352 test(spec, body); 354 test(spec, body);
353 } finally { 355 } finally {
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 Function protectAsync2(Function callback, {String id}) { 579 Function protectAsync2(Function callback, {String id}) {
578 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke2; 580 return new _SpreadArgsHelper(callback, 0, -1, null, id).invoke2;
579 } 581 }
580 582
581 /** 583 /**
582 * Creates a new named group of tests. Calls to group() or test() within the 584 * Creates a new named group of tests. Calls to group() or test() within the
583 * body of the function passed to this will inherit this group's description. 585 * body of the function passed to this will inherit this group's description.
584 */ 586 */
585 void group(String description, void body()) { 587 void group(String description, void body()) {
586 ensureInitialized(); 588 ensureInitialized();
589 _requireNotRunning();
587 _currentContext = new _GroupContext(_currentContext, description); 590 _currentContext = new _GroupContext(_currentContext, description);
588 try { 591 try {
589 body(); 592 body();
590 } catch (e, trace) { 593 } catch (e, trace) {
591 var stack = (trace == null) ? '' : ': ${trace.toString()}'; 594 var stack = (trace == null) ? '' : ': ${trace.toString()}';
592 _uncaughtErrorMessage = "${e.toString()}$stack"; 595 _uncaughtErrorMessage = "${e.toString()}$stack";
593 } finally { 596 } finally {
594 // Now that the group is over, restore the previous one. 597 // Now that the group is over, restore the previous one.
595 _currentContext = _currentContext.parent; 598 _currentContext = _currentContext.parent;
596 } 599 }
597 } 600 }
598 601
599 /** Like [skip_test], but for groups. */ 602 /** Like [skip_test], but for groups. */
600 void skip_group(String description, void body()) {} 603 void skip_group(String description, void body()) {}
601 604
602 /** Like [solo_test], but for groups. */ 605 /** Like [solo_test], but for groups. */
603 void solo_group(String description, void body()) { 606 void solo_group(String description, void body()) {
607 _requireNotRunning();
604 ensureInitialized(); 608 ensureInitialized();
605 if (!_soloTestSeen) { 609 if (!_soloTestSeen) {
606 _soloTestSeen = true; 610 _soloTestSeen = true;
607 // This is the first solo-ed group. Discard all tests up to now. 611 // This is the first solo-ed group. Discard all tests up to now.
608 _testCases.clear(); 612 _testCases.clear();
609 } 613 }
610 ++_soloNestingLevel; 614 ++_soloNestingLevel;
611 try { 615 try {
612 group(description, body); 616 group(description, body);
613 } finally { 617 } finally {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 } else if (testFilter is RegExp) { 680 } else if (testFilter is RegExp) {
677 filterFunction = (t) => testFilter.hasMatch(t.description); 681 filterFunction = (t) => testFilter.hasMatch(t.description);
678 } else if (testFilter is Function) { 682 } else if (testFilter is Function) {
679 filterFunction = testFilter; 683 filterFunction = testFilter;
680 } 684 }
681 _testCases.retainWhere(filterFunction); 685 _testCases.retainWhere(filterFunction);
682 } 686 }
683 687
684 /** Runs all queued tests, one at a time. */ 688 /** Runs all queued tests, one at a time. */
685 void runTests() { 689 void runTests() {
690 _requireNotRunning();
686 _ensureInitialized(false); 691 _ensureInitialized(false);
687 _currentTestCaseIndex = 0; 692 _currentTestCaseIndex = 0;
688 _config.onStart(); 693 _config.onStart();
689 _runTest(); 694 _runTest();
690 } 695 }
691 696
692 /** 697 /**
693 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, it is 698 * Run [tryBody] guarded in a try-catch block. If an exception is thrown, it is
694 * passed to the corresponding test. 699 * passed to the corresponding test.
695 * 700 *
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 } else { 732 } else {
728 testCase.error(message, trace); 733 testCase.error(message, trace);
729 } 734 }
730 } 735 }
731 736
732 /** 737 /**
733 * Runs the next test. 738 * Runs the next test.
734 */ 739 */
735 void _runTest() { 740 void _runTest() {
736 if (_currentTestCaseIndex >= testCases.length) { 741 if (_currentTestCaseIndex >= testCases.length) {
742 assert(_currentTestCaseIndex == testCases.length);
737 _completeTests(); 743 _completeTests();
738 } else { 744 } else {
739 final testCase = testCases[_currentTestCaseIndex]; 745 var testCase = testCases[_currentTestCaseIndex];
740 var f = _guardAsync(testCase._run, null, testCase); 746 Future f = _guardAsync(testCase._run, null, testCase);
747 var timeout = unittestConfiguration.timeout;
Emily Fortuna 2014/01/30 23:32:15 any reason why these aren't final anymore? NBD, j
kevmoo 2014/01/30 23:42:04 it's against our guidelines. I had a crazy hang-u
748
741 Timer timer; 749 Timer timer;
742 final Duration timeout = unittestConfiguration.timeout;
743 if (timeout != null) { 750 if (timeout != null) {
744 try { 751 try {
745 timer = new Timer(timeout, () { 752 timer = new Timer(timeout, () {
746 testCase.error("Test timed out after ${timeout.inSeconds} seconds."); 753 testCase.error("Test timed out after ${timeout.inSeconds} seconds.");
747 _nextTestCase(); 754 _nextTestCase();
748 }); 755 });
749 } on UnsupportedError catch (e) { 756 } on UnsupportedError catch (e) {
750 if (e.message != "Timer greater than 0.") rethrow; 757 if (e.message != "Timer greater than 0.") rethrow;
751 // Support running on d8 and jsshell which don't support timers. 758 // Support running on d8 and jsshell which don't support timers.
752 } 759 }
(...skipping 22 matching lines...) Expand all
775 switch (t.result) { 782 switch (t.result) {
776 case PASS: passed++; break; 783 case PASS: passed++; break;
777 case FAIL: failed++; break; 784 case FAIL: failed++; break;
778 case ERROR: errors++; break; 785 case ERROR: errors++; break;
779 } 786 }
780 } 787 }
781 _config.onSummary(passed, failed, errors, testCases, _uncaughtErrorMessage); 788 _config.onSummary(passed, failed, errors, testCases, _uncaughtErrorMessage);
782 _config.onDone(passed > 0 && failed == 0 && errors == 0 && 789 _config.onDone(passed > 0 && failed == 0 && errors == 0 &&
783 _uncaughtErrorMessage == null); 790 _uncaughtErrorMessage == null);
784 _initialized = false; 791 _initialized = false;
792 _currentTestCaseIndex = -1;
785 } 793 }
786 794
787 String _fullSpec(String spec) { 795 String _fullSpec(String spec) {
788 var group = '${_currentContext.fullName}'; 796 var group = '${_currentContext.fullName}';
789 if (spec == null) return group; 797 if (spec == null) return group;
790 return group != '' ? '$group$groupSep$spec' : spec; 798 return group != '' ? '$group$groupSep$spec' : spec;
791 } 799 }
792 800
793 /** 801 /**
794 * Lazily initializes the test library if not already initialized. 802 * Lazily initializes the test library if not already initialized.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 * Useful to disable when debugging unittest or matcher customizations. 859 * Useful to disable when debugging unittest or matcher customizations.
852 */ 860 */
853 bool formatStacks = true; 861 bool formatStacks = true;
854 862
855 /** 863 /**
856 * A flag that controls whether we try to filter out irrelevant frames from 864 * A flag that controls whether we try to filter out irrelevant frames from
857 * the stack trace. Requires formatStacks to be set. 865 * the stack trace. Requires formatStacks to be set.
858 */ 866 */
859 bool filterStacks = true; 867 bool filterStacks = true;
860 868
869 void _requireNotRunning() {
870 if(_currentTestCaseIndex != -1) {
871 throw new StateError('Not allowed when tests are running.');
872 }
873 }
874
861 /** 875 /**
862 * Returns a Trace object from a StackTrace object or a String, or the 876 * Returns a Trace object from a StackTrace object or a String, or the
863 * unchanged input if formatStacks is false; 877 * unchanged input if formatStacks is false;
864 */ 878 */
865 Trace _getTrace(stack) { 879 Trace _getTrace(stack) {
866 Trace trace; 880 Trace trace;
867 if (stack == null || !formatStacks) return null; 881 if (stack == null || !formatStacks) return null;
868 if (stack is String) { 882 if (stack is String) {
869 trace = new Trace.parse(stack); 883 trace = new Trace.parse(stack);
870 } else if (stack is StackTrace) { 884 } else if (stack is StackTrace) {
871 trace = new Trace.from(stack); 885 trace = new Trace.from(stack);
872 } else { 886 } else {
873 throw new Exception('Invalid stack type ${stack.runtimeType} for $stack.'); 887 throw new Exception('Invalid stack type ${stack.runtimeType} for $stack.');
874 } 888 }
875 889
876 if (!filterStacks) return trace; 890 if (!filterStacks) return trace;
877 891
878 // Format the stack trace by removing everything above TestCase._runTest, 892 // Format the stack trace by removing everything above TestCase._runTest,
879 // which is usually going to be irrelevant. Also fold together unittest and 893 // which is usually going to be irrelevant. Also fold together unittest and
880 // core library calls so only the function the user called is visible. 894 // core library calls so only the function the user called is visible.
881 return new Trace(trace.frames.takeWhile((frame) { 895 return new Trace(trace.frames.takeWhile((frame) {
882 return frame.package != 'unittest' || frame.member != 'TestCase._runTest'; 896 return frame.package != 'unittest' || frame.member != 'TestCase._runTest';
883 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore); 897 })).terse.foldFrames((frame) => frame.package == 'unittest' || frame.isCore);
884 } 898 }
OLDNEW
« no previous file with comments | « no previous file | pkg/unittest/pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698