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.vm_listener; | 5 library unittest.vm_listener; |
6 | 6 |
7 import 'dart:isolate'; | 7 import 'dart:isolate'; |
8 import 'dart:async'; | 8 import 'dart:async'; |
9 | 9 |
10 import 'declarer.dart'; | 10 import 'declarer.dart'; |
11 import 'remote_exception.dart'; | 11 import 'remote_exception.dart'; |
12 import 'suite.dart'; | 12 import 'suite.dart'; |
13 import 'test.dart'; | 13 import 'test.dart'; |
14 import 'utils.dart'; | |
14 | 15 |
15 /// A class that runs tests in a separate isolate and communicates the results | 16 /// A class that runs tests in a separate isolate and communicates the results |
16 /// back to the main isolate. | 17 /// back to the main isolate. |
17 class VmListener { | 18 class VmListener { |
18 /// The test suite to run. | 19 /// The test suite to run. |
19 final Suite _suite; | 20 final Suite _suite; |
20 | 21 |
21 /// Extracts metadata about all the tests in [main] and sends information | 22 /// Extracts metadata about all the tests in the function returned by |
22 /// about them over [sendPort]. | 23 /// [getMain] and sends information about them over [sendPort]. |
24 /// | |
25 /// The main function is wrapped in a closure so that we can handle it being | |
26 /// undefined here rather than in the generated code. | |
23 /// | 27 /// |
24 /// Once that's done, this starts listening for commands about which tests to | 28 /// Once that's done, this starts listening for commands about which tests to |
25 /// run. | 29 /// run. |
26 static void start(SendPort sendPort, main()) { | 30 static void start(SendPort sendPort, Function getMain()) { |
31 var main; | |
32 try { | |
33 main = getMain(); | |
34 } on NoSuchMethodError catch (error, stackTrace) { | |
kevmoo
2015/02/19 01:54:08
skip the stackTrace arg if it's not used
nweiz
2015/02/19 02:10:18
Done.
| |
35 _sendLoadException(sendPort, "No top-level main() function defined."); | |
36 return; | |
37 } | |
38 | |
39 if (main is! Function) { | |
40 _sendLoadException(sendPort, "Top-level main getter is not a function."); | |
41 return; | |
42 } else if (main is! AsyncFunction) { | |
43 _sendLoadException( | |
44 sendPort, "Top-level main() function takes arguments."); | |
45 return; | |
46 } | |
47 | |
27 var declarer = new Declarer(); | 48 var declarer = new Declarer(); |
28 runZoned(main, zoneValues: {#unittest.declarer: declarer}); | 49 try { |
50 runZoned(main, zoneValues: {#unittest.declarer: declarer}); | |
51 } catch (error, stackTrace) { | |
52 sendPort.send({ | |
53 "type": "error", | |
54 "error": RemoteException.serialize(error, stackTrace) | |
55 }); | |
56 return; | |
57 } | |
58 | |
29 new VmListener._(new Suite("VmListener", declarer.tests)) | 59 new VmListener._(new Suite("VmListener", declarer.tests)) |
30 ._listen(sendPort); | 60 ._listen(sendPort); |
31 } | 61 } |
32 | 62 |
63 /// Sends a message over [sendPort] indicating that the tests failed to load. | |
64 /// | |
65 /// [message] should describe the failure. | |
66 static void _sendLoadException(SendPort sendPort, String message) { | |
67 sendPort.send({"type": "loadException", "message": message}); | |
68 } | |
69 | |
33 VmListener._(this._suite); | 70 VmListener._(this._suite); |
34 | 71 |
35 /// Send information about [_suite] across [sendPort] and start listening for | 72 /// Send information about [_suite] across [sendPort] and start listening for |
36 /// commands to run the tests. | 73 /// commands to run the tests. |
37 void _listen(SendPort sendPort) { | 74 void _listen(SendPort sendPort) { |
38 var tests = []; | 75 var tests = []; |
39 for (var i = 0; i < _suite.tests.length; i++) { | 76 for (var i = 0; i < _suite.tests.length; i++) { |
40 var test = _suite.tests[i]; | 77 var test = _suite.tests[i]; |
41 var receivePort = new ReceivePort(); | 78 var receivePort = new ReceivePort(); |
42 tests.add({"name": test.name, "sendPort": receivePort.sendPort}); | 79 tests.add({"name": test.name, "sendPort": receivePort.sendPort}); |
43 | 80 |
44 receivePort.listen((message) { | 81 receivePort.listen((message) { |
45 assert(message['command'] == 'run'); | 82 assert(message['command'] == 'run'); |
46 _runTest(test, message['reply']); | 83 _runTest(test, message['reply']); |
47 }); | 84 }); |
48 } | 85 } |
49 | 86 |
50 sendPort.send(tests); | 87 sendPort.send({ |
88 "type": "success", | |
89 "tests": tests | |
90 }); | |
51 } | 91 } |
52 | 92 |
53 /// Runs [test] and send the results across [sendPort]. | 93 /// Runs [test] and send the results across [sendPort]. |
54 void _runTest(Test test, SendPort sendPort) { | 94 void _runTest(Test test, SendPort sendPort) { |
55 var liveTest = test.load(_suite); | 95 var liveTest = test.load(_suite); |
56 | 96 |
57 liveTest.onStateChange.listen((state) { | 97 liveTest.onStateChange.listen((state) { |
58 sendPort.send({ | 98 sendPort.send({ |
59 "type": "state-change", | 99 "type": "state-change", |
60 "status": state.status.name, | 100 "status": state.status.name, |
61 "result": state.result.name | 101 "result": state.result.name |
62 }); | 102 }); |
63 }); | 103 }); |
64 | 104 |
65 liveTest.onError.listen((asyncError) { | 105 liveTest.onError.listen((asyncError) { |
66 sendPort.send({ | 106 sendPort.send({ |
67 "type": "error", | 107 "type": "error", |
68 "error": RemoteException.serialize( | 108 "error": RemoteException.serialize( |
69 asyncError.error, asyncError.stackTrace) | 109 asyncError.error, asyncError.stackTrace) |
70 }); | 110 }); |
71 }); | 111 }); |
72 | 112 |
73 liveTest.run().then((_) => sendPort.send({"type": "complete"})); | 113 liveTest.run().then((_) => sendPort.send({"type": "complete"})); |
74 } | 114 } |
75 } | 115 } |
OLD | NEW |