OLD | NEW |
| (Empty) |
1 // Copyright (c) 2015, the Dartino 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.md file. | |
4 | |
5 /// Tests of 'package:fletchc/src/zone_helper.dart'. | |
6 library fletch_tests.zone_helper_tests; | |
7 | |
8 import 'dart:async'; | |
9 | |
10 import 'dart:isolate'; | |
11 | |
12 import 'package:fletchc/src/zone_helper.dart'; | |
13 | |
14 import 'package:expect/expect.dart'; | |
15 | |
16 import 'dart:io' show | |
17 Platform; | |
18 | |
19 final Uri fileWithCompileTimeError = | |
20 Uri.base.resolve("tests/fletch_tests/file_with_compile_time_error.dart"); | |
21 | |
22 /// Test that runGuarded completes with an error when a synchronous error is | |
23 /// thrown. | |
24 testEarlySyncError() { | |
25 bool threw = false; | |
26 return runGuarded(() { | |
27 throw "Early error"; | |
28 }, handleLateError: (e, s) { | |
29 throw "Broken"; | |
30 }).catchError((e) { | |
31 Expect.stringEquals("Early error", e); | |
32 threw = true; | |
33 }).then((_) { | |
34 Expect.isTrue(threw); | |
35 }); | |
36 } | |
37 | |
38 /// Test that runGuarded completes with an error when an asynchronous error is | |
39 /// thrown. | |
40 testEarlyAsyncError() { | |
41 bool threw = false; | |
42 return runGuarded(() { | |
43 return new Future.error("Early error"); | |
44 }, handleLateError: (e, s) { | |
45 throw "Broken"; | |
46 }).catchError((e) { | |
47 Expect.stringEquals("Early error", e); | |
48 threw = true; | |
49 }).then((_) { | |
50 Expect.isTrue(threw); | |
51 }); | |
52 } | |
53 | |
54 /// Test that handleLateError is invoked if a late asynchronous error occurs. | |
55 testLateError() { | |
56 Completer completer = new Completer(); | |
57 bool threw = false; | |
58 return runGuarded(() { | |
59 new Future(() { | |
60 throw "Late error"; | |
61 }); | |
62 return new Future.value(42); | |
63 }, handleLateError: (e, s) { | |
64 completer.complete(e); | |
65 }).catchError((_) { | |
66 threw = true; | |
67 }).then((value) { | |
68 Expect.isFalse(threw); | |
69 Expect.equals(42, value); | |
70 return completer.future; | |
71 }).then((String value) { | |
72 Expect.stringEquals("Late error", value); | |
73 }); | |
74 } | |
75 | |
76 /// Helper for [testUnhandledLateError]. | |
77 testUnhandledLateErrorIsolate(_) { | |
78 bool threw = false; | |
79 return runGuarded(() { | |
80 new Future(() { | |
81 throw "Late error"; | |
82 }); | |
83 return new Future.value(0); | |
84 }).catchError((_) { | |
85 threw = true; | |
86 }).then((_) { | |
87 Expect.isFalse(threw); | |
88 }); | |
89 } | |
90 | |
91 /// Test that a late asynchronous error is passed to the parent zone if no | |
92 /// handleLateError is provided (the parent zone being Zone.ROOT). | |
93 testUnhandledLateError() async { | |
94 Isolate isolate = | |
95 await Isolate.spawn(testUnhandledLateErrorIsolate, null, paused: true); | |
96 ReceivePort exitPort = new ReceivePort(); | |
97 ReceivePort errorPort = new ReceivePort(); | |
98 isolate | |
99 ..addOnExitListener(exitPort.sendPort) | |
100 ..setErrorsFatal(false) | |
101 ..addErrorListener(errorPort.sendPort); | |
102 acknowledgeControlMessages(isolate, resume: isolate.pauseCapability); | |
103 bool errorPortListenWasCalled = false; | |
104 await errorPort.listen((errorList) { | |
105 errorPort.close(); | |
106 errorPortListenWasCalled = true; | |
107 var lines = errorList[0].split("\n"); | |
108 if (lines.length > 1) { | |
109 // Bug (not getting the correct error from the system). | |
110 Expect.isTrue(lines[0].endsWith("Late error")); | |
111 } else { | |
112 Expect.stringEquals("Late error", errorList[0]); | |
113 } | |
114 isolate.kill(); | |
115 }).asFuture(); | |
116 bool exitPortListenWasCalled = false; | |
117 await exitPort.listen((message) { | |
118 exitPortListenWasCalled = true; | |
119 exitPort.close(); | |
120 Expect.isNull(message); | |
121 }).asFuture(); | |
122 Expect.isTrue(errorPortListenWasCalled); | |
123 Expect.isTrue(exitPortListenWasCalled); | |
124 print("Test succeeded."); | |
125 } | |
126 | |
127 /// Test that a bad test will fail, not crash the test runner. | |
128 testAlwaysFails() async { | |
129 await new Stream.fromIterable([null]).listen((_) { | |
130 throw "BROKEN"; | |
131 }).asFuture(); | |
132 } | |
133 | |
134 testCompileTimeError() async { | |
135 Isolate isolate; | |
136 ReceivePort exitPort = new ReceivePort(); | |
137 ReceivePort errorPort = new ReceivePort(); | |
138 ReceivePort port = new ReceivePort(); | |
139 | |
140 bool exited = false; | |
141 bool hadError = false; | |
142 var messageFromIsolate; | |
143 | |
144 Future exitFuture = exitPort.listen((_) { | |
145 exited = true; | |
146 exitPort.close(); | |
147 errorPort.close(); | |
148 port.close(); | |
149 }).asFuture(); | |
150 | |
151 Future errorFuture = errorPort.listen((List message) { | |
152 hadError = true; | |
153 var error = message[0]; | |
154 var stackTrace = message[1]; | |
155 if (stackTrace != null) { | |
156 print(stackTrace); | |
157 } | |
158 }).asFuture(); | |
159 | |
160 Future portFuture = port.listen((message) { | |
161 Expect.isNull(messageFromIsolate); | |
162 messageFromIsolate = message; | |
163 isolate.kill(); | |
164 }).asFuture(); | |
165 | |
166 // The call to spawnUri will pick up the default .packages packages config. | |
167 isolate = await Isolate.spawnUri( | |
168 fileWithCompileTimeError, <String>[], port.sendPort, paused: true, | |
169 checked: true); | |
170 | |
171 isolate.setErrorsFatal(true); | |
172 isolate.addOnExitListener(exitPort.sendPort); | |
173 isolate.addErrorListener(errorPort.sendPort); | |
174 await acknowledgeControlMessages(isolate, resume: isolate.pauseCapability); | |
175 await exitFuture; | |
176 await errorFuture; | |
177 await portFuture; | |
178 Expect.isTrue(exited); | |
179 Expect.isTrue(hadError); | |
180 Expect.isNotNull(messageFromIsolate); | |
181 | |
182 print("Test passed, got message: $messageFromIsolate"); | |
183 | |
184 // No-op call to let dart2js know this method is actually used. | |
185 testCompileTimeErrorHelper(null, () {}); | |
186 } | |
187 | |
188 testCompileTimeErrorHelper(SendPort port, void methodWithCompileTimeError()) { | |
189 return runGuarded(() { | |
190 methodWithCompileTimeError(); | |
191 }).catchError((e, s) { | |
192 port.send("Error in isolate: $e\nStack trace: $s"); | |
193 }); | |
194 } | |
OLD | NEW |