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

Unified Diff: pkg/unittest/lib/unittest.dart

Issue 13973021: Retrying the setUp/tearDown chaining change. This is the same as r21819 but with a change to schedu… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/unittest/lib/src/test_case.dart ('k') | pkg/unittest/test/unittest_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/unittest/lib/unittest.dart
===================================================================
--- pkg/unittest/lib/unittest.dart (revision 21853)
+++ pkg/unittest/lib/unittest.dart (working copy)
@@ -205,12 +205,6 @@
void logMessage(String message) =>
_config.onLogMessage(currentTestCase, message);
-/**
- * Description text of the current test group. If multiple groups are nested,
- * this will contain all of their text concatenated.
- */
-String _currentGroup = '';
-
/** Separator used between group names and test names. */
String groupSep = ' ';
@@ -219,12 +213,78 @@
/** 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 and teardown functions for a group and its parents, the latter
+ * for chaining.
+ */
+class GroupContext {
+ final GroupContext parent;
-/** Teardown function called after each test in a group */
-Function _testTeardown;
+ /** Description text of the current test group. */
+ final String _name;
+ /** Setup function called before each test in a group. */
+ Function _testSetup;
+
+ get testSetup => _testSetup;
+
+ get parentSetup => (parent == null) ? null : parent.testSetup;
+
+ set testSetup(Function setup) {
+ var preSetup = parentSetup;
+ if (preSetup == null) {
+ _testSetup = setup;
+ } else {
+ _testSetup = () {
+ var f = preSetup();
+ if (f is Future) {
+ return f.then((_) => setup());
+ } else {
+ return setup();
+ }
+ };
+ }
+ }
+
+ /** Teardown function called after each test in a group. */
+ Function _testTeardown;
+
+ get testTeardown => _testTeardown;
+
+ get parentTeardown => (parent == null) ? null : parent.testTeardown;
+
+ set testTeardown(Function teardown) {
+ var postTeardown = parentTeardown;
+ if (postTeardown == null) {
+ _testTeardown = teardown;
+ } else {
+ _testTeardown = () {
+ var f = teardown();
+ if (f is Future) {
+ return f.then((_) => postTeardown());
+ } else {
+ return postTeardown();
+ }
+ };
+ }
+ }
+
+ String get fullName => (parent == null || parent == _rootContext)
+ ? _name
+ : "${parent.fullName}$groupSep$_name";
+
+ GroupContext([this.parent, this._name = '']) {
+ _testSetup = parentSetup;
+ _testTeardown = parentTeardown;
+ }
+}
+
+// We use a 'dummy' context for the top level to eliminate null
+// checks when querying the context. This allows us to easily
+// support top-level setUp/tearDown functions as well.
+GroupContext _rootContext = new GroupContext();
+GroupContext _currentContext = _rootContext;
+
int _currentTestCaseIndex = 0;
/** [TestCase] currently being executed. */
@@ -596,46 +656,27 @@
*/
void group(String description, void body()) {
ensureInitialized();
- // Concatenate the new group.
- final parentGroup = _currentGroup;
- if (_currentGroup != '') {
- // Add a space.
- _currentGroup = '$_currentGroup$groupSep$description';
- } else {
- // The first group.
- _currentGroup = description;
- }
-
- // Groups can be nested, so we need to preserve the current
- // settings for test setup/teardown.
- Function parentSetup = _testSetup;
- Function parentTeardown = _testTeardown;
-
+ _currentContext = new GroupContext(_currentContext, description);
try {
- _testSetup = null;
- _testTeardown = null;
body();
} catch (e, trace) {
var stack = (trace == null) ? '' : ': ${trace.toString()}';
_uncaughtErrorMessage = "${e.toString()}$stack";
} finally {
// Now that the group is over, restore the previous one.
- _currentGroup = parentGroup;
- _testSetup = parentSetup;
- _testTeardown = parentTeardown;
+ _currentContext = _currentContext.parent;
}
}
/**
* 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;
+ _currentContext.testSetup = setupTest;
}
/**
@@ -647,7 +688,7 @@
* case it must return a [Future].
*/
void tearDown(Function teardownTest) {
- _testTeardown = teardownTest;
+ _currentContext.testTeardown = teardownTest;
}
/** Advance to the next test case. */
@@ -712,7 +753,6 @@
void runTests() {
_ensureInitialized(false);
_currentTestCaseIndex = 0;
- _currentGroup = '';
// If we are soloing a test, remove all the others.
if (_soloTest != null) {
@@ -811,8 +851,9 @@
}
String _fullSpec(String spec) {
- if (spec == null) return '$_currentGroup';
- return _currentGroup != '' ? '$_currentGroup$groupSep$spec' : spec;
+ var group = '${_currentContext.fullName}';
+ if (spec == null) return group;
+ return group != '' ? '$group$groupSep$spec' : spec;
}
/**
« no previous file with comments | « pkg/unittest/lib/src/test_case.dart ('k') | pkg/unittest/test/unittest_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698