Index: pkg/unittest/lib/unittest.dart |
=================================================================== |
--- pkg/unittest/lib/unittest.dart (revision 21778) |
+++ pkg/unittest/lib/unittest.dart (working copy) |
@@ -219,12 +219,16 @@ |
/** Tests executed in this suite. */ |
final List<TestCase> testCases = new UnmodifiableListView<TestCase>(_testCases); |
-/** Setup function called before each test in a group */ |
-Function _testSetup; |
+/** Setup function called before each test in a group. */ |
+Function _testSetup = null; |
-/** Teardown function called after each test in a group */ |
-Function _testTeardown; |
+/** Teardown function called after each test in a group. */ |
+Function _testTeardown = null; |
+/** Setup and teardown functions of parent group, for chaining. */ |
+Function _parentSetup = null; |
+Function _parentTeardown = null; |
+ |
int _currentTestCaseIndex = 0; |
/** [TestCase] currently being executed. */ |
@@ -607,13 +611,18 @@ |
} |
// Groups can be nested, so we need to preserve the current |
- // settings for test setup/teardown. |
- Function parentSetup = _testSetup; |
- Function parentTeardown = _testTeardown; |
+ // settings for test setup/teardown. We use a local copy here so we |
+ // can nest multiple levels; we also have the global parent variables |
+ // which are used for chaining. |
+ Function _oldSetup = _testSetup; |
+ Function _oldTeardown = _testTeardown; |
+ Function _oldParentSetup = _parentSetup; |
+ Function _oldParentTeardown = _parentTeardown; |
+ _parentSetup = _testSetup; |
+ _parentTeardown = _testTeardown; |
+ |
try { |
- _testSetup = null; |
- _testTeardown = null; |
body(); |
} catch (e, trace) { |
var stack = (trace == null) ? '' : ': ${trace.toString()}'; |
@@ -621,21 +630,30 @@ |
} finally { |
// Now that the group is over, restore the previous one. |
_currentGroup = parentGroup; |
- _testSetup = parentSetup; |
- _testTeardown = parentTeardown; |
+ _testSetup = _oldSetup; |
+ _testTeardown = _oldTeardown; |
+ _parentSetup = _oldParentSetup; |
+ _parentTeardown = _oldParentTeardown; |
Siggi Cherem (dart-lang)
2013/04/19 23:55:05
now that we have 5 of these, it might be worth cre
|
} |
} |
/** |
* Register a [setUp] function for a test [group]. This function will |
- * be called before each test in the group is run. Note that if groups |
- * are nested only the most locally scoped [setUpTest] function will be run. |
+ * be called before each test in the group is run. |
* [setUp] and [tearDown] should be called within the [group] before any |
* calls to [test]. The [setupTest] function can be asynchronous; in this |
* case it must return a [Future]. |
*/ |
void setUp(Function setupTest) { |
- _testSetup = setupTest; |
+ var parent = _parentSetup; |
+ _testSetup = () { |
+ var f = parent == null ? null : parent(); |
+ if (f is Future) { |
+ return f.then((_) => setupTest()); |
+ } else { |
+ return setupTest(); |
+ } |
+ }; |
} |
/** |
@@ -647,7 +665,19 @@ |
* case it must return a [Future]. |
*/ |
void tearDown(Function teardownTest) { |
- _testTeardown = teardownTest; |
+ var parent = _parentTeardown; |
+ _testTeardown = () { |
+ var f = teardownTest(); |
+ if (parent == null) return f; |
+ if (f is Future) { |
+ // TODO(gram): as _parentTeardown is a global, do we need |
+ // to first take a local copy so the value is fixed at the |
+ // point that tearDown is called? |
+ return f.then((_) => parent()); |
+ } else { |
+ return parent(); |
+ } |
+ }; |
} |
/** Advance to the next test case. */ |