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 unittest.live_test_controller; | 5 library unittest.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'; |
11 | 11 |
12 import 'live_test.dart'; | 12 import 'live_test.dart'; |
13 import 'state.dart'; | 13 import 'state.dart'; |
14 import 'suite.dart'; | 14 import 'suite.dart'; |
15 import 'test.dart'; | 15 import 'test.dart'; |
16 import 'utils.dart'; | |
16 | 17 |
17 /// An implementation of [LiveTest] that's controlled by a [LiveTestController]. | 18 /// An implementation of [LiveTest] that's controlled by a [LiveTestController]. |
18 class _LiveTest extends LiveTest { | 19 class _LiveTest extends LiveTest { |
19 final LiveTestController _controller; | 20 final LiveTestController _controller; |
20 | 21 |
21 Suite get suite => _controller._suite; | 22 Suite get suite => _controller._suite; |
22 | 23 |
23 Test get test => _controller._test; | 24 Test get test => _controller._test; |
24 | 25 |
25 State get state => _controller._state; | 26 State get state => _controller._state; |
26 | 27 |
27 Stream<State> get onStateChange => | 28 Stream<State> get onStateChange => |
28 _controller._onStateChangeController.stream; | 29 _controller._onStateChangeController.stream; |
29 | 30 |
30 List<AsyncError> get errors => new UnmodifiableListView(_controller._errors); | 31 List<AsyncError> get errors => new UnmodifiableListView(_controller._errors); |
31 | 32 |
32 Stream<AsyncError> get onError => _controller._onErrorController.stream; | 33 Stream<AsyncError> get onError => _controller._onErrorController.stream; |
33 | 34 |
34 Future get onComplete => _controller.completer.future; | 35 Future get onComplete => _controller.completer.future; |
35 | 36 |
36 Future run() => _controller._run(); | 37 Future run() => _controller._run(); |
37 | 38 |
39 Future close() => _controller._close(); | |
40 | |
38 _LiveTest(this._controller); | 41 _LiveTest(this._controller); |
39 } | 42 } |
40 | 43 |
41 /// A controller that drives a [LiveTest]. | 44 /// A controller that drives a [LiveTest]. |
42 /// | 45 /// |
43 /// This is a utility class to make it easier for implementors of [Test] to | 46 /// This is a utility class to make it easier for implementors of [Test] to |
44 /// create the [LiveTest] returned by [Test.load]. The [LiveTest] is accessible | 47 /// create the [LiveTest] returned by [Test.load]. The [LiveTest] is accessible |
45 /// through [LiveTestController.liveTest]. | 48 /// through [LiveTestController.liveTest]. |
46 /// | 49 /// |
47 /// This automatically handles some of [LiveTest]'s guarantees, but for the most | 50 /// This automatically handles some of [LiveTest]'s guarantees, but for the most |
48 /// part it's the caller's responsibility to make sure everything gets | 51 /// part it's the caller's responsibility to make sure everything gets |
49 /// dispatched in the correct order. | 52 /// dispatched in the correct order. |
50 class LiveTestController { | 53 class LiveTestController { |
51 /// The [LiveTest] controlled by [this]. | 54 /// The [LiveTest] controlled by [this]. |
52 LiveTest get liveTest => _liveTest; | 55 LiveTest get liveTest => _liveTest; |
53 LiveTest _liveTest; | 56 LiveTest _liveTest; |
54 | 57 |
55 /// The test suite that's running [this]. | 58 /// The test suite that's running [this]. |
56 final Suite _suite; | 59 final Suite _suite; |
57 | 60 |
58 /// The test that's being run. | 61 /// The test that's being run. |
59 final Test _test; | 62 final Test _test; |
60 | 63 |
61 /// The function that will actually start the test running. | 64 /// The function that will actually start the test running. |
62 final Function _onRun; | 65 final Function _onRun; |
63 | 66 |
67 /// A function to run when the test is closed. | |
68 /// | |
69 /// This may be `null`. | |
70 final AsyncFunction _onClose; | |
71 | |
64 /// The list of errors caught by the test. | 72 /// The list of errors caught by the test. |
65 final _errors = new List<AsyncError>(); | 73 final _errors = new List<AsyncError>(); |
66 | 74 |
67 /// The current state of the test. | 75 /// The current state of the test. |
68 var _state = const State(Status.pending, Result.success); | 76 var _state = const State(Status.pending, Result.success); |
69 | 77 |
70 /// The controller for [LiveTest.onStateChange]. | 78 /// The controller for [LiveTest.onStateChange]. |
71 final _onStateChangeController = new StreamController<State>.broadcast(); | 79 final _onStateChangeController = new StreamController<State>.broadcast(); |
72 | 80 |
73 /// The controller for [LiveTest.onError]. | 81 /// The controller for [LiveTest.onError]. |
74 final _onErrorController = new StreamController<AsyncError>.broadcast(); | 82 final _onErrorController = new StreamController<AsyncError>.broadcast(); |
75 | 83 |
76 /// The completer for [LiveTest.onComplete]; | 84 /// The completer for [LiveTest.onComplete]; |
77 final completer = new Completer(); | 85 final completer = new Completer(); |
78 | 86 |
79 /// Whether [run] has been called. | 87 /// Whether [run] has been called. |
80 var _runCalled = false; | 88 var _runCalled = false; |
81 | 89 |
90 /// Whether [close] has been called. | |
91 bool get _isClosed => _onErrorController.isClosed; | |
92 | |
82 /// Creates a new controller for a [LiveTest]. | 93 /// Creates a new controller for a [LiveTest]. |
83 /// | 94 /// |
84 /// [test] is the test being run; [suite] is the suite that contains it. | 95 /// [test] is the test being run; [suite] is the suite that contains it. |
85 /// | 96 /// |
86 /// [onRun] is a function that will be called from [LiveTest.run]. It should | 97 /// [onRun] is a function that will be called from [LiveTest.run]. It should |
87 /// start the test running. The controller takes care of ensuring that | 98 /// start the test running. The controller takes care of ensuring that |
88 /// [LiveTest.run] isn't called more than once and that [LiveTest.onComplete] | 99 /// [LiveTest.run] isn't called more than once and that [LiveTest.onComplete] |
89 /// is returned. | 100 /// is returned. |
90 LiveTestController(this._suite, this._test, void onRun()) | 101 /// |
91 : _onRun = onRun { | 102 /// If [onClose] is passed, it's called the first [LiveTest.close] is called. |
103 /// It should clean up any resources that have been allocated for the test. It | |
104 /// may return a [Future]. | |
105 LiveTestController(this._suite, this._test, void onRun(), {onClose()}) | |
106 : _onRun = onRun, | |
107 _onClose = onClose { | |
92 _liveTest = new _LiveTest(this); | 108 _liveTest = new _LiveTest(this); |
93 } | 109 } |
94 | 110 |
95 /// Adds an error to the [LiveTest]. | 111 /// Adds an error to the [LiveTest]. |
96 /// | 112 /// |
97 /// This both adds the error to [LiveTest.errors] and emits it via | 113 /// This both adds the error to [LiveTest.errors] and emits it via |
98 /// [LiveTest.onError]. [stackTrace] is automatically converted into a [Chain] | 114 /// [LiveTest.onError]. [stackTrace] is automatically converted into a [Chain] |
99 /// if it's not one already. | 115 /// if it's not one already. |
100 void addError(error, StackTrace stackTrace) { | 116 void addError(error, StackTrace stackTrace) { |
101 var asyncError = new AsyncError(error, new Chain.forTrace(stackTrace)); | 117 var asyncError = new AsyncError(error, new Chain.forTrace(stackTrace)); |
(...skipping 16 matching lines...) Expand all Loading... | |
118 /// [LiveTest.run]. | 134 /// [LiveTest.run]. |
119 Future _run() { | 135 Future _run() { |
120 if (_runCalled) { | 136 if (_runCalled) { |
121 throw new StateError("LiveTest.run() may not be called more than once."); | 137 throw new StateError("LiveTest.run() may not be called more than once."); |
122 } | 138 } |
123 _runCalled = true; | 139 _runCalled = true; |
124 | 140 |
125 _onRun(); | 141 _onRun(); |
126 return liveTest.onComplete; | 142 return liveTest.onComplete; |
127 } | 143 } |
144 | |
145 /// A wrapper for [_onClose] that ensures that all controllers are closed. | |
146 Future _close() { | |
147 if (_isClosed) return; | |
kevmoo
2015/02/12 02:24:29
return null here
...will make the analyzer happy
nweiz
2015/02/12 19:03:41
Done.
| |
148 _onStateChangeController.close(); | |
149 _onErrorController.close(); | |
150 if (!completer.isCompleted) completer.complete(); | |
151 | |
152 if (_onClose != null) return new Future.sync(_onClose); | |
153 return new Future.value(); | |
154 } | |
128 } | 155 } |
OLD | NEW |