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

Side by Side Diff: lib/src/backend/invoker.dart

Issue 1159923010: Use the Zone API for registerException. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: more changes Created 5 years, 6 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 library test.backend.invoker; 5 library test.backend.invoker;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:stack_trace/stack_trace.dart'; 9 import 'package:stack_trace/stack_trace.dart';
10 10
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
137 }, zoneValues: { 137 }, zoneValues: {
138 // Use the invoker as a key so that multiple invokers can have different 138 // Use the invoker as a key so that multiple invokers can have different
139 // outstanding callback counters at once. 139 // outstanding callback counters at once.
140 this: counter 140 this: counter
141 }); 141 });
142 142
143 return counter.noOutstandingCallbacks; 143 return counter.noOutstandingCallbacks;
144 } 144 }
145 145
146 /// Notifies the invoker of an asynchronous error. 146 /// Notifies the invoker of an asynchronous error.
147 /// 147 void _handleError(error, [StackTrace stackTrace]) {
148 /// Note that calling this explicitly is rarely necessary, since any
149 /// otherwise-uncaught errors will be forwarded to the invoker anyway.
150 void handleError(error, [StackTrace stackTrace]) {
151 if (stackTrace == null) stackTrace = new Chain.current(); 148 if (stackTrace == null) stackTrace = new Chain.current();
152 149
153 var afterSuccess = liveTest.isComplete && 150 var afterSuccess = liveTest.isComplete &&
154 liveTest.state.result == Result.success; 151 liveTest.state.result == Result.success;
155 152
156 if (error is! TestFailure) { 153 if (error is! TestFailure) {
157 _controller.setState(const State(Status.complete, Result.error)); 154 _controller.setState(const State(Status.complete, Result.error));
158 } else if (liveTest.state.result != Result.error) { 155 } else if (liveTest.state.result != Result.error) {
159 _controller.setState(const State(Status.complete, Result.failure)); 156 _controller.setState(const State(Status.complete, Result.failure));
160 } 157 }
161 158
162 _controller.addError(error, stackTrace); 159 _controller.addError(error, stackTrace);
163 _outstandingCallbacks.removeAllOutstandingCallbacks(); 160 _outstandingCallbacks.removeAllOutstandingCallbacks();
164 161
165 // If a test was marked as success but then had an error, that indicates 162 // If a test was marked as success but then had an error, that indicates
166 // that it was poorly-written and could be flaky. 163 // that it was poorly-written and could be flaky.
167 if (!afterSuccess) return; 164 if (!afterSuccess) return;
168 handleError( 165 _handleError(
169 "This test failed after it had already completed. Make sure to use " 166 "This test failed after it had already completed. Make sure to use "
170 "[expectAsync]\n" 167 "[expectAsync]\n"
171 "or the [completes] matcher when testing async code.", 168 "or the [completes] matcher when testing async code.",
172 stackTrace); 169 stackTrace);
173 } 170 }
174 171
175 /// The method that's run when the test is started. 172 /// The method that's run when the test is started.
176 void _onRun() { 173 void _onRun() {
177 _controller.setState(const State(Status.running, Result.success)); 174 _controller.setState(const State(Status.running, Result.success));
178 175
179 var outstandingCallbacksForBody = new OutstandingCallbackCounter(); 176 var outstandingCallbacksForBody = new OutstandingCallbackCounter();
180 177
181 // TODO(nweiz): Use async/await here once issue 23497 has been fixed in two 178 // TODO(nweiz): Use async/await here once issue 23497 has been fixed in two
182 // stable versions. 179 // stable versions.
183 Chain.capture(() { 180 Chain.capture(() {
184 runZonedWithValues(() { 181 runZonedWithValues(() {
185 // TODO(nweiz): Reset this timer whenever the user's code interacts 182 // TODO(nweiz): Reset this timer whenever the user's code interacts
186 // with the library. 183 // with the library.
187 var timeout = metadata.timeout.apply(new Duration(seconds: 30)); 184 var timeout = metadata.timeout.apply(new Duration(seconds: 30));
188 var timer = new Timer(timeout, () { 185 var timer = new Timer(timeout, () {
189 if (liveTest.isComplete) return; 186 if (liveTest.isComplete) return;
190 handleError( 187 _handleError(
191 new TimeoutException( 188 new TimeoutException(
192 "Test timed out after ${niceDuration(timeout)}.", timeout)); 189 "Test timed out after ${niceDuration(timeout)}.", timeout));
193 }); 190 });
194 191
195 // Run the test asynchronously so that the "running" state change has 192 // Run the test asynchronously so that the "running" state change has
196 // a chance to hit its event handler(s) before the test produces an 193 // a chance to hit its event handler(s) before the test produces an
197 // error. If an error is emitted before the first state change is 194 // error. If an error is emitted before the first state change is
198 // handled, we can end up with [onError] callbacks firing before the 195 // handled, we can end up with [onError] callbacks firing before the
199 // corresponding [onStateChange], which violates the timing 196 // corresponding [onStateChange], which violates the timing
200 // guarantees. 197 // guarantees.
201 new Future(_test._body) 198 new Future(_test._body)
202 .then((_) => removeOutstandingCallback()); 199 .then((_) => removeOutstandingCallback());
203 200
204 _outstandingCallbacks.noOutstandingCallbacks.then((_) { 201 _outstandingCallbacks.noOutstandingCallbacks.then((_) {
205 if (_test._tearDown == null) return null; 202 if (_test._tearDown == null) return null;
206 203
207 // Reset the outstanding callback counter to wait for callbacks from 204 // Reset the outstanding callback counter to wait for callbacks from
208 // the test's `tearDown` to complete. 205 // the test's `tearDown` to complete.
209 return waitForOutstandingCallbacks(() => 206 return waitForOutstandingCallbacks(() =>
210 runZoned(_test._tearDown, onError: handleError)); 207 runZoned(_test._tearDown, onError: _handleError));
211 }).then((_) { 208 }).then((_) {
212 timer.cancel(); 209 timer.cancel();
213 _controller.setState( 210 _controller.setState(
214 new State(Status.complete, liveTest.state.result)); 211 new State(Status.complete, liveTest.state.result));
215 212
216 // Use [Timer.run] here to avoid starving the DOM or other 213 // Use [Timer.run] here to avoid starving the DOM or other
217 // non-microtask events. 214 // non-microtask events.
218 Timer.run(_controller.completer.complete); 215 Timer.run(_controller.completer.complete);
219 }); 216 });
220 }, zoneValues: { 217 }, zoneValues: {
221 #test.invoker: this, 218 #test.invoker: this,
222 // Use the invoker as a key so that multiple invokers can have different 219 // Use the invoker as a key so that multiple invokers can have different
223 // outstanding callback counters at once. 220 // outstanding callback counters at once.
224 this: outstandingCallbacksForBody 221 this: outstandingCallbacksForBody
225 }, 222 },
226 zoneSpecification: new ZoneSpecification( 223 zoneSpecification: new ZoneSpecification(
227 print: (self, parent, zone, line) => _controller.print(line)), 224 print: (self, parent, zone, line) => _controller.print(line)),
228 onError: handleError); 225 onError: _handleError);
229 }); 226 });
230 } 227 }
231 } 228 }
OLDNEW
« CHANGELOG.md ('K') | « CHANGELOG.md ('k') | lib/src/frontend/expect_async.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698