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

Side by Side Diff: test/vm_listener_test.dart

Issue 914963003: Add a VmListener and IsolateTest class for running tests in other isolates. (Closed) Base URL: git@github.com:dart-lang/unittest@master
Patch Set: Code review changes Created 5 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
« no previous file with comments | « test/utils.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 import 'dart:async';
6 import 'dart:isolate';
7
8 import 'package:unittest/src/declarer.dart';
9 import 'package:unittest/src/invoker.dart';
10 import 'package:unittest/src/isolate_test.dart';
11 import 'package:unittest/src/live_test.dart';
12 import 'package:unittest/src/state.dart';
13 import 'package:unittest/src/suite.dart';
14 import 'package:unittest/src/vm_listener.dart';
15 import 'package:unittest/unittest.dart';
16
17 import 'utils.dart';
18
19 /// The current declarer.
20 Declarer get _declarer => Zone.current[#unittest.declarer];
21
22 /// An isolate that's been spun up for the current test.
23 ///
24 /// This is tracked so that it can be killed once the test is done.
25 Isolate _isolate;
26
27 /// A live test that's running for the current test.
28 ///
29 /// This is tracked so that it can be closed once the test is done.
30 LiveTest _liveTest;
31
32 void main() {
33 tearDown(() {
34 if (_isolate != null) _isolate.kill(Isolate.IMMEDIATE);
35 _isolate = null;
36
37 if (_liveTest != null) _liveTest.close();
38 _liveTest = null;
39 });
40
41 test("sends a list of available tests on startup", () {
42 return _spawnIsolate(_successfulTests).then((receivePort) {
43 return receivePort.first;
44 }).then((tests) {
45 expect(tests, hasLength(3));
46 expect(tests[0], containsPair("name", "successful 1"));
47 expect(tests[1], containsPair("name", "successful 2"));
48 expect(tests[2], containsPair("name", "successful 3"));
49 });
50 });
51
52 group("in a successful test", () {
53 test("the state changes from pending to running to complete", () {
54 return _isolateTest(_successfulTests).then((liveTest) {
55 liveTest.onError.listen(expectAsync((_) {}, count: 0));
56
57 expect(liveTest.state,
58 equals(const State(Status.pending, Result.success)));
59
60 var future = liveTest.run();
61
62 expect(liveTest.state,
63 equals(const State(Status.running, Result.success)));
64
65 return future.then((_) {
66 expect(liveTest.state,
67 equals(const State(Status.complete, Result.success)));
68 });
69 });
70 });
71
72 test("onStateChange fires for each state change", () {
73 return _isolateTest(_successfulTests).then((liveTest) {
74 liveTest.onError.listen(expectAsync((_) {}, count: 0));
75
76 var first = true;
77 liveTest.onStateChange.listen(expectAsync((state) {
78 if (first) {
79 expect(state.status, equals(Status.running));
80 first = false;
81 } else {
82 expect(state.status, equals(Status.complete));
83 }
84 expect(state.result, equals(Result.success));
85 }, count: 2, max: 2));
86
87 return liveTest.run();
88 });
89 });
90 });
91
92 group("in a test with failures", () {
93 test("a failure reported causes the test to fail", () {
94 return _isolateTest(_failingTest).then((liveTest) {
95 expectSingleFailure(liveTest);
96 return liveTest.run();
97 });
98 });
99
100 test("a failure reported asynchronously after the test causes it to error",
101 () {
102 return _isolateTest(_failAfterSucceedTest).then((liveTest) {
103 expectStates(liveTest, [
104 const State(Status.running, Result.success),
105 const State(Status.complete, Result.success),
106 const State(Status.complete, Result.failure),
107 const State(Status.complete, Result.error)
108 ]);
109
110 expectErrors(liveTest, [(error) {
111 expect(lastState,
112 equals(const State(Status.complete, Result.failure)));
113 expect(error, isTestFailure("oh no"));
114 }, (error) {
115 expect(lastState, equals(const State(Status.complete, Result.error)));
116 expect(error, isRemoteException(
117 "This test failed after it had already completed. Make sure to "
118 "use [expectAsync]\n"
119 "or the [completes] matcher when testing async code."));
120 }]);
121
122 return liveTest.run();
123 });
124 });
125
126 test("multiple asynchronous failures are reported", () {
127 return _isolateTest(_multiFailTest).then((liveTest) {
128 expectStates(liveTest, [
129 const State(Status.running, Result.success),
130 const State(Status.complete, Result.failure)
131 ]);
132
133 expectErrors(liveTest, [(error) {
134 expect(lastState.status, equals(Status.complete));
135 expect(error, isTestFailure("one"));
136 }, (error) {
137 expect(error, isTestFailure("two"));
138 }, (error) {
139 expect(error, isTestFailure("three"));
140 }, (error) {
141 expect(error, isTestFailure("four"));
142 }]);
143
144 return liveTest.run();
145 });
146 });
147 });
148
149 group("in a test with errors", () {
150 test("an error reported causes the test to error", () {
151 return _isolateTest(_errorTest).then((liveTest) {
152 expectStates(liveTest, [
153 const State(Status.running, Result.success),
154 const State(Status.complete, Result.error)
155 ]);
156
157 expectErrors(liveTest, [(error) {
158 expect(lastState.status, equals(Status.complete));
159 expect(error, isRemoteException("oh no"));
160 }]);
161
162 return liveTest.run();
163 });
164 });
165
166 test("an error reported asynchronously after the test causes it to error",
167 () {
168 return _isolateTest(_errorAfterSucceedTest).then((liveTest) {
169 expectStates(liveTest, [
170 const State(Status.running, Result.success),
171 const State(Status.complete, Result.success),
172 const State(Status.complete, Result.error)
173 ]);
174
175 expectErrors(liveTest, [(error) {
176 expect(lastState,
177 equals(const State(Status.complete, Result.error)));
178 expect(error, isRemoteException("oh no"));
179 }, (error) {
180 expect(error, isRemoteException(
181 "This test failed after it had already completed. Make sure to "
182 "use [expectAsync]\n"
183 "or the [completes] matcher when testing async code."));
184 }]);
185
186 return liveTest.run();
187 });
188 });
189
190 test("multiple asynchronous errors are reported", () {
191 return _isolateTest(_multiErrorTest).then((liveTest) {
192 expectStates(liveTest, [
193 const State(Status.running, Result.success),
194 const State(Status.complete, Result.error)
195 ]);
196
197 expectErrors(liveTest, [(error) {
198 expect(lastState.status, equals(Status.complete));
199 expect(error, isRemoteException("one"));
200 }, (error) {
201 expect(error, isRemoteException("two"));
202 }, (error) {
203 expect(error, isRemoteException("three"));
204 }, (error) {
205 expect(error, isRemoteException("four"));
206 }]);
207
208 return liveTest.run();
209 });
210 });
211 });
212 }
213
214 /// Loads the first test defined in [entryPoint] in another isolate.
215 ///
216 /// This test will be automatically closed when the test is finished.
217 Future<LiveTest> _isolateTest(void entryPoint(SendPort sendPort)) {
218 return _spawnIsolate(entryPoint).then((receivePort) {
219 return receivePort.first;
220 }).then((response) {
221 var testMap = response.first;
222 var test = new IsolateTest(testMap["name"], testMap["sendPort"]);
223 var suite = new Suite("suite", [test]);
224 _liveTest = test.load(suite);
225 return _liveTest;
226 });
227 }
228
229 /// Spawns an isolate from [entryPoint], sends it a new [SendPort], and returns
230 /// the corresponding [ReceivePort].
231 ///
232 /// This isolate will be automatically killed when the test is finished.
233 Future<ReceivePort> _spawnIsolate(void entryPoint(SendPort sendPort)) {
234 var receivePort = new ReceivePort();
235 return Isolate.spawn(entryPoint, receivePort.sendPort).then((isolate) {
236 _isolate = isolate;
237 return receivePort;
238 });
239 }
240
241 /// An isolate entrypoint that defines three tests that succeed.
242 void _successfulTests(SendPort sendPort) {
243 VmListener.start(sendPort, () {
244 _declarer.test("successful 1", () {});
245 _declarer.test("successful 2", () {});
246 _declarer.test("successful 3", () {});
247 });
248 }
249
250 /// An isolate entrypoint that defines a test that fails.
251 void _failingTest(SendPort sendPort) {
252 VmListener.start(sendPort, () {
253 _declarer.test("failure", () => throw new TestFailure('oh no'));
254 });
255 }
256
257 /// An isolate entrypoint that defines a test that fails after succeeding.
258 void _failAfterSucceedTest(SendPort sendPort) {
259 VmListener.start(sendPort, () {
260 _declarer.test("fail after succeed", () {
261 pumpEventQueue().then((_) {
262 throw new TestFailure('oh no');
263 });
264 });
265 });
266 }
267
268 /// An isolate entrypoint that defines a test that fails multiple times.
269 void _multiFailTest(SendPort sendPort) {
270 VmListener.start(sendPort, () {
271 _declarer.test("multiple failures", () {
272 Invoker.current.addOutstandingCallback();
273 new Future(() => throw new TestFailure("one"));
274 new Future(() => throw new TestFailure("two"));
275 new Future(() => throw new TestFailure("three"));
276 new Future(() => throw new TestFailure("four"));
277 });
278 });
279 }
280
281 /// An isolate entrypoint that defines a test that errors.
282 void _errorTest(SendPort sendPort) {
283 VmListener.start(sendPort, () {
284 _declarer.test("error", () => throw 'oh no');
285 });
286 }
287
288 /// An isolate entrypoint that defines a test that errors after succeeding.
289 void _errorAfterSucceedTest(SendPort sendPort) {
290 VmListener.start(sendPort, () {
291 _declarer.test("error after succeed", () {
292 pumpEventQueue().then((_) => throw 'oh no');
293 });
294 });
295 }
296
297 /// An isolate entrypoint that defines a test that errors multiple times.
298 void _multiErrorTest(SendPort sendPort) {
299 VmListener.start(sendPort, () {
300 _declarer.test("multiple errors", () {
301 Invoker.current.addOutstandingCallback();
302 new Future(() => throw "one");
303 new Future(() => throw "two");
304 new Future(() => throw "three");
305 new Future(() => throw "four");
306 });
307 });
308 }
OLDNEW
« no previous file with comments | « test/utils.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698