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 import 'dart:async'; | |
6 | |
7 import 'package:fake_async/fake_async.dart'; | |
8 import 'package:unittest/src/backend/invoker.dart'; | |
9 import 'package:unittest/src/backend/state.dart'; | |
10 import 'package:unittest/src/backend/suite.dart'; | |
11 import 'package:unittest/unittest.dart'; | |
12 | |
13 import 'utils.dart'; | |
14 | |
15 void main() { | |
16 var suite; | |
17 setUp(() { | |
18 lastState = null; | |
19 suite = new Suite("suite", []); | |
20 }); | |
21 | |
22 group("Invoker.current", () { | |
23 var invoker = Invoker.current; | |
24 test("returns null outside of a test body", () { | |
25 expect(invoker, isNull); | |
26 }); | |
27 | |
28 test("returns the current invoker in a test body", () { | |
29 var invoker; | |
30 var liveTest = new LocalTest("test", () { | |
31 invoker = Invoker.current; | |
32 }).load(suite); | |
33 liveTest.onError.listen(expectAsync((_) {}, count: 0)); | |
34 | |
35 return liveTest.run().then((_) { | |
36 expect(invoker.liveTest, equals(liveTest)); | |
37 }); | |
38 }); | |
39 | |
40 test("returns the current invoker in a test body after the test completes", | |
41 () { | |
42 var status; | |
43 var completer = new Completer(); | |
44 var liveTest = new LocalTest("test", () { | |
45 // Use [new Future] in particular to wait longer than a microtask for | |
46 // the test to complete. | |
47 new Future(() { | |
48 status = Invoker.current.liveTest.state.status; | |
49 completer.complete(Invoker.current); | |
50 }); | |
51 }).load(suite); | |
52 liveTest.onError.listen(expectAsync((_) {}, count: 0)); | |
53 | |
54 expect(liveTest.run(), completes); | |
55 return completer.future.then((invoker) { | |
56 expect(invoker.liveTest, equals(liveTest)); | |
57 expect(status, equals(Status.complete)); | |
58 }); | |
59 }); | |
60 | |
61 test("returns the current invoker in a tearDown body", () { | |
62 var invoker; | |
63 var liveTest = new LocalTest("test", () {}, tearDown: () { | |
64 invoker = Invoker.current; | |
65 }).load(suite); | |
66 liveTest.onError.listen(expectAsync((_) {}, count: 0)); | |
67 | |
68 return liveTest.run().then((_) { | |
69 expect(invoker.liveTest, equals(liveTest)); | |
70 }); | |
71 }); | |
72 | |
73 test("returns the current invoker in a tearDown body after the test " | |
74 "completes", () { | |
75 var status; | |
76 var completer = new Completer(); | |
77 var liveTest = new LocalTest("test", () {}, tearDown: () { | |
78 // Use [new Future] in particular to wait longer than a microtask for | |
79 // the test to complete. | |
80 new Future(() { | |
81 status = Invoker.current.liveTest.state.status; | |
82 completer.complete(Invoker.current); | |
83 }); | |
84 }).load(suite); | |
85 liveTest.onError.listen(expectAsync((_) {}, count: 0)); | |
86 | |
87 expect(liveTest.run(), completes); | |
88 return completer.future.then((invoker) { | |
89 expect(invoker.liveTest, equals(liveTest)); | |
90 expect(status, equals(Status.complete)); | |
91 }); | |
92 }); | |
93 }); | |
94 | |
95 group("in a successful test,", () { | |
96 test("the state changes from pending to running to complete", () { | |
97 var stateInTest; | |
98 var stateInTearDown; | |
99 var liveTest; | |
100 liveTest = new LocalTest("test", () { | |
101 stateInTest = liveTest.state; | |
102 }, tearDown: () { | |
103 stateInTearDown = liveTest.state; | |
104 }).load(suite); | |
105 liveTest.onError.listen(expectAsync((_) {}, count: 0)); | |
106 | |
107 expect(liveTest.state.status, equals(Status.pending)); | |
108 expect(liveTest.state.result, equals(Result.success)); | |
109 | |
110 var future = liveTest.run(); | |
111 | |
112 expect(liveTest.state.status, equals(Status.running)); | |
113 expect(liveTest.state.result, equals(Result.success)); | |
114 | |
115 return future.then((_) { | |
116 expect(stateInTest.status, equals(Status.running)); | |
117 expect(stateInTest.result, equals(Result.success)); | |
118 | |
119 expect(stateInTearDown.status, equals(Status.running)); | |
120 expect(stateInTearDown.result, equals(Result.success)); | |
121 | |
122 expect(liveTest.state.status, equals(Status.complete)); | |
123 expect(liveTest.state.result, equals(Result.success)); | |
124 }); | |
125 }); | |
126 | |
127 test("onStateChange fires for each state change", () { | |
128 var liveTest = new LocalTest("test", () {}).load(suite); | |
129 liveTest.onError.listen(expectAsync((_) {}, count: 0)); | |
130 | |
131 var first = true; | |
132 liveTest.onStateChange.listen(expectAsync((state) { | |
133 if (first) { | |
134 expect(state.status, equals(Status.running)); | |
135 first = false; | |
136 } else { | |
137 expect(state.status, equals(Status.complete)); | |
138 } | |
139 expect(state.result, equals(Result.success)); | |
140 }, count: 2, max: 2)); | |
141 | |
142 return liveTest.run(); | |
143 }); | |
144 | |
145 test("onComplete completes once the test body and tearDown are done", () { | |
146 var testRun = false; | |
147 var tearDownRun = false; | |
148 var liveTest = new LocalTest("test", () { | |
149 testRun = true; | |
150 }, tearDown: () { | |
151 tearDownRun = true; | |
152 }).load(suite); | |
153 | |
154 expect(liveTest.onComplete.then((_) { | |
155 expect(testRun, isTrue); | |
156 expect(tearDownRun, isTrue); | |
157 }), completes); | |
158 | |
159 return liveTest.run(); | |
160 }); | |
161 }); | |
162 | |
163 group("in a test with failures,", () { | |
164 test("a synchronous throw is reported and causes the test to fail", () { | |
165 var liveTest = new LocalTest("test", () { | |
166 throw new TestFailure('oh no'); | |
167 }).load(suite); | |
168 | |
169 expectSingleFailure(liveTest); | |
170 return liveTest.run(); | |
171 }); | |
172 | |
173 test("a synchronous reported failure causes the test to fail", () { | |
174 var liveTest = new LocalTest("test", () { | |
175 Invoker.current.handleError(new TestFailure("oh no")); | |
176 }).load(suite); | |
177 | |
178 expectSingleFailure(liveTest); | |
179 return liveTest.run(); | |
180 }); | |
181 | |
182 test("a failure reported asynchronously during the test causes it to fail", | |
183 () { | |
184 var liveTest = new LocalTest("test", () { | |
185 Invoker.current.addOutstandingCallback(); | |
186 new Future(() => Invoker.current.handleError(new TestFailure("oh no"))); | |
187 }).load(suite); | |
188 | |
189 expectSingleFailure(liveTest); | |
190 return liveTest.run(); | |
191 }); | |
192 | |
193 test("a failure thrown asynchronously during the test causes it to fail", | |
194 () { | |
195 var liveTest = new LocalTest("test", () { | |
196 Invoker.current.addOutstandingCallback(); | |
197 new Future(() => throw new TestFailure("oh no")); | |
198 }).load(suite); | |
199 | |
200 expectSingleFailure(liveTest); | |
201 return liveTest.run(); | |
202 }); | |
203 | |
204 test("a failure reported asynchronously after the test causes it to error", | |
205 () { | |
206 var liveTest = new LocalTest("test", () { | |
207 new Future(() => Invoker.current.handleError(new TestFailure("oh no"))); | |
208 }).load(suite); | |
209 | |
210 expectStates(liveTest, [ | |
211 const State(Status.running, Result.success), | |
212 const State(Status.complete, Result.success), | |
213 const State(Status.complete, Result.failure), | |
214 const State(Status.complete, Result.error) | |
215 ]); | |
216 | |
217 expectErrors(liveTest, [(error) { | |
218 expect(lastState, equals(const State(Status.complete, Result.failure))); | |
219 expect(error, isTestFailure("oh no")); | |
220 }, (error) { | |
221 expect(lastState, equals(const State(Status.complete, Result.error))); | |
222 expect(error, equals( | |
223 "This test failed after it had already completed. Make sure to " | |
224 "use [expectAsync]\n" | |
225 "or the [completes] matcher when testing async code.")); | |
226 }]); | |
227 | |
228 return liveTest.run(); | |
229 }); | |
230 | |
231 test("multiple asynchronous failures are reported", () { | |
232 var liveTest = new LocalTest("test", () { | |
233 Invoker.current.addOutstandingCallback(); | |
234 new Future(() => throw new TestFailure("one")); | |
235 new Future(() => throw new TestFailure("two")); | |
236 new Future(() => throw new TestFailure("three")); | |
237 new Future(() => throw new TestFailure("four")); | |
238 }).load(suite); | |
239 | |
240 expectStates(liveTest, [ | |
241 const State(Status.running, Result.success), | |
242 const State(Status.complete, Result.failure) | |
243 ]); | |
244 | |
245 expectErrors(liveTest, [(error) { | |
246 expect(lastState.status, equals(Status.complete)); | |
247 expect(error, isTestFailure("one")); | |
248 }, (error) { | |
249 expect(error, isTestFailure("two")); | |
250 }, (error) { | |
251 expect(error, isTestFailure("three")); | |
252 }, (error) { | |
253 expect(error, isTestFailure("four")); | |
254 }]); | |
255 | |
256 return liveTest.run(); | |
257 }); | |
258 | |
259 test("a failure after an error doesn't change the state of the test", () { | |
260 var liveTest = new LocalTest("test", () { | |
261 new Future(() => throw new TestFailure("fail")); | |
262 throw "error"; | |
263 }).load(suite); | |
264 | |
265 expectStates(liveTest, [ | |
266 const State(Status.running, Result.success), | |
267 const State(Status.complete, Result.error) | |
268 ]); | |
269 | |
270 expectErrors(liveTest, [(error) { | |
271 expect(lastState, equals(const State(Status.complete, Result.error))); | |
272 expect(error, equals("error")); | |
273 }, (error) { | |
274 expect(error, isTestFailure("fail")); | |
275 }]); | |
276 | |
277 return liveTest.run(); | |
278 }); | |
279 | |
280 test("tearDown is run after an asynchronous failure", () { | |
281 var stateDuringTearDown; | |
282 var liveTest; | |
283 liveTest = new LocalTest("test", () { | |
284 Invoker.current.addOutstandingCallback(); | |
285 new Future(() => throw new TestFailure("oh no")); | |
286 }, tearDown: () { | |
287 stateDuringTearDown = liveTest.state; | |
288 }).load(suite); | |
289 | |
290 expectSingleFailure(liveTest); | |
291 return liveTest.run().then((_) { | |
292 expect(stateDuringTearDown, | |
293 equals(const State(Status.complete, Result.failure))); | |
294 }); | |
295 }); | |
296 }); | |
297 | |
298 group("in a test with errors,", () { | |
299 test("a synchronous throw is reported and causes the test to error", () { | |
300 var liveTest = new LocalTest("test", () { | |
301 throw 'oh no'; | |
302 }).load(suite); | |
303 | |
304 expectSingleError(liveTest); | |
305 return liveTest.run(); | |
306 }); | |
307 | |
308 test("a synchronous reported error causes the test to error", () { | |
309 var liveTest = new LocalTest("test", () { | |
310 Invoker.current.handleError("oh no"); | |
311 }).load(suite); | |
312 | |
313 expectSingleError(liveTest); | |
314 return liveTest.run(); | |
315 }); | |
316 | |
317 test("an error reported asynchronously during the test causes it to error", | |
318 () { | |
319 var liveTest = new LocalTest("test", () { | |
320 Invoker.current.addOutstandingCallback(); | |
321 new Future(() => Invoker.current.handleError("oh no")); | |
322 }).load(suite); | |
323 | |
324 expectSingleError(liveTest); | |
325 return liveTest.run(); | |
326 }); | |
327 | |
328 test("an error thrown asynchronously during the test causes it to error", | |
329 () { | |
330 var liveTest = new LocalTest("test", () { | |
331 Invoker.current.addOutstandingCallback(); | |
332 new Future(() => throw "oh no"); | |
333 }).load(suite); | |
334 | |
335 expectSingleError(liveTest); | |
336 return liveTest.run(); | |
337 }); | |
338 | |
339 test("an error reported asynchronously after the test causes it to error", | |
340 () { | |
341 var liveTest = new LocalTest("test", () { | |
342 new Future(() => Invoker.current.handleError("oh no")); | |
343 }).load(suite); | |
344 | |
345 expectStates(liveTest, [ | |
346 const State(Status.running, Result.success), | |
347 const State(Status.complete, Result.success), | |
348 const State(Status.complete, Result.error) | |
349 ]); | |
350 | |
351 expectErrors(liveTest, [(error) { | |
352 expect(lastState, equals(const State(Status.complete, Result.error))); | |
353 expect(error, equals("oh no")); | |
354 }, (error) { | |
355 expect(error, equals( | |
356 "This test failed after it had already completed. Make sure to " | |
357 "use [expectAsync]\n" | |
358 "or the [completes] matcher when testing async code.")); | |
359 }]); | |
360 | |
361 return liveTest.run(); | |
362 }); | |
363 | |
364 test("multiple asynchronous errors are reported", () { | |
365 var liveTest = new LocalTest("test", () { | |
366 Invoker.current.addOutstandingCallback(); | |
367 new Future(() => throw "one"); | |
368 new Future(() => throw "two"); | |
369 new Future(() => throw "three"); | |
370 new Future(() => throw "four"); | |
371 }).load(suite); | |
372 | |
373 expectStates(liveTest, [ | |
374 const State(Status.running, Result.success), | |
375 const State(Status.complete, Result.error) | |
376 ]); | |
377 | |
378 expectErrors(liveTest, [(error) { | |
379 expect(lastState.status, equals(Status.complete)); | |
380 expect(error, equals("one")); | |
381 }, (error) { | |
382 expect(error, equals("two")); | |
383 }, (error) { | |
384 expect(error, equals("three")); | |
385 }, (error) { | |
386 expect(error, equals("four")); | |
387 }]); | |
388 | |
389 return liveTest.run(); | |
390 }); | |
391 | |
392 test("an error after a failure changes the state of the test", () { | |
393 var liveTest = new LocalTest("test", () { | |
394 new Future(() => throw "error"); | |
395 throw new TestFailure("fail"); | |
396 }).load(suite); | |
397 | |
398 expectStates(liveTest, [ | |
399 const State(Status.running, Result.success), | |
400 const State(Status.complete, Result.failure), | |
401 const State(Status.complete, Result.error) | |
402 ]); | |
403 | |
404 expectErrors(liveTest, [(error) { | |
405 expect(lastState, equals(const State(Status.complete, Result.failure))); | |
406 expect(error, isTestFailure("fail")); | |
407 }, (error) { | |
408 expect(lastState, equals(const State(Status.complete, Result.error))); | |
409 expect(error, equals("error")); | |
410 }]); | |
411 | |
412 return liveTest.run(); | |
413 }); | |
414 | |
415 test("tearDown is run after an asynchronous error", () { | |
416 var stateDuringTearDown; | |
417 var liveTest; | |
418 liveTest = new LocalTest("test", () { | |
419 Invoker.current.addOutstandingCallback(); | |
420 new Future(() => throw "oh no"); | |
421 }, tearDown: () { | |
422 stateDuringTearDown = liveTest.state; | |
423 }).load(suite); | |
424 | |
425 expectSingleError(liveTest); | |
426 return liveTest.run().then((_) { | |
427 expect(stateDuringTearDown, | |
428 equals(const State(Status.complete, Result.error))); | |
429 }); | |
430 }); | |
431 }); | |
432 | |
433 test("a test doesn't complete until there are no outstanding callbacks", | |
434 () { | |
435 var outstandingCallbackRemoved = false; | |
436 var liveTest = new LocalTest("test", () { | |
437 Invoker.current.addOutstandingCallback(); | |
438 | |
439 // Pump the event queue to make sure the test isn't coincidentally | |
440 // completing after the outstanding callback is removed. | |
441 pumpEventQueue().then((_) { | |
442 outstandingCallbackRemoved = true; | |
443 Invoker.current.removeOutstandingCallback(); | |
444 }); | |
445 }).load(suite); | |
446 | |
447 liveTest.onError.listen(expectAsync((_) {}, count: 0)); | |
448 | |
449 return liveTest.run().then((_) { | |
450 expect(outstandingCallbackRemoved, isTrue); | |
451 }); | |
452 }); | |
453 | |
454 test("a test's tearDown isn't run until there are no outstanding callbacks", | |
455 () { | |
456 var outstandingCallbackRemoved = false; | |
457 var outstandingCallbackRemovedBeforeTeardown = false; | |
458 var liveTest = new LocalTest("test", () { | |
459 Invoker.current.addOutstandingCallback(); | |
460 pumpEventQueue().then((_) { | |
461 outstandingCallbackRemoved = true; | |
462 Invoker.current.removeOutstandingCallback(); | |
463 }); | |
464 }, tearDown: () { | |
465 outstandingCallbackRemovedBeforeTeardown = outstandingCallbackRemoved; | |
466 }).load(suite); | |
467 | |
468 liveTest.onError.listen(expectAsync((_) {}, count: 0)); | |
469 | |
470 return liveTest.run().then((_) { | |
471 expect(outstandingCallbackRemovedBeforeTeardown, isTrue); | |
472 }); | |
473 }); | |
474 | |
475 test("a test times out after 30 seconds", () { | |
476 new FakeAsync().run((async) { | |
477 var liveTest = new LocalTest("test", () { | |
478 Invoker.current.addOutstandingCallback(); | |
479 }).load(suite); | |
480 | |
481 expectStates(liveTest, [ | |
482 const State(Status.running, Result.success), | |
483 const State(Status.complete, Result.error) | |
484 ]); | |
485 | |
486 expectErrors(liveTest, [(error) { | |
487 expect(lastState.status, equals(Status.complete)); | |
488 expect(error, new isInstanceOf<TimeoutException>()); | |
489 }]); | |
490 | |
491 liveTest.run(); | |
492 async.elapse(new Duration(seconds: 30)); | |
493 }); | |
494 }); | |
495 } | |
OLD | NEW |