OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013, 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 // Helper functions and classes for running a set of unittests in a | |
6 // remote isolate. | |
7 // Used to test Isolate.spawn because dartium/drt does not allow it in the DOM | |
8 // isolate. | |
9 | |
10 import "dart:isolate"; | |
11 import "package:unittest/unittest.dart"; | |
12 import "dart:mirrors"; | |
13 | |
14 /** | |
15 * Use this function at the beginning of the main method: | |
16 * | |
17 * void main([args, port]) { | |
18 * if (testRemote(main, port)) return; | |
19 * // the usual test. | |
20 * } | |
21 */ | |
siva
2013/11/14 17:21:08
I find this a little tricky, you probably did it t
Lasse Reichstein Nielsen
2013/11/15 14:57:45
Minimizing changes was a goal, yes :) Didn't succe
| |
22 bool testRemote(Function main, SendPort port) { | |
23 if (port == null) { | |
24 return new LocalTests().run(main); | |
25 } else { | |
26 unittestConfiguration = new RemoteConfiguration(port); | |
27 return false; | |
28 } | |
29 } | |
30 | |
31 | |
32 class LocalTests { | |
33 final ReceivePort _port = new ReceivePort(); | |
34 final Map<String, Function> _testBody = new Map<String, Function>(); | |
35 | |
36 bool run(Function main) { | |
37 ClosureMirror closure = reflect(main); | |
38 LibraryMirror library = closure.function.owner; | |
39 try { | |
40 Isolate.spawnUri(library.uri, null, _port.sendPort); | |
41 _port.listen(remoteAction); | |
42 return true; | |
43 } catch (e) { | |
44 // spawnUri is only supported by dart2js if web workers are available. | |
45 // If the spawnUri fails, run the tests locally instead, since we are | |
46 // not in a browser anyway. | |
47 return false; | |
48 } | |
49 } | |
50 | |
51 void remoteAction(message) { | |
52 switch (message[0]) { | |
53 case "testStart": | |
54 String name = message[1]; | |
55 test(name, () { | |
56 _testBody[name] = expectAsync2((result, message) { | |
57 if (result == FAIL) { | |
58 fail(message); | |
59 } else if (result == ERROR) { | |
60 throw message; | |
61 } | |
62 _testBody.remove(name); | |
63 }); | |
64 }); | |
65 break; | |
66 case "testResult": | |
67 String name = message[1]; | |
68 Function completer = _testBody[name]; | |
69 completer(message[2], message[3]); | |
70 break; | |
71 case "testResultChanged": | |
72 throw new UnsupportedError("result change after the fact?"); | |
73 case "logMessage": | |
74 break; // Ignore. | |
75 case "summary": | |
76 throw message[1]; // Uncaught error. | |
77 case "done": | |
78 _port.close(); | |
79 break; | |
80 } | |
81 } | |
82 } | |
83 | |
84 | |
85 class RemoteConfiguration implements Configuration { | |
86 final SendPort _port; | |
87 Duration timeout = const Duration(minutes: 2); | |
88 | |
89 RemoteConfiguration(this._port); | |
90 | |
91 bool get autoStart => true; | |
92 | |
93 void onInit() { } | |
94 | |
95 void onStart() { } | |
96 | |
97 void onTestStart(TestCase testCase) { | |
98 _port.send(["testStart", testCase.description]); | |
99 } | |
100 | |
101 void onTestResult(TestCase testCase) { | |
102 _port.send(["testResult", testCase.description, | |
103 testCase.result, testCase.message]); | |
104 } | |
105 | |
106 void onTestResultChanged(TestCase testCase) { | |
107 _port.send(["testResultChanged", testCase.description, | |
108 testCase.result, testCase.message]); | |
109 } | |
110 | |
111 void onLogMessage(TestCase testCase, String message) { | |
112 _port.send(["logMessage", testCase.description, message]); | |
113 } | |
114 | |
115 void onDone(bool success) { | |
116 _port.send(["done", success]); | |
117 } | |
118 | |
119 void onSummary(int passed, int failed, int errors, List<TestCase> results, | |
120 String uncaughtError) { | |
121 if (uncaughtError != null) { | |
122 _port.send(["summary", uncaughtError]); | |
123 } | |
124 } | |
125 } | |
OLD | NEW |