| OLD | NEW |
| (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 library unittest.runner.vm_listener; | |
| 6 | |
| 7 import 'dart:isolate'; | |
| 8 import 'dart:async'; | |
| 9 | |
| 10 import '../backend/declarer.dart'; | |
| 11 import '../backend/suite.dart'; | |
| 12 import '../backend/test.dart'; | |
| 13 import '../util/remote_exception.dart'; | |
| 14 import '../utils.dart'; | |
| 15 | |
| 16 /// A class that runs tests in a separate isolate and communicates the results | |
| 17 /// back to the main isolate. | |
| 18 class VmListener { | |
| 19 /// The test suite to run. | |
| 20 final Suite _suite; | |
| 21 | |
| 22 /// Extracts metadata about all the tests in the function returned by | |
| 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. | |
| 27 /// | |
| 28 /// Once that's done, this starts listening for commands about which tests to | |
| 29 /// run. | |
| 30 static void start(SendPort sendPort, Function getMain()) { | |
| 31 var main; | |
| 32 try { | |
| 33 main = getMain(); | |
| 34 } on NoSuchMethodError catch (_) { | |
| 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 | |
| 48 var declarer = new 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 | |
| 59 new VmListener._(new Suite("VmListener", declarer.tests)) | |
| 60 ._listen(sendPort); | |
| 61 } | |
| 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 | |
| 70 VmListener._(this._suite); | |
| 71 | |
| 72 /// Send information about [_suite] across [sendPort] and start listening for | |
| 73 /// commands to run the tests. | |
| 74 void _listen(SendPort sendPort) { | |
| 75 var tests = []; | |
| 76 for (var i = 0; i < _suite.tests.length; i++) { | |
| 77 var test = _suite.tests[i]; | |
| 78 var receivePort = new ReceivePort(); | |
| 79 tests.add({"name": test.name, "sendPort": receivePort.sendPort}); | |
| 80 | |
| 81 receivePort.listen((message) { | |
| 82 assert(message['command'] == 'run'); | |
| 83 _runTest(test, message['reply']); | |
| 84 }); | |
| 85 } | |
| 86 | |
| 87 sendPort.send({ | |
| 88 "type": "success", | |
| 89 "tests": tests | |
| 90 }); | |
| 91 } | |
| 92 | |
| 93 /// Runs [test] and send the results across [sendPort]. | |
| 94 void _runTest(Test test, SendPort sendPort) { | |
| 95 var liveTest = test.load(_suite); | |
| 96 | |
| 97 liveTest.onStateChange.listen((state) { | |
| 98 sendPort.send({ | |
| 99 "type": "state-change", | |
| 100 "status": state.status.name, | |
| 101 "result": state.result.name | |
| 102 }); | |
| 103 }); | |
| 104 | |
| 105 liveTest.onError.listen((asyncError) { | |
| 106 sendPort.send({ | |
| 107 "type": "error", | |
| 108 "error": RemoteException.serialize( | |
| 109 asyncError.error, asyncError.stackTrace) | |
| 110 }); | |
| 111 }); | |
| 112 | |
| 113 liveTest.run().then((_) => sendPort.send({"type": "complete"})); | |
| 114 } | |
| 115 } | |
| OLD | NEW |