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

Side by Side Diff: test/runner/isolate_listener_test.dart

Issue 1685363002: Add a platform plugin infrastructure. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Code review changes Created 4 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/runner/engine_test.dart ('k') | test/runner/load_suite_test.dart » ('j') | 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 @TestOn("vm")
6
7 import 'dart:async';
8 import 'dart:isolate';
9
10 import 'package:test/src/backend/group.dart';
11 import 'package:test/src/backend/invoker.dart';
12 import 'package:test/src/backend/live_test.dart';
13 import 'package:test/src/backend/metadata.dart';
14 import 'package:test/src/backend/state.dart';
15 import 'package:test/src/backend/suite.dart';
16 import 'package:test/src/runner/vm/isolate_listener.dart';
17 import 'package:test/src/runner/vm/isolate_test.dart';
18 import 'package:test/src/util/remote_exception.dart';
19 import 'package:test/test.dart';
20
21 import '../utils.dart';
22
23 /// An isolate that's been spun up for the current test.
24 ///
25 /// This is tracked so that it can be killed once the test is done.
26 Isolate _isolate;
27
28 /// A live test that's running for the current test.
29 ///
30 /// This is tracked so that it can be closed once the test is done.
31 LiveTest _liveTest;
32
33 void main() {
34 tearDown(() {
35 if (_isolate != null) _isolate.kill();
36 _isolate = null;
37
38 if (_liveTest != null) _liveTest.close();
39 _liveTest = null;
40 });
41
42 test("sends a list of available tests and groups on startup", () async {
43 var response = await (await _spawnIsolate(_successfulTests)).first;
44 expect(response, containsPair("type", "success"));
45 expect(response, contains("root"));
46
47 var root = response["root"];
48 expect(root, containsPair("type", "group"));
49 expect(root, containsPair("name", null));
50
51 var tests = root["entries"];
52 expect(tests, hasLength(3));
53 expect(tests[0], containsPair("name", "successful 1"));
54 expect(tests[1], containsPair("name", "successful 2"));
55 expect(tests[2], containsPair("type", "group"));
56 expect(tests[2], containsPair("name", "successful"));
57 expect(tests[2], contains("entries"));
58 expect(tests[2]["entries"][0], containsPair("name", "successful 3"));
59 });
60
61 test("waits for a returned future sending a response", () async {
62 var response = await (await _spawnIsolate(_asyncTests)).first;
63 expect(response, containsPair("type", "success"));
64 expect(response, contains("root"));
65
66 var tests = response["root"]["entries"];
67 expect(tests, hasLength(3));
68 expect(tests[0], containsPair("name", "successful 1"));
69 expect(tests[1], containsPair("name", "successful 2"));
70 expect(tests[2], containsPair("name", "successful 3"));
71 });
72
73 test("sends an error response if loading fails", () async {
74 var response = await (await _spawnIsolate(_loadError)).first;
75 expect(response, containsPair("type", "error"));
76 expect(response, contains("error"));
77
78 var error = RemoteException.deserialize(response["error"]).error;
79 expect(error.message, equals("oh no"));
80 expect(error.type, equals("String"));
81 });
82
83 test("sends an error response on a NoSuchMethodError", () async {
84 var response = await (await _spawnIsolate(_noSuchMethodError)).first;
85 expect(response, containsPair("type", "loadException"));
86 expect(response,
87 containsPair("message", "No top-level main() function defined."));
88 });
89
90 test("sends an error response on non-function main", () async {
91 var response = await (await _spawnIsolate(_nonFunction)).first;
92 expect(response, containsPair("type", "loadException"));
93 expect(response,
94 containsPair("message", "Top-level main getter is not a function."));
95 });
96
97 test("sends an error response on wrong-arity main", () async {
98 var response = await (await _spawnIsolate(_wrongArity)).first;
99 expect(response, containsPair("type", "loadException"));
100 expect(
101 response,
102 containsPair(
103 "message",
104 "Top-level main() function takes arguments."));
105 });
106
107 group("in a successful test", () {
108 test("the state changes from pending to running to complete", () async {
109 var liveTest = await _isolateTest(_successfulTests);
110 liveTest.onError.listen(expectAsync((_) {}, count: 0));
111
112 expect(liveTest.state,
113 equals(const State(Status.pending, Result.success)));
114
115 var future = liveTest.run();
116 expect(liveTest.state,
117 equals(const State(Status.running, Result.success)));
118
119 await future;
120 expect(liveTest.state,
121 equals(const State(Status.complete, Result.success)));
122 });
123
124 test("onStateChange fires for each state change", () async {
125 var liveTest = await _isolateTest(_successfulTests);
126 liveTest.onError.listen(expectAsync((_) {}, count: 0));
127
128 var first = true;
129 liveTest.onStateChange.listen(expectAsync((state) {
130 if (first) {
131 expect(state.status, equals(Status.running));
132 first = false;
133 } else {
134 expect(state.status, equals(Status.complete));
135 }
136 expect(state.result, equals(Result.success));
137 }, count: 2, max: 2));
138
139 await liveTest.run();
140 });
141 });
142
143 group("in a test with failures", () {
144 test("a failure reported causes the test to fail", () async {
145 var liveTest = await _isolateTest(_failingTest);
146 expectSingleFailure(liveTest);
147 await liveTest.run();
148 });
149
150 test("a failure reported asynchronously after the test causes it to error",
151 () async {
152 var liveTest = await _isolateTest(_failAfterSucceedTest);
153 expectStates(liveTest, [
154 const State(Status.running, Result.success),
155 const State(Status.complete, Result.success),
156 const State(Status.complete, Result.failure),
157 const State(Status.complete, Result.error)
158 ]);
159
160 expectErrors(liveTest, [(error) {
161 expect(lastState,
162 equals(const State(Status.complete, Result.failure)));
163 expect(error, isTestFailure("oh no"));
164 }, (error) {
165 expect(lastState, equals(const State(Status.complete, Result.error)));
166 expect(error, isRemoteException(
167 "This test failed after it had already completed. Make sure to "
168 "use [expectAsync]\n"
169 "or the [completes] matcher when testing async code."));
170 }]);
171
172 await liveTest.run();
173 });
174
175 test("multiple asynchronous failures are reported", () async {
176 var liveTest = await _isolateTest(_multiFailTest);
177 expectStates(liveTest, [
178 const State(Status.running, Result.success),
179 const State(Status.complete, Result.failure)
180 ]);
181
182 expectErrors(liveTest, [(error) {
183 expect(lastState.status, equals(Status.complete));
184 expect(error, isTestFailure("one"));
185 }, (error) {
186 expect(error, isTestFailure("two"));
187 }, (error) {
188 expect(error, isTestFailure("three"));
189 }, (error) {
190 expect(error, isTestFailure("four"));
191 }]);
192
193 await liveTest.run();
194 });
195 });
196
197 group("in a test with errors", () {
198 test("an error reported causes the test to error", () async {
199 var liveTest = await _isolateTest(_errorTest);
200 expectStates(liveTest, [
201 const State(Status.running, Result.success),
202 const State(Status.complete, Result.error)
203 ]);
204
205 expectErrors(liveTest, [(error) {
206 expect(lastState.status, equals(Status.complete));
207 expect(error, isRemoteException("oh no"));
208 }]);
209
210 await liveTest.run();
211 });
212
213 test("an error reported asynchronously after the test causes it to error",
214 () async {
215 var liveTest = await _isolateTest(_errorAfterSucceedTest);
216 expectStates(liveTest, [
217 const State(Status.running, Result.success),
218 const State(Status.complete, Result.success),
219 const State(Status.complete, Result.error)
220 ]);
221
222 expectErrors(liveTest, [(error) {
223 expect(lastState,
224 equals(const State(Status.complete, Result.error)));
225 expect(error, isRemoteException("oh no"));
226 }, (error) {
227 expect(error, isRemoteException(
228 "This test failed after it had already completed. Make sure to "
229 "use [expectAsync]\n"
230 "or the [completes] matcher when testing async code."));
231 }]);
232
233 await liveTest.run();
234 });
235
236 test("multiple asynchronous errors are reported", () async {
237 var liveTest = await _isolateTest(_multiErrorTest);
238 expectStates(liveTest, [
239 const State(Status.running, Result.success),
240 const State(Status.complete, Result.error)
241 ]);
242
243 expectErrors(liveTest, [(error) {
244 expect(lastState.status, equals(Status.complete));
245 expect(error, isRemoteException("one"));
246 }, (error) {
247 expect(error, isRemoteException("two"));
248 }, (error) {
249 expect(error, isRemoteException("three"));
250 }, (error) {
251 expect(error, isRemoteException("four"));
252 }]);
253
254 await liveTest.run();
255 });
256 });
257
258 test("forwards a test's prints", () async {
259 var liveTest = await _isolateTest(_printTest);
260 expect(liveTest.onPrint.take(2).toList(),
261 completion(equals(["Hello,", "world!"])));
262
263 await liveTest.run();
264 });
265 }
266
267 /// Loads the first test defined in [entryPoint] in another isolate.
268 ///
269 /// This test will be automatically closed when the test is finished.
270 Future<LiveTest> _isolateTest(void entryPoint(SendPort sendPort)) async {
271 var response = await (await _spawnIsolate(entryPoint)).first;
272 expect(response, containsPair("type", "success"));
273
274 var testMap = response["root"]["entries"].first;
275 expect(testMap, containsPair("type", "test"));
276 var metadata = new Metadata.deserialize(testMap["metadata"]);
277 var test = new IsolateTest(testMap["name"], metadata, testMap["sendPort"]);
278 var suite = new Suite(new Group.root([test]));
279 _liveTest = test.load(suite);
280 return _liveTest;
281 }
282
283 /// Spawns an isolate from [entryPoint], sends it a new [SendPort], and returns
284 /// the corresponding [ReceivePort].
285 ///
286 /// This isolate will be automatically killed when the test is finished.
287 Future<ReceivePort> _spawnIsolate(void entryPoint(SendPort sendPort)) async {
288 var receivePort = new ReceivePort();
289 var isolate = await Isolate.spawn(entryPoint, receivePort.sendPort);
290 _isolate = isolate;
291 return receivePort;
292 }
293
294 /// An isolate entrypoint that throws immediately.
295 void _loadError(SendPort sendPort) {
296 IsolateListener.start(sendPort, new Metadata(), () => () => throw 'oh no');
297 }
298
299 /// An isolate entrypoint that throws a NoSuchMethodError.
300 void _noSuchMethodError(SendPort sendPort) {
301 IsolateListener.start(sendPort, new Metadata(), () =>
302 throw new NoSuchMethodError(null, #main, [], {}));
303 }
304
305 /// An isolate entrypoint that returns a non-function.
306 void _nonFunction(SendPort sendPort) {
307 IsolateListener.start(sendPort, new Metadata(), () => null);
308 }
309
310 /// An isolate entrypoint that returns a function with the wrong arity.
311 void _wrongArity(SendPort sendPort) {
312 IsolateListener.start(sendPort, new Metadata(), () => (_) {});
313 }
314
315 /// An isolate entrypoint that defines three tests that succeed.
316 void _successfulTests(SendPort sendPort) {
317 IsolateListener.start(sendPort, new Metadata(), () => () {
318 test("successful 1", () {});
319 test("successful 2", () {});
320 group("successful", () => test("3", () {}));
321 });
322 }
323
324 /// An isolate entrypoint that defines three tests asynchronously.
325 void _asyncTests(SendPort sendPort) {
326 IsolateListener.start(sendPort, new Metadata(), () => () {
327 return new Future(() {
328 test("successful 1", () {});
329
330 return new Future(() {
331 test("successful 2", () {});
332
333 return new Future(() {
334 test("successful 3", () {});
335 });
336 });
337 });
338 });
339 }
340
341 /// An isolate entrypoint that defines a test that fails.
342 void _failingTest(SendPort sendPort) {
343 IsolateListener.start(sendPort, new Metadata(), () => () {
344 test("failure", () => throw new TestFailure('oh no'));
345 });
346 }
347
348 /// An isolate entrypoint that defines a test that fails after succeeding.
349 void _failAfterSucceedTest(SendPort sendPort) {
350 IsolateListener.start(sendPort, new Metadata(), () => () {
351 test("fail after succeed", () {
352 pumpEventQueue().then((_) {
353 throw new TestFailure('oh no');
354 });
355 });
356 });
357 }
358
359 /// An isolate entrypoint that defines a test that fails multiple times.
360 void _multiFailTest(SendPort sendPort) {
361 IsolateListener.start(sendPort, new Metadata(), () => () {
362 test("multiple failures", () {
363 Invoker.current.addOutstandingCallback();
364 new Future(() => throw new TestFailure("one"));
365 new Future(() => throw new TestFailure("two"));
366 new Future(() => throw new TestFailure("three"));
367 new Future(() => throw new TestFailure("four"));
368 });
369 });
370 }
371
372 /// An isolate entrypoint that defines a test that errors.
373 void _errorTest(SendPort sendPort) {
374 IsolateListener.start(sendPort, new Metadata(), () => () {
375 test("error", () => throw 'oh no');
376 });
377 }
378
379 /// An isolate entrypoint that defines a test that errors after succeeding.
380 void _errorAfterSucceedTest(SendPort sendPort) {
381 IsolateListener.start(sendPort, new Metadata(), () => () {
382 test("error after succeed", () {
383 pumpEventQueue().then((_) {
384 throw 'oh no';
385 });
386 });
387 });
388 }
389
390 /// An isolate entrypoint that defines a test that errors multiple times.
391 void _multiErrorTest(SendPort sendPort) {
392 IsolateListener.start(sendPort, new Metadata(), () => () {
393 test("multiple errors", () {
394 Invoker.current.addOutstandingCallback();
395 new Future(() => throw "one");
396 new Future(() => throw "two");
397 new Future(() => throw "three");
398 new Future(() => throw "four");
399 });
400 });
401 }
402
403 /// An isolate entrypoint that defines a test that prints twice.
404 void _printTest(SendPort sendPort) {
405 IsolateListener.start(sendPort, new Metadata(), () => () {
406 test("prints", () {
407 print("Hello,");
408 return new Future(() => print("world!"));
409 });
410 });
411 }
412
OLDNEW
« no previous file with comments | « test/runner/engine_test.dart ('k') | test/runner/load_suite_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698