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

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

Issue 12213079: setUp/tearDown functions can now be asynchronous. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 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/lib/unittest.dart » ('j') | pkg/unittest/lib/unittest.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 part of unittest; 5 part of unittest;
6 6
7 /** 7 /**
8 * testcase.dart: this file is sourced by unittest.dart. It defines [TestCase] 8 * testcase.dart: this file is sourced by unittest.dart. It defines [TestCase]
9 * and assumes unittest defines the type [TestFunction]. 9 * and assumes unittest defines the type [TestFunction].
10 */ 10 */
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 bool _doneTeardown = false; 61 bool _doneTeardown = false;
62 62
63 TestCase(this.id, this.description, this.test, 63 TestCase(this.id, this.description, this.test,
64 this.callbackFunctionsOutstanding) 64 this.callbackFunctionsOutstanding)
65 : currentGroup = _currentGroup, 65 : currentGroup = _currentGroup,
66 _setUp = _testSetup, 66 _setUp = _testSetup,
67 _tearDown = _testTeardown; 67 _tearDown = _testTeardown;
68 68
69 bool get isComplete => !enabled || result != null; 69 bool get isComplete => !enabled || result != null;
70 70
71 void _prepTest() {
72 _config.onTestStart(this);
73 startTime = new DateTime.now();
74 runningTime = null;
75 }
76
71 void run() { 77 void run() {
72 if (enabled) { 78 if (enabled) {
73 result = stackTrace = null; 79 result = stackTrace = null;
74 message = ''; 80 message = '';
75 _doneTeardown = false; 81 _doneTeardown = false;
76 if (_setUp != null) { 82 if (_setUp != null) {
77 _setUp(); 83 var rtn = _setUp();
84 if (rtn is Future) {
85 rtn.then(expectAsync1((_) {
86 _prepTest();
87 test();
88 }, id: '[Async setUp completion handler]'))
89 .catchError((e) {
justinfagnani 2013/02/08 01:36:48 Make sure you always call catchError() before then
gram 2013/02/08 17:52:24 Why?
Siggi Cherem (dart-lang) 2013/02/08 18:02:22 to clarify: as long as the futures are chained, th
justinfagnani 2013/02/08 18:36:57 Good catch. I was mentally using the old pattern,
90 _prepTest();
justinfagnani 2013/02/08 01:36:48 why call _prepTest() when there's an error?
gram 2013/02/08 17:52:24 We are going to treat this like a regular test err
91 // Calling error() will result in the tearDown being done.
92 // One could debate whether tearDown should be done after
93 // a failed setUp. There is no right answer, but doing it
94 // seems to be the more conservative approach.
95 error("$description: Test setup failed: ${e.error}");
96 });
97 return;
98 }
78 } 99 }
79 _config.onTestStart(this); 100 _prepTest();
justinfagnani 2013/02/08 01:36:48 Looks like for async setup _prepTest() and test()
gram 2013/02/08 17:52:24 No, there is a return statement in the block.
justinfagnani 2013/02/08 18:36:57 Oops
80 startTime = new DateTime.now();
81 runningTime = null;
82 test(); 101 test();
102 } else {
103 _nextTestCase();
83 } 104 }
84 } 105 }
85 106
86 void _complete() { 107 void _complete() {
87 if (runningTime == null) { 108 if (runningTime == null) {
88 // TODO(gram): currently the duration measurement code is blocked 109 // TODO(gram): currently the duration measurement code is blocked
89 // by issue 4437. When that is fixed replace the line below with: 110 // by issue 4437. When that is fixed replace the line below with:
90 // runningTime = new DateTime.now().difference(startTime); 111 // runningTime = new DateTime.now().difference(startTime);
91 runningTime = new Duration(milliseconds: 0); 112 runningTime = new Duration(milliseconds: 0);
92 } 113 }
114 bool mustRunNextTest = false;
93 if (!_doneTeardown) { 115 if (!_doneTeardown) {
116 _doneTeardown = true;
117 mustRunNextTest = true;
94 if (_tearDown != null) { 118 if (_tearDown != null) {
95 _tearDown(); 119 var rtn = _tearDown();
120 if (rtn is Future) {
121 rtn.then(expectAsync1((_) {
122 if (result == null) {
123 // The test passed. In some cases we will already
124 // have set this result (e.g. if the test was async
125 // and all callbacks completed). If not, we do it here.
126 pass();
127 } else {
128 // The test has already been marked as pass/fail.
129 // Just report the updated result.
130 _config.onTestResult(this);
131 }
132 _nextTestCase();
133 }, id: '[Async tearDown completion handler]'))
134 .catchError((e) {
justinfagnani 2013/02/08 01:36:48 Make sure you always call catchError() before then
135 // We don't call fail() as that will potentially result in
136 // spurious messages like 'test failed more than once'.
137 result = ERROR;
138 message = "$description: Test teardown failed: ${e.error}";
139 _config.onTestResult(this);
140 _nextTestCase();
141 });
142 return;
143 }
96 } 144 }
97 _doneTeardown = true;
98 } 145 }
99 _config.onTestResult(this); 146 _config.onTestResult(this);
147 if (mustRunNextTest) {
148 _nextTestCase();
149 }
100 } 150 }
101 151
102 void pass() { 152 void pass() {
103 result = PASS; 153 result = PASS;
104 _complete(); 154 _complete();
105 } 155 }
106 156
107 void fail(String messageText, [String stack = '']) { 157 void fail(String messageText, [String stack = '']) {
108 if (result != null) { 158 if (result != null) {
109 if (result == PASS) { 159 if (result == PASS) {
110 error('Test failed after initially passing: $messageText', stack); 160 error('Test failed after initially passing: $messageText', stack);
111 } else if (result == FAIL) { 161 } else if (result == FAIL) {
112 error('Test failed more than once: $messageText', stack); 162 error('Test failed more than once: $messageText', stack);
113 } 163 }
114 } else { 164 } else {
115 result = FAIL; 165 result = FAIL;
116 message = messageText; 166 message = messageText;
117 stackTrace = stack; 167 stackTrace = stack;
118 _complete(); 168 _complete();
119 } 169 }
120 } 170 }
121 171
122 void error(String messageText, [String stack = '']) { 172 void error(String messageText, [String stack = '']) {
123 result = ERROR; 173 result = ERROR;
124 message = messageText; 174 message = messageText;
125 stackTrace = stack; 175 stackTrace = stack;
126 _complete(); 176 _complete();
127 } 177 }
128 } 178 }
OLDNEW
« no previous file with comments | « no previous file | pkg/unittest/lib/unittest.dart » ('j') | pkg/unittest/lib/unittest.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698