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 @TestOn("vm") | |
kevmoo
2015/11/21 03:37:17
several type errors, failures etc...you're on this
nweiz
2015/11/23 22:24:08
Yes.
| |
6 | |
7 import 'dart:convert'; | |
8 | |
9 import 'package:path/path.dart' as p; | |
10 import 'package:scheduled_test/descriptor.dart' as d; | |
11 import 'package:scheduled_test/scheduled_process.dart'; | |
12 import 'package:scheduled_test/scheduled_stream.dart'; | |
13 import 'package:scheduled_test/scheduled_test.dart'; | |
14 | |
15 import 'package:test/src/runner/version.dart'; | |
16 | |
17 import '../io.dart'; | |
18 | |
19 final _start = { | |
20 "type": "start", | |
21 "protocolVersion": "0.1.0", | |
22 "runnerVersion": testVersion | |
23 }; | |
24 | |
25 void main() { | |
26 useSandbox(); | |
27 | |
28 test("runs several successful tests and reports when each completes", () { | |
29 _expectReport( | |
30 """ | |
31 test('success 1', () {}); | |
32 test('success 2', () {}); | |
33 test('success 3', () {});""", | |
34 [ | |
35 _start, | |
36 _testStart(0, "loading test.dart"), | |
37 _testDone(0, hidden: true), | |
38 _testStart(1, "success 1"), | |
39 _testDone(1), | |
40 _testStart(2, "success 2"), | |
41 _testDone(2), | |
42 _testStart(3, "success 3"), | |
43 _testDone(3), | |
44 _done() | |
45 ]); | |
46 }); | |
47 | |
48 test("runs several failing tests and reports when each fails", () { | |
49 _expectReport( | |
50 """ | |
51 test('failure 1', () => throw new TestFailure('oh no')); | |
52 test('failure 2', () => throw new TestFailure('oh no')); | |
53 test('failure 3', () => throw new TestFailure('oh no'));""", | |
54 """ | |
55 {"type":"enter","name":"enter","time":\\d+} | |
56 {"type":"start","name":"failure 1","time":\\d+} | |
57 {"type":"fail","name":"failure 1","time":\\d+,"failMessage":"oh no","sta | |
58 ckTrace":"test.dart 6:33 main.<fn>\\\\n"} | |
59 {"type":"start","name":"failure 2","time":\\d+} | |
60 {"type":"fail","name":"failure 2","time":\\d+,"failMessage":"oh no","sta | |
61 ckTrace":"test.dart 7:33 main.<fn>\\\\n"} | |
62 {"type":"start","name":"failure 3","time":\\d+} | |
63 {"type":"fail","name":"failure 3","time":\\d+,"failMessage":"oh no","sta | |
64 ckTrace":"test.dart 8:33 main.<fn>\\\\n"} | |
65 {"type":"exit","name":"exit","time":\\d+}"""); | |
66 }); | |
67 | |
68 test("includes the full stack trace with --verbose-trace", () { | |
69 d | |
70 .file( | |
71 "test.dart", | |
72 """ | |
73 import 'dart:async'; | |
74 | |
75 import 'package:test/test.dart'; | |
76 | |
77 void main() { | |
78 test("failure", () => throw "oh no"); | |
79 } | |
80 """) | |
81 .create(); | |
82 | |
83 var test = runTest(["--verbose-trace", "test.dart"], compact: true); | |
84 test.stdout.expect(consumeThrough(contains("dart:isolate-patch"))); | |
85 test.shouldExit(1); | |
86 }); | |
87 | |
88 test("runs failing tests along with successful tests", () { | |
89 _expectReport( | |
90 """ | |
91 test('failure 1', () => throw new TestFailure('oh no')); | |
92 test('success 1', () {}); | |
93 test('failure 2', () => throw new TestFailure('oh no')); | |
94 test('success 2', () {});""", | |
95 """ | |
96 {"type":"enter","name":"enter","time":\\d+} | |
97 {"type":"start","name":"failure 1","time":\\d+} | |
98 {"type":"fail","name":"failure 1","time":\\d+,"failMessage":"oh no","sta | |
99 ckTrace":"test.dart 6:33 main.<fn>\\\\n"} | |
100 {"type":"start","name":"success 1","time":\\d+} | |
101 {"type":"pass","name":"success 1","time":\\d+} | |
102 {"type":"start","name":"failure 2","time":\\d+} | |
103 {"type":"fail","name":"failure 2","time":\\d+,"failMessage":"oh no","sta | |
104 ckTrace":"test.dart 8:33 main.<fn>\\\\n"} | |
105 {"type":"start","name":"success 2","time":\\d+} | |
106 {"type":"pass","name":"success 2","time":\\d+} | |
107 {"type":"exit","name":"exit","time":\\d+} | |
108 """); | |
109 }); | |
110 | |
111 test("always prints the full test name", () { | |
112 _expectReport( | |
113 """ | |
114 test( | |
115 'really gosh dang long test name. Even longer than that. No, yet ' | |
116 'longer. A little more... okay, that should do it.', | |
117 () {});""", | |
118 """ | |
119 {"type":"enter","name":"enter","time":\\d+} | |
120 {"type":"start","name":"really gosh dang long test name. Even longer tha | |
121 n that. No, yet longer. A little more... okay, that should do it.","time":\\d+} | |
122 {"type":"pass","name":"really gosh dang long test name. Even longer than | |
123 that. No, yet longer. A little more... okay, that should do it.","time":\\d+} | |
124 {"type":"exit","name":"exit","time":\\d+} | |
125 """); | |
126 }); | |
127 | |
128 test("gracefully handles multiple test failures in a row", () { | |
129 _expectReport( | |
130 """ | |
131 // This completer ensures that the test isolate isn't killed until all | |
132 // errors have been thrown. | |
133 var completer = new Completer(); | |
134 test('failures', () { | |
135 new Future.microtask(() => throw 'first error'); | |
136 new Future.microtask(() => throw 'second error'); | |
137 new Future.microtask(() => throw 'third error'); | |
138 new Future.microtask(completer.complete); | |
139 }); | |
140 test('wait', () => completer.future);""", | |
141 """ | |
142 {"type":"enter","name":"enter","time":\\d+} | |
143 {"type":"start","name":"failures","time":\\d+} | |
144 {"type":"error","name":"failures","time":\\d+,"errorMessage":"first erro | |
145 r","stackTrace":"test.dart 10:38 main.<fn>.<fn>\\\\n===== asynchronous gap ==== | |
146 =======================\\\\ndart:async Future.Future.microtask\\\\ntest.da | |
147 rt 10:15 main.<fn>\\\\n"} | |
148 {"type":"error","name":"failures","time":\\d+,"errorMessage":"second err | |
149 or","stackTrace":"test.dart 11:38 main.<fn>.<fn>\\\\n===== asynchronous gap === | |
150 ========================\\\\ndart:async Future.Future.microtask\\\\ntest.d | |
151 art 11:15 main.<fn>\\\\n"} | |
152 {"type":"error","name":"failures","time":\\d+,"errorMessage":"third erro | |
153 r","stackTrace":"test.dart 12:38 main.<fn>.<fn>\\\\n===== asynchronous gap ==== | |
154 =======================\\\\ndart:async Future.Future.microtask\\\\ntest.da | |
155 rt 12:15 main.<fn>\\\\n"} | |
156 {"type":"start","name":"wait","time":\\d+} | |
157 {"type":"pass","name":"wait","time":\\d+} | |
158 {"type":"exit","name":"exit","time":\\d+} | |
159 """); | |
160 }); | |
161 | |
162 group("print:", () { | |
163 test("handles multiple prints", () { | |
164 _expectReport( | |
165 """ | |
166 test('test', () { | |
167 print("one"); | |
168 print("two"); | |
169 print("three"); | |
170 print("four"); | |
171 });""", | |
172 """ | |
173 {"type":"enter","name":"enter","time":\\d+} | |
174 {"type":"start","name":"test","time":\\d+} | |
175 {"type":"print","name":"test","time":\\d+,"message":"one"} | |
176 {"type":"print","name":"test","time":\\d+,"message":"two"} | |
177 {"type":"print","name":"test","time":\\d+,"message":"three"} | |
178 {"type":"print","name":"test","time":\\d+,"message":"four"} | |
179 {"type":"pass","name":"test","time":\\d+} | |
180 {"type":"exit","name":"exit","time":\\d+} | |
181 """); | |
182 }); | |
183 | |
184 test("handles a print after the test completes", () { | |
185 _expectReport( | |
186 """ | |
187 // This completer ensures that the test isolate isn't killed until all | |
188 // prints have happened. | |
189 var testDone = new Completer(); | |
190 var waitStarted = new Completer(); | |
191 test('test', () async { | |
192 waitStarted.future.then((_) { | |
193 new Future(() => print("one")); | |
194 new Future(() => print("two")); | |
195 new Future(() => print("three")); | |
196 new Future(() => print("four")); | |
197 new Future(testDone.complete); | |
198 }); | |
199 }); | |
200 | |
201 test('wait', () { | |
202 waitStarted.complete(); | |
203 return testDone.future; | |
204 });""", | |
205 """ | |
206 {"type":"enter","name":"enter","time":\\d+} | |
207 {"type":"start","name":"test","time":\\d+} | |
208 {"type":"pass","name":"test","time":\\d+} | |
209 {"type":"start","name":"wait","time":\\d+} | |
210 {"type":"print","name":"test","time":\\d+,"message":"one"} | |
211 {"type":"print","name":"test","time":\\d+,"message":"two"} | |
212 {"type":"print","name":"test","time":\\d+,"message":"three"} | |
213 {"type":"print","name":"test","time":\\d+,"message":"four"} | |
214 {"type":"pass","name":"wait","time":\\d+} | |
215 {"type":"exit","name":"exit","time":\\d+} | |
216 """); | |
217 }); | |
218 | |
219 test("interleaves prints and errors", () { | |
220 _expectReport( | |
221 """ | |
222 // This completer ensures that the test isolate isn't killed until all | |
223 // prints have happened. | |
224 var completer = new Completer(); | |
225 test('test', () { | |
226 scheduleMicrotask(() { | |
227 print("three"); | |
228 print("four"); | |
229 throw "second error"; | |
230 }); | |
231 | |
232 scheduleMicrotask(() { | |
233 print("five"); | |
234 print("six"); | |
235 completer.complete(); | |
236 }); | |
237 | |
238 print("one"); | |
239 print("two"); | |
240 throw "first error"; | |
241 }); | |
242 | |
243 test('wait', () => completer.future);""", | |
244 """ | |
245 {"type":"enter","name":"enter","time":\\d+} | |
246 {"type":"start","name":"test","time":\\d+} | |
247 {"type":"print","name":"test","time":\\d+,"message":"one"} | |
248 {"type":"print","name":"test","time":\\d+,"message":"two"} | |
249 {"type":"error","name":"test","time":\\d+,"errorMessage":"first error"," | |
250 stackTrace":"test.dart 24:11 main.<fn>\\\\n"} | |
251 {"type":"print","name":"test","time":\\d+,"message":"three"} | |
252 {"type":"print","name":"test","time":\\d+,"message":"four"} | |
253 {"type":"error","name":"test","time":\\d+,"errorMessage":"second error", | |
254 "stackTrace":"test.dart 13:13 main.<fn>.<fn>\\\\n===== asynchronous gap ======= | |
255 ====================\\\\ndart:async scheduleMicrotask\\\\ntest.dart 10:11 | |
256 main.<fn>\\\\n"} | |
257 {"type":"print","name":"test","time":\\d+,"message":"five"} | |
258 {"type":"print","name":"test","time":\\d+,"message":"six"} | |
259 {"type":"start","name":"wait","time":\\d+} | |
260 {"type":"pass","name":"wait","time":\\d+} | |
261 {"type":"exit","name":"exit","time":\\d+} | |
262 """); | |
263 }); | |
264 }); | |
265 | |
266 group("skip:", () { | |
267 test("displays skipped tests separately", () { | |
268 _expectReport( | |
269 """ | |
270 test('skip 1', () {}, skip: true); | |
271 test('skip 2', () {}, skip: true); | |
272 test('skip 3', () {}, skip: true);""", | |
273 """ | |
274 {"type":"enter","name":"enter","time":\\d+} | |
275 {"type":"start","name":"skip 1","time":\\d+} | |
276 {"type":"skip","name":"skip 1","time":\\d+} | |
277 {"type":"start","name":"skip 2","time":\\d+} | |
278 {"type":"skip","name":"skip 2","time":\\d+} | |
279 {"type":"start","name":"skip 3","time":\\d+} | |
280 {"type":"skip","name":"skip 3","time":\\d+} | |
281 {"type":"exit","name":"exit","time":\\d+} | |
282 """); | |
283 }); | |
284 | |
285 test("runs skipped tests along with successful tests", () { | |
286 _expectReport( | |
287 """ | |
288 test('skip 1', () {}, skip: true); | |
289 test('success 1', () {}); | |
290 test('skip 2', () {}, skip: true); | |
291 test('success 2', () {});""", | |
292 """ | |
293 {"type":"enter","name":"enter","time":\\d+} | |
294 {"type":"start","name":"skip 1","time":\\d+} | |
295 {"type":"skip","name":"skip 1","time":\\d+} | |
296 {"type":"start","name":"success 1","time":\\d+} | |
297 {"type":"pass","name":"success 1","time":\\d+} | |
298 {"type":"start","name":"skip 2","time":\\d+} | |
299 {"type":"skip","name":"skip 2","time":\\d+} | |
300 {"type":"start","name":"success 2","time":\\d+} | |
301 {"type":"pass","name":"success 2","time":\\d+} | |
302 {"type":"exit","name":"exit","time":\\d+} | |
303 """); | |
304 }); | |
305 | |
306 test("runs skipped tests along with successful and failing tests", () { | |
307 _expectReport( | |
308 """ | |
309 test('failure 1', () => throw new TestFailure('oh no')); | |
310 test('skip 1', () {}, skip: true); | |
311 test('success 1', () {}); | |
312 test('failure 2', () => throw new TestFailure('oh no')); | |
313 test('skip 2', () {}, skip: true); | |
314 test('success 2', () {});""", | |
315 """ | |
316 {"type":"enter","name":"enter","time":\\d+} | |
317 {"type":"start","name":"failure 1","time":\\d+} | |
318 {"type":"fail","name":"failure 1","time":\\d+,"failMessage":"oh no","s | |
319 tackTrace":"test.dart 6:35 main.<fn>\\\\n"} | |
320 {"type":"start","name":"skip 1","time":\\d+} | |
321 {"type":"skip","name":"skip 1","time":1\\d+} | |
322 {"type":"start","name":"success 1","time":\\d+} | |
323 {"type":"pass","name":"success 1","time":\\d+} | |
324 {"type":"start","name":"failure 2","time":\\d+} | |
325 {"type":"fail","name":"failure 2","time":\\d+,"failMessage":"oh no","s | |
326 tackTrace":"test.dart 9:35 main.<fn>\\\\n"} | |
327 {"type":"start","name":"skip 2","time":\\d+} | |
328 {"type":"skip","name":"skip 2","time":\\d+} | |
329 {"type":"start","name":"success 2","time":\\d+} | |
330 {"type":"pass","name":"success 2","time":\\d+} | |
331 {"type":"exit","name":"exit","time":\\d+} | |
332 """); | |
333 }); | |
334 | |
335 test("displays the skip reason if available", () { | |
336 _expectReport( | |
337 """ | |
338 test('skip 1', () {}, skip: 'some reason'); | |
339 test('skip 2', () {}, skip: 'or another');""", | |
340 """ | |
341 {"type":"enter","name":"enter","time":\\d+} | |
342 {"type":"start","name":"skip 1","time":\\d+} | |
343 {"type":"skip","name":"skip 1","time":\\d+,"reason":"some reason"} | |
344 {"type":"start","name":"skip 2","time":\\d+} | |
345 {"type":"skip","name":"skip 2","time":\\d+,"reason":"or another"} | |
346 {"type":"exit","name":"exit","time":\\d+} | |
347 """); | |
348 }); | |
349 }); | |
350 } | |
351 | |
352 void _expectReport(String tests, List<Map> expected) { | |
353 var dart = """ | |
354 import 'dart:async'; | |
355 | |
356 import 'package:test/test.dart'; | |
357 | |
358 void main() { | |
359 $tests | |
360 } | |
361 """; | |
362 | |
363 d.file("test.dart", dart).create(); | |
364 | |
365 var test = runTest(["test.dart"], reporter: "json"); | |
366 test.shouldExit(); | |
367 | |
368 schedule(() async { | |
369 var stdoutLines = await test.stdoutStream().toList(); | |
370 | |
371 expect(stdoutLines.length, equals(expected.length), | |
372 reason: "Expected $stdoutLines to match $expected."); | |
373 | |
374 // Remove excess trailing whitespace. | |
375 for (var i = 0; i < stdoutLines.length; i++) { | |
376 var event = JSON.decode(stdoutLines[i]); | |
377 expect(event.remove("time"), new isInstanceOf<int>()); | |
378 expect(event, equals(expected[i])); | |
379 } | |
380 }); | |
381 } | |
382 | |
383 Map _testStart(int id, String name, {skip}) { | |
384 var metadata; | |
385 if (skip == true) { | |
386 metadata = {"skip": true, "skipReason": null}; | |
387 } else if (skip is String) { | |
388 metadata = {"skip": true, "skipReason": skip}; | |
389 } else { | |
390 metadata = {"skip": false, "skipReason": null}; | |
391 } | |
392 | |
393 return { | |
394 "type": "testStart", | |
395 "test": {"id": id, "name": name, "metadata": metadata} | |
396 }; | |
397 } | |
398 | |
399 Map _testDone(int id, {String result, bool hidden: false}) { | |
400 result ??= "success"; | |
401 return {"type": "testDone", "testID": id, "result": result, "hidden": hidden}; | |
402 } | |
403 | |
404 Map _done({bool success: true}) => {"type": "done", "success": success}; | |
OLD | NEW |