OLD | NEW |
---|---|
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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 String _currentGroup = ''; | 212 String _currentGroup = ''; |
213 | 213 |
214 /** Separator used between group names and test names. */ | 214 /** Separator used between group names and test names. */ |
215 String groupSep = ' '; | 215 String groupSep = ' '; |
216 | 216 |
217 final List<TestCase> _testCases = new List<TestCase>(); | 217 final List<TestCase> _testCases = new List<TestCase>(); |
218 | 218 |
219 /** Tests executed in this suite. */ | 219 /** Tests executed in this suite. */ |
220 final List<TestCase> testCases = new UnmodifiableListView<TestCase>(_testCases); | 220 final List<TestCase> testCases = new UnmodifiableListView<TestCase>(_testCases); |
221 | 221 |
222 /** Setup function called before each test in a group */ | 222 /** Setup function called before each test in a group. */ |
223 Function _testSetup; | 223 Function _testSetup = null; |
224 | 224 |
225 /** Teardown function called after each test in a group */ | 225 /** Teardown function called after each test in a group. */ |
226 Function _testTeardown; | 226 Function _testTeardown = null; |
227 | |
228 /** Setup and teardown functions of parent group, for chaining. */ | |
229 Function _parentSetup = null; | |
230 Function _parentTeardown = null; | |
227 | 231 |
228 int _currentTestCaseIndex = 0; | 232 int _currentTestCaseIndex = 0; |
229 | 233 |
230 /** [TestCase] currently being executed. */ | 234 /** [TestCase] currently being executed. */ |
231 TestCase get currentTestCase => | 235 TestCase get currentTestCase => |
232 (_currentTestCaseIndex >= 0 && _currentTestCaseIndex < testCases.length) | 236 (_currentTestCaseIndex >= 0 && _currentTestCaseIndex < testCases.length) |
233 ? testCases[_currentTestCaseIndex] | 237 ? testCases[_currentTestCaseIndex] |
234 : null; | 238 : null; |
235 | 239 |
236 /** Whether the framework is in an initialized state. */ | 240 /** Whether the framework is in an initialized state. */ |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
600 final parentGroup = _currentGroup; | 604 final parentGroup = _currentGroup; |
601 if (_currentGroup != '') { | 605 if (_currentGroup != '') { |
602 // Add a space. | 606 // Add a space. |
603 _currentGroup = '$_currentGroup$groupSep$description'; | 607 _currentGroup = '$_currentGroup$groupSep$description'; |
604 } else { | 608 } else { |
605 // The first group. | 609 // The first group. |
606 _currentGroup = description; | 610 _currentGroup = description; |
607 } | 611 } |
608 | 612 |
609 // Groups can be nested, so we need to preserve the current | 613 // Groups can be nested, so we need to preserve the current |
610 // settings for test setup/teardown. | 614 // settings for test setup/teardown. We use a local copy here so we |
611 Function parentSetup = _testSetup; | 615 // can nest multiple levels; we also have the global parent variables |
612 Function parentTeardown = _testTeardown; | 616 // which are used for chaining. |
617 | |
618 Function _oldSetup = _testSetup; | |
619 Function _oldTeardown = _testTeardown; | |
620 Function _oldParentSetup = _parentSetup; | |
621 Function _oldParentTeardown = _parentTeardown; | |
622 _parentSetup = _testSetup; | |
623 _parentTeardown = _testTeardown; | |
613 | 624 |
614 try { | 625 try { |
615 _testSetup = null; | |
616 _testTeardown = null; | |
617 body(); | 626 body(); |
618 } catch (e, trace) { | 627 } catch (e, trace) { |
619 var stack = (trace == null) ? '' : ': ${trace.toString()}'; | 628 var stack = (trace == null) ? '' : ': ${trace.toString()}'; |
620 _uncaughtErrorMessage = "${e.toString()}$stack"; | 629 _uncaughtErrorMessage = "${e.toString()}$stack"; |
621 } finally { | 630 } finally { |
622 // Now that the group is over, restore the previous one. | 631 // Now that the group is over, restore the previous one. |
623 _currentGroup = parentGroup; | 632 _currentGroup = parentGroup; |
624 _testSetup = parentSetup; | 633 _testSetup = _oldSetup; |
625 _testTeardown = parentTeardown; | 634 _testTeardown = _oldTeardown; |
635 _parentSetup = _oldParentSetup; | |
636 _parentTeardown = _oldParentTeardown; | |
Siggi Cherem (dart-lang)
2013/04/19 23:55:05
now that we have 5 of these, it might be worth cre
| |
626 } | 637 } |
627 } | 638 } |
628 | 639 |
629 /** | 640 /** |
630 * Register a [setUp] function for a test [group]. This function will | 641 * Register a [setUp] function for a test [group]. This function will |
631 * be called before each test in the group is run. Note that if groups | 642 * be called before each test in the group is run. |
632 * are nested only the most locally scoped [setUpTest] function will be run. | |
633 * [setUp] and [tearDown] should be called within the [group] before any | 643 * [setUp] and [tearDown] should be called within the [group] before any |
634 * calls to [test]. The [setupTest] function can be asynchronous; in this | 644 * calls to [test]. The [setupTest] function can be asynchronous; in this |
635 * case it must return a [Future]. | 645 * case it must return a [Future]. |
636 */ | 646 */ |
637 void setUp(Function setupTest) { | 647 void setUp(Function setupTest) { |
638 _testSetup = setupTest; | 648 var parent = _parentSetup; |
649 _testSetup = () { | |
650 var f = parent == null ? null : parent(); | |
651 if (f is Future) { | |
652 return f.then((_) => setupTest()); | |
653 } else { | |
654 return setupTest(); | |
655 } | |
656 }; | |
639 } | 657 } |
640 | 658 |
641 /** | 659 /** |
642 * Register a [tearDown] function for a test [group]. This function will | 660 * Register a [tearDown] function for a test [group]. This function will |
643 * be called after each test in the group is run. Note that if groups | 661 * be called after each test in the group is run. Note that if groups |
644 * are nested only the most locally scoped [teardownTest] function will be run. | 662 * are nested only the most locally scoped [teardownTest] function will be run. |
645 * [setUp] and [tearDown] should be called within the [group] before any | 663 * [setUp] and [tearDown] should be called within the [group] before any |
646 * calls to [test]. The [teardownTest] function can be asynchronous; in this | 664 * calls to [test]. The [teardownTest] function can be asynchronous; in this |
647 * case it must return a [Future]. | 665 * case it must return a [Future]. |
648 */ | 666 */ |
649 void tearDown(Function teardownTest) { | 667 void tearDown(Function teardownTest) { |
650 _testTeardown = teardownTest; | 668 var parent = _parentTeardown; |
669 _testTeardown = () { | |
670 var f = teardownTest(); | |
671 if (parent == null) return f; | |
672 if (f is Future) { | |
673 // TODO(gram): as _parentTeardown is a global, do we need | |
674 // to first take a local copy so the value is fixed at the | |
675 // point that tearDown is called? | |
676 return f.then((_) => parent()); | |
677 } else { | |
678 return parent(); | |
679 } | |
680 }; | |
651 } | 681 } |
652 | 682 |
653 /** Advance to the next test case. */ | 683 /** Advance to the next test case. */ |
654 void _nextTestCase() { | 684 void _nextTestCase() { |
655 _defer(() { | 685 _defer(() { |
656 _currentTestCaseIndex++; | 686 _currentTestCaseIndex++; |
657 _nextBatch(); | 687 _nextBatch(); |
658 }); | 688 }); |
659 } | 689 } |
660 | 690 |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
870 } | 900 } |
871 | 901 |
872 /** Enable a test by ID. */ | 902 /** Enable a test by ID. */ |
873 void enableTest(int testId) => _setTestEnabledState(testId, true); | 903 void enableTest(int testId) => _setTestEnabledState(testId, true); |
874 | 904 |
875 /** Disable a test by ID. */ | 905 /** Disable a test by ID. */ |
876 void disableTest(int testId) => _setTestEnabledState(testId, false); | 906 void disableTest(int testId) => _setTestEnabledState(testId, false); |
877 | 907 |
878 /** Signature for a test function. */ | 908 /** Signature for a test function. */ |
879 typedef dynamic TestFunction(); | 909 typedef dynamic TestFunction(); |
OLD | NEW |