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.live_test_controller; | 5 library test.backend.live_test_controller; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 | 9 |
10 import 'package:stack_trace/stack_trace.dart'; | 10 import 'package:stack_trace/stack_trace.dart'; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 /// Whether [run] has been called. | 103 /// Whether [run] has been called. |
104 var _runCalled = false; | 104 var _runCalled = false; |
105 | 105 |
106 /// Whether [close] has been called. | 106 /// Whether [close] has been called. |
107 bool get _isClosed => _onErrorController.isClosed; | 107 bool get _isClosed => _onErrorController.isClosed; |
108 | 108 |
109 /// Creates a new controller for a [LiveTest]. | 109 /// Creates a new controller for a [LiveTest]. |
110 /// | 110 /// |
111 /// [test] is the test being run; [suite] is the suite that contains it. | 111 /// [test] is the test being run; [suite] is the suite that contains it. |
112 /// | 112 /// |
113 /// [onRun] is a function that will be called from [LiveTest.run]. It should | 113 /// [onRun] is a function that's called from [LiveTest.run]. It should start |
114 /// start the test running. The controller takes care of ensuring that | 114 /// the test running. The controller takes care of ensuring that |
115 /// [LiveTest.run] isn't called more than once and that [LiveTest.onComplete] | 115 /// [LiveTest.run] isn't called more than once and that [LiveTest.onComplete] |
116 /// is returned. | 116 /// is returned. |
117 /// | 117 /// |
118 /// If [onClose] is passed, it's called the first [LiveTest.close] is called. | 118 /// [onClose] is a function that's called the first time [LiveTest.close] is |
119 /// It should clean up any resources that have been allocated for the test. It | 119 /// called. It should clean up any resources that have been allocated for the |
120 /// may return a [Future]. | 120 /// test and ensure that the test finishes quickly if it's still running. It |
121 LiveTestController(this._suite, this._test, void onRun(), {onClose()}) | 121 /// will only be called if [onRun] has been called first. |
| 122 LiveTestController(this._suite, this._test, void onRun(), void onClose()) |
122 : _onRun = onRun, | 123 : _onRun = onRun, |
123 _onClose = onClose { | 124 _onClose = onClose { |
124 _liveTest = new _LiveTest(this); | 125 _liveTest = new _LiveTest(this); |
125 } | 126 } |
126 | 127 |
127 /// Adds an error to the [LiveTest]. | 128 /// Adds an error to the [LiveTest]. |
128 /// | 129 /// |
129 /// This both adds the error to [LiveTest.errors] and emits it via | 130 /// This both adds the error to [LiveTest.errors] and emits it via |
130 /// [LiveTest.onError]. [stackTrace] is automatically converted into a [Chain] | 131 /// [LiveTest.onError]. [stackTrace] is automatically converted into a [Chain] |
131 /// if it's not one already. | 132 /// if it's not one already. |
132 void addError(error, StackTrace stackTrace) { | 133 void addError(error, StackTrace stackTrace) { |
| 134 if (_isClosed) return; |
| 135 |
133 var asyncError = new AsyncError(error, new Chain.forTrace(stackTrace)); | 136 var asyncError = new AsyncError(error, new Chain.forTrace(stackTrace)); |
134 _errors.add(asyncError); | 137 _errors.add(asyncError); |
135 _onErrorController.add(asyncError); | 138 _onErrorController.add(asyncError); |
136 } | 139 } |
137 | 140 |
138 /// Sets the current state of the [LiveTest] to [newState]. | 141 /// Sets the current state of the [LiveTest] to [newState]. |
139 /// | 142 /// |
140 /// If [newState] is different than the old state, this both sets | 143 /// If [newState] is different than the old state, this both sets |
141 /// [LiveTest.state] and emits the new state via [LiveTest.onStateChanged]. If | 144 /// [LiveTest.state] and emits the new state via [LiveTest.onStateChanged]. If |
142 /// it's not different, this does nothing. | 145 /// it's not different, this does nothing. |
143 void setState(State newState) { | 146 void setState(State newState) { |
| 147 if (_isClosed) return; |
144 if (_state == newState) return; | 148 if (_state == newState) return; |
| 149 |
145 _state = newState; | 150 _state = newState; |
146 _onStateChangeController.add(newState); | 151 _onStateChangeController.add(newState); |
147 } | 152 } |
148 | 153 |
149 /// Emits a line printed by the test over [LiveTest.onPrint]. | 154 /// Emits a line printed by the test over [LiveTest.onPrint]. |
150 void print(String line) => _onPrintController.add(line); | 155 void print(String line) => _onPrintController.add(line); |
151 | 156 |
152 /// A wrapper for [_onRun] that ensures that it follows the guarantees for | 157 /// A wrapper for [_onRun] that ensures that it follows the guarantees for |
153 /// [LiveTest.run]. | 158 /// [LiveTest.run]. |
154 Future _run() { | 159 Future _run() { |
155 if (_runCalled) { | 160 if (_runCalled) { |
156 throw new StateError("LiveTest.run() may not be called more than once."); | 161 throw new StateError("LiveTest.run() may not be called more than once."); |
157 } | 162 } |
158 _runCalled = true; | 163 _runCalled = true; |
159 | 164 |
160 _onRun(); | 165 _onRun(); |
161 return liveTest.onComplete; | 166 return liveTest.onComplete; |
162 } | 167 } |
163 | 168 |
164 /// A wrapper for [_onClose] that ensures that all controllers are closed. | 169 /// A wrapper for [_onClose] that ensures that all controllers are closed. |
165 Future _close() { | 170 Future _close() { |
166 if (_isClosed) return new Future.value(); | 171 if (_isClosed) return completer.future; |
| 172 |
167 _onStateChangeController.close(); | 173 _onStateChangeController.close(); |
168 _onErrorController.close(); | 174 _onErrorController.close(); |
169 if (!completer.isCompleted) completer.complete(); | |
170 | 175 |
171 if (_onClose != null) return new Future.sync(_onClose); | 176 if (_runCalled) { |
172 return new Future.value(); | 177 _onClose(); |
| 178 } else { |
| 179 completer.complete(); |
| 180 } |
| 181 |
| 182 return completer.future; |
173 } | 183 } |
174 } | 184 } |
OLD | NEW |