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

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') | 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) 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 final String currentGroup; 53 final String currentGroup;
54 54
55 DateTime startTime; 55 DateTime startTime;
56 56
57 Duration runningTime; 57 Duration runningTime;
58 58
59 bool enabled = true; 59 bool enabled = true;
60 60
61 bool _doneTeardown = false; 61 bool _doneTeardown = false;
62 62
63 Completer _testComplete;
64
63 TestCase(this.id, this.description, this.test, 65 TestCase(this.id, this.description, this.test,
64 this.callbackFunctionsOutstanding) 66 this.callbackFunctionsOutstanding)
65 : currentGroup = _currentGroup, 67 : currentGroup = _currentGroup,
66 _setUp = _testSetup, 68 _setUp = _testSetup,
67 _tearDown = _testTeardown; 69 _tearDown = _testTeardown;
68 70
69 bool get isComplete => !enabled || result != null; 71 bool get isComplete => !enabled || result != null;
70 72
71 void run() { 73 void _prepTest() {
72 if (enabled) { 74 _config.onTestStart(this);
73 result = stackTrace = null; 75 startTime = new DateTime.now();
74 message = ''; 76 runningTime = null;
75 _doneTeardown = false; 77 }
76 if (_setUp != null) { 78
77 _setUp(); 79 void _runTest() {
78 } 80 _prepTest();
79 _config.onTestStart(this); 81 test();
80 startTime = new DateTime.now(); 82 if (result == null && callbackFunctionsOutstanding == 0) {
81 runningTime = null; 83 pass();
82 test(); 84 }
85 }
86
87 /**
88 * Perform any associated [setUp] function and run the test. Returns
89 * a [Future] that can be used to schedule the next test. If the test runs
90 * to completion synchronously, or is disabled, we return null, to
91 * tell unittest to schedule the next test immediately.
92 */
93 Future run() {
94 if (!enabled) return null;
95
96 result = stackTrace = null;
97 message = '';
98 _doneTeardown = false;
99 var rtn = _setUp == null ? null : _setUp();
100 if (rtn is Future) {
101 rtn.then(expectAsync1((_) =>_runTest(),
102 id: '[Async setUp completion handler]'))
103 .catchError((e) {
104 _prepTest();
105 // Calling error() will result in the tearDown being done.
106 // One could debate whether tearDown should be done after
107 // a failed setUp. There is no right answer, but doing it
108 // seems to be the more conservative approach, because
109 // unittest will not stop at a test failure.
110 error("$description: Test setup failed: ${e.error}");
111 });
112 } else {
113 _runTest();
114 }
115 if (result == null) { // Not complete.
116 _testComplete = new Completer();
117 return _testComplete.future;
118 }
119 return null;
120 }
121
122 void _notifyComplete() {
123 if (_testComplete != null) {
124 _testComplete.complete(this);
125 _testComplete = null;
83 } 126 }
84 } 127 }
85 128
86 void _complete() { 129 void _complete() {
87 if (runningTime == null) { 130 if (runningTime == null) {
88 // TODO(gram): currently the duration measurement code is blocked 131 // TODO(gram): currently the duration measurement code is blocked
89 // by issue 4437. When that is fixed replace the line below with: 132 // by issue 4437. When that is fixed replace the line below with:
90 // runningTime = new DateTime.now().difference(startTime); 133 // runningTime = new DateTime.now().difference(startTime);
91 runningTime = new Duration(milliseconds: 0); 134 runningTime = new Duration(milliseconds: 0);
92 } 135 }
93 if (!_doneTeardown) { 136 if (!_doneTeardown) {
137 _doneTeardown = true;
94 if (_tearDown != null) { 138 if (_tearDown != null) {
95 _tearDown(); 139 var rtn = _tearDown();
140 if (rtn is Future) {
141 rtn.then((_) {
142 if (result == null) {
143 // The test passed. In some cases we will already
144 // have set this result (e.g. if the test was async
145 // and all callbacks completed). If not, we do it here.
146 pass();
147 } else {
148 // The test has already been marked as pass/fail.
149 // Just report the updated result.
150 _config.onTestResult(this);
151 }
152 _notifyComplete();
153 })
154 .catchError((e) {
155 // We don't call fail() as that will potentially result in
156 // spurious messages like 'test failed more than once'.
157 result = ERROR;
158 message = "$description: Test teardown failed: ${e.error}";
159 _config.onTestResult(this);
160 _notifyComplete();
161 });
162 return;
163 }
96 } 164 }
97 _doneTeardown = true;
98 } 165 }
99 _config.onTestResult(this); 166 _config.onTestResult(this);
167 _notifyComplete();
100 } 168 }
101 169
102 void pass() { 170 void pass() {
103 result = PASS; 171 result = PASS;
104 _complete(); 172 _complete();
105 } 173 }
106 174
107 void fail(String messageText, [String stack = '']) { 175 void fail(String messageText, [String stack = '']) {
108 if (result != null) { 176 if (result != null) {
109 if (result == PASS) { 177 if (result == PASS) {
110 error('Test failed after initially passing: $messageText', stack); 178 error('Test failed after initially passing: $messageText', stack);
111 } else if (result == FAIL) { 179 } else if (result == FAIL) {
112 error('Test failed more than once: $messageText', stack); 180 error('Test failed more than once: $messageText', stack);
113 } 181 }
114 } else { 182 } else {
115 result = FAIL; 183 result = FAIL;
116 message = messageText; 184 message = messageText;
117 stackTrace = stack; 185 stackTrace = stack;
118 _complete(); 186 _complete();
119 } 187 }
120 } 188 }
121 189
122 void error(String messageText, [String stack = '']) { 190 void error(String messageText, [String stack = '']) {
123 result = ERROR; 191 result = ERROR;
124 message = messageText; 192 message = messageText;
125 stackTrace = stack; 193 stackTrace = stack;
126 _complete(); 194 _complete();
127 } 195 }
128 } 196 }
OLDNEW
« no previous file with comments | « no previous file | pkg/unittest/lib/unittest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698