 Chromium Code Reviews
 Chromium Code Reviews Issue 1361303002:
  Get rid of LocalTest.tearDown.  (Closed) 
  Base URL: git@github.com:dart-lang/test@master
    
  
    Issue 1361303002:
  Get rid of LocalTest.tearDown.  (Closed) 
  Base URL: git@github.com:dart-lang/test@master| OLD | NEW | 
|---|---|
| 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 | 
| 11 import '../frontend/expect.dart'; | 11 import '../frontend/expect.dart'; | 
| 12 import '../utils.dart'; | 12 import '../utils.dart'; | 
| 13 import 'closed_exception.dart'; | 13 import 'closed_exception.dart'; | 
| 14 import 'live_test.dart'; | 14 import 'live_test.dart'; | 
| 15 import 'live_test_controller.dart'; | 15 import 'live_test_controller.dart'; | 
| 16 import 'metadata.dart'; | 16 import 'metadata.dart'; | 
| 17 import 'outstanding_callback_counter.dart'; | 17 import 'outstanding_callback_counter.dart'; | 
| 18 import 'state.dart'; | 18 import 'state.dart'; | 
| 19 import 'suite.dart'; | 19 import 'suite.dart'; | 
| 20 import 'test.dart'; | 20 import 'test.dart'; | 
| 21 | 21 | 
| 22 /// A test in this isolate. | 22 /// A test in this isolate. | 
| 23 class LocalTest implements Test { | 23 class LocalTest implements Test { | 
| 24 final String name; | 24 final String name; | 
| 25 final Metadata metadata; | 25 final Metadata metadata; | 
| 26 | 26 | 
| 27 /// The test body. | 27 /// The test body. | 
| 28 final AsyncFunction _body; | 28 final AsyncFunction _body; | 
| 29 | 29 | 
| 30 /// The callback used to clean up after the test. | 30 LocalTest(this.name, this.metadata, body()) | 
| 31 /// | 31 : _body = body; | 
| 32 /// This is separated out from [_body] because it needs to run once the test's | |
| 33 /// asynchronous computation has finished, even if that's different from the | |
| 34 /// completion of the main body of the test. | |
| 35 final AsyncFunction _tearDown; | |
| 36 | |
| 37 LocalTest(this.name, this.metadata, body(), {tearDown()}) | |
| 38 : _body = body, | |
| 39 _tearDown = tearDown; | |
| 40 | 32 | 
| 41 /// Loads a single runnable instance of this test. | 33 /// Loads a single runnable instance of this test. | 
| 42 LiveTest load(Suite suite) { | 34 LiveTest load(Suite suite) { | 
| 43 var invoker = new Invoker._(suite, this); | 35 var invoker = new Invoker._(suite, this); | 
| 44 return invoker.liveTest; | 36 return invoker.liveTest; | 
| 45 } | 37 } | 
| 46 | 38 | 
| 47 Test change({String name, Metadata metadata}) { | 39 Test change({String name, Metadata metadata}) { | 
| 48 if (name == name && metadata == this.metadata) return this; | 40 if (name == name && metadata == this.metadata) return this; | 
| 49 if (name == null) name = this.name; | 41 if (name == null) name = this.name; | 
| 50 if (metadata == null) metadata = this.metadata; | 42 if (metadata == null) metadata = this.metadata; | 
| 51 return new LocalTest(name, metadata, _body, tearDown: _tearDown); | 43 return new LocalTest(name, metadata, _body); | 
| 52 } | 44 } | 
| 53 } | 45 } | 
| 54 | 46 | 
| 55 /// The class responsible for managing the lifecycle of a single local test. | 47 /// The class responsible for managing the lifecycle of a single local test. | 
| 56 /// | 48 /// | 
| 57 /// The current invoker is accessible within the zone scope of the running test | 49 /// The current invoker is accessible within the zone scope of the running test | 
| 58 /// using [Invoker.current]. It's used to track asynchronous callbacks and | 50 /// using [Invoker.current]. It's used to track asynchronous callbacks and | 
| 59 /// report asynchronous errors. | 51 /// report asynchronous errors. | 
| 60 class Invoker { | 52 class Invoker { | 
| 61 /// The live test being driven by the invoker. | 53 /// The live test being driven by the invoker. | 
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 140 /// | 132 /// | 
| 141 /// Future calls to [addOutstandingCallback] and [removeOutstandingCallback] | 133 /// Future calls to [addOutstandingCallback] and [removeOutstandingCallback] | 
| 142 /// will be ignored. | 134 /// will be ignored. | 
| 143 void removeAllOutstandingCallbacks() => | 135 void removeAllOutstandingCallbacks() => | 
| 144 _outstandingCallbacks.removeAllOutstandingCallbacks(); | 136 _outstandingCallbacks.removeAllOutstandingCallbacks(); | 
| 145 | 137 | 
| 146 /// Runs [fn] and returns once all (registered) outstanding callbacks it | 138 /// Runs [fn] and returns once all (registered) outstanding callbacks it | 
| 147 /// transitively invokes have completed. | 139 /// transitively invokes have completed. | 
| 148 /// | 140 /// | 
| 149 /// If [fn] itself returns a future, this will automatically wait until that | 141 /// If [fn] itself returns a future, this will automatically wait until that | 
| 150 /// future completes as well. | 142 /// future completes as well. Note that outstanding callbacks registered | 
| 143 /// within [fn] will *not* be registered as outstanding callback outside of | |
| 144 /// [fn]. | |
| 151 /// | 145 /// | 
| 152 /// Note that outstanding callbacks registered within [fn] will *not* be | 146 /// If [fn] produces an unhandled error, this marks the current test as | 
| 153 /// registered as outstanding callback outside of [fn]. | 147 /// failed, removes all outstanding callbacks registered within [fn], and the | 
| 148 /// completes returned future. It does not remove any outstanding callbacks | |
| 
Bob Nystrom
2015/09/24 16:05:02
"and the completes returned future" no has grammar
 
nweiz
2015/09/24 19:56:20
Done.
 | |
| 149 /// registered outside of [fn]. | |
| 154 Future waitForOutstandingCallbacks(fn()) { | 150 Future waitForOutstandingCallbacks(fn()) { | 
| 155 heartbeat(); | 151 heartbeat(); | 
| 156 | 152 | 
| 157 var counter = new OutstandingCallbackCounter(); | 153 var counter = new OutstandingCallbackCounter(); | 
| 158 runZoned(() { | 154 runZoned(() { | 
| 159 // TODO(nweiz): Use async/await here once issue 23497 has been fixed in | 155 // TODO(nweiz): Use async/await here once issue 23497 has been fixed in | 
| 160 // two stable versions. | 156 // two stable versions. | 
| 161 new Future.sync(fn).then((_) => counter.removeOutstandingCallback()); | 157 runZoned(() { | 
| 158 new Future.sync(fn).then((_) => counter.removeOutstandingCallback()); | |
| 159 }, onError: _handleError); | |
| 162 }, zoneValues: { | 160 }, zoneValues: { | 
| 163 // Use the invoker as a key so that multiple invokers can have different | 161 // Use the invoker as a key so that multiple invokers can have different | 
| 164 // outstanding callback counters at once. | 162 // outstanding callback counters at once. | 
| 165 this: counter | 163 this: counter | 
| 166 }); | 164 }); | 
| 167 | 165 | 
| 168 return counter.noOutstandingCallbacks; | 166 return counter.noOutstandingCallbacks; | 
| 169 } | 167 } | 
| 170 | 168 | 
| 171 /// Notifies the invoker that progress is being made. | 169 /// Notifies the invoker that progress is being made. | 
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 // Run the test asynchronously so that the "running" state change has | 228 // Run the test asynchronously so that the "running" state change has | 
| 231 // a chance to hit its event handler(s) before the test produces an | 229 // a chance to hit its event handler(s) before the test produces an | 
| 232 // error. If an error is emitted before the first state change is | 230 // error. If an error is emitted before the first state change is | 
| 233 // handled, we can end up with [onError] callbacks firing before the | 231 // handled, we can end up with [onError] callbacks firing before the | 
| 234 // corresponding [onStateChange], which violates the timing | 232 // corresponding [onStateChange], which violates the timing | 
| 235 // guarantees. | 233 // guarantees. | 
| 236 new Future(_test._body) | 234 new Future(_test._body) | 
| 237 .then((_) => removeOutstandingCallback()); | 235 .then((_) => removeOutstandingCallback()); | 
| 238 | 236 | 
| 239 _outstandingCallbacks.noOutstandingCallbacks.then((_) { | 237 _outstandingCallbacks.noOutstandingCallbacks.then((_) { | 
| 240 if (_test._tearDown == null) return null; | |
| 241 | |
| 242 // Reset the outstanding callback counter to wait for callbacks from | |
| 243 // the test's `tearDown` to complete. | |
| 244 return waitForOutstandingCallbacks(() => | |
| 245 runZoned(_test._tearDown, onError: _handleError)); | |
| 246 }).then((_) { | |
| 247 if (_timeoutTimer != null) _timeoutTimer.cancel(); | 238 if (_timeoutTimer != null) _timeoutTimer.cancel(); | 
| 248 _controller.setState( | 239 _controller.setState( | 
| 249 new State(Status.complete, liveTest.state.result)); | 240 new State(Status.complete, liveTest.state.result)); | 
| 250 | 241 | 
| 251 // Use [Timer.run] here to avoid starving the DOM or other | 242 // Use [Timer.run] here to avoid starving the DOM or other | 
| 252 // non-microtask events. | 243 // non-microtask events. | 
| 253 Timer.run(_controller.completer.complete); | 244 Timer.run(_controller.completer.complete); | 
| 254 }); | 245 }); | 
| 255 }, zoneValues: { | 246 }, zoneValues: { | 
| 256 #test.invoker: this, | 247 #test.invoker: this, | 
| 257 // Use the invoker as a key so that multiple invokers can have different | 248 // Use the invoker as a key so that multiple invokers can have different | 
| 258 // outstanding callback counters at once. | 249 // outstanding callback counters at once. | 
| 259 this: outstandingCallbacksForBody | 250 this: outstandingCallbacksForBody | 
| 260 }, | 251 }, | 
| 261 zoneSpecification: new ZoneSpecification( | 252 zoneSpecification: new ZoneSpecification( | 
| 262 print: (self, parent, zone, line) => _controller.print(line)), | 253 print: (self, parent, zone, line) => _controller.print(line)), | 
| 263 onError: _handleError); | 254 onError: _handleError); | 
| 264 }); | 255 }); | 
| 265 } | 256 } | 
| 266 } | 257 } | 
| OLD | NEW |