<lambda>null1 package kotlinx.coroutines.test
2
3 import kotlinx.coroutines.*
4 import kotlinx.coroutines.testing.*
5 import kotlin.test.*
6 import kotlin.test.assertFailsWith
7
8 @Suppress("DEPRECATION", "DEPRECATION_ERROR")
9 class TestRunBlockingTest {
10
11 @Test
12 fun delay_advancesTimeAutomatically() = runBlockingTest {
13 assertRunsFast {
14 delay(SLOW)
15 }
16 }
17
18 @Test
19 fun callingSuspendWithDelay_advancesAutomatically() = runBlockingTest {
20 suspend fun withDelay(): Int {
21 delay(SLOW)
22 return 3
23 }
24
25 assertRunsFast {
26 assertEquals(3, withDelay())
27 }
28 }
29
30 @Test
31 fun launch_advancesAutomatically() = runBlockingTest {
32 val job = launch {
33 delay(SLOW)
34 }
35 assertRunsFast {
36 job.join()
37 assertTrue(job.isCompleted)
38 }
39 }
40
41 @Test
42 fun async_advancesAutomatically() = runBlockingTest {
43 val deferred = async {
44 delay(SLOW)
45 3
46 }
47
48 assertRunsFast {
49 assertEquals(3, deferred.await())
50 }
51 }
52
53 @Test
54 fun whenUsingTimeout_triggersWhenDelayed() {
55 assertFailsWith<TimeoutCancellationException> {
56 runBlockingTest {
57 assertRunsFast {
58 withTimeout(SLOW) {
59 delay(SLOW)
60 }
61 }
62 }
63 }
64 }
65
66 @Test
67 fun whenUsingTimeout_doesNotTriggerWhenFast() = runBlockingTest {
68 assertRunsFast {
69 withTimeout(SLOW) {
70 delay(0)
71 }
72 }
73 }
74
75 @Test
76 fun whenUsingTimeout_triggersWhenWaiting() {
77 assertFailsWith<TimeoutCancellationException> {
78 runBlockingTest {
79 val uncompleted = CompletableDeferred<Unit>()
80 assertRunsFast {
81 withTimeout(SLOW) {
82 uncompleted.await()
83 }
84 }
85 }
86 }
87 }
88
89 @Test
90 fun whenUsingTimeout_doesNotTriggerWhenComplete() = runBlockingTest {
91 val completed = CompletableDeferred<Unit>()
92 assertRunsFast {
93 completed.complete(Unit)
94 withTimeout(SLOW) {
95 completed.await()
96 }
97 }
98 }
99
100 @Test
101 fun testDelayInAsync_withAwait() = runBlockingTest {
102 assertRunsFast {
103 val deferred = async {
104 delay(SLOW)
105 3
106 }
107 assertEquals(3, deferred.await())
108 }
109 }
110
111 @Test
112 fun whenUsingTimeout_inAsync_triggersWhenDelayed() {
113 assertFailsWith<TimeoutCancellationException> {
114 runBlockingTest {
115 val deferred = async {
116 withTimeout(SLOW) {
117 delay(SLOW)
118 }
119 }
120
121 assertRunsFast {
122 deferred.await()
123 }
124 }
125 }
126 }
127
128 @Test
129 fun whenUsingTimeout_inAsync_doesNotTriggerWhenNotDelayed() = runBlockingTest {
130 val deferred = async {
131 withTimeout(SLOW) {
132 delay(0)
133 }
134 }
135
136 assertRunsFast {
137 deferred.await()
138 }
139 }
140
141 @Test
142 fun whenUsingTimeout_inLaunch_triggersWhenDelayed() {
143 assertFailsWith<TimeoutCancellationException> {
144 runBlockingTest {
145 val job = launch {
146 withTimeout(1) {
147 delay(SLOW + 1)
148 }
149 }
150
151 assertRunsFast {
152 job.join()
153 throw job.getCancellationException()
154 }
155 }
156 }
157 }
158
159 @Test
160 fun whenUsingTimeout_inLaunch_doesNotTriggerWhenNotDelayed() = runBlockingTest {
161 val job = launch {
162 withTimeout(SLOW) {
163 delay(0)
164 }
165 }
166
167 assertRunsFast {
168 job.join()
169 assertTrue(job.isCompleted)
170 }
171 }
172
173 @Test
174 fun throwingException_throws() {
175 assertFailsWith<IllegalArgumentException> {
176 runBlockingTest {
177 assertRunsFast {
178 delay(SLOW)
179 throw IllegalArgumentException("Test")
180 }
181 }
182 }
183 }
184
185 @Test
186 fun throwingException_inLaunch_throws() {
187 assertFailsWith<IllegalArgumentException> {
188 runBlockingTest {
189 val job = launch {
190 delay(SLOW)
191 throw IllegalArgumentException("Test")
192 }
193
194 assertRunsFast {
195 job.join()
196 throw job.getCancellationException().cause ?: AssertionError("expected exception")
197 }
198 }
199 }
200 }
201
202 @Test
203 fun throwingException__inAsync_throws() {
204 assertFailsWith<IllegalArgumentException> {
205 runBlockingTest {
206 val deferred: Deferred<Unit> = async {
207 delay(SLOW)
208 throw IllegalArgumentException("Test")
209 }
210
211 assertRunsFast {
212 deferred.await()
213 }
214 }
215 }
216 }
217
218 @Test
219 fun callingLaunchFunction_executesLaunchBlockImmediately() = runBlockingTest {
220 assertRunsFast {
221 var executed = false
222 launch {
223 delay(SLOW)
224 executed = true
225 }
226
227 delay(SLOW)
228 assertTrue(executed)
229 }
230 }
231
232 @Test
233 fun callingAsyncFunction_executesAsyncBlockImmediately() = runBlockingTest {
234 assertRunsFast {
235 var executed = false
236 val deferred = async {
237 delay(SLOW)
238 executed = true
239 }
240 delay(SLOW)
241
242 assertTrue(deferred.isCompleted)
243 assertTrue(executed)
244 }
245 }
246
247 @Test
248 fun nestingBuilders_executesSecondLevelImmediately() = runBlockingTest {
249 assertRunsFast {
250 var levels = 0
251 launch {
252 delay(SLOW)
253 levels++
254 launch {
255 delay(SLOW)
256 levels++
257 }
258 }
259 advanceUntilIdle()
260
261 assertEquals(2, levels)
262 }
263 }
264
265 @Test
266 fun testCancellationException() = runBlockingTest {
267 var actual: CancellationException? = null
268 val uncompleted = CompletableDeferred<Unit>()
269 val job = launch {
270 actual = kotlin.runCatching { uncompleted.await() }.exceptionOrNull() as? CancellationException
271 }
272
273 assertNull(actual)
274 job.cancel()
275 assertNotNull(actual)
276 }
277
278 @Test
279 fun testCancellationException_notThrown() = runBlockingTest {
280 val uncompleted = CompletableDeferred<Unit>()
281 val job = launch {
282 uncompleted.await()
283 }
284
285 job.cancel()
286 job.join()
287 }
288
289 @Test
290 fun whenACoroutineLeaks_errorIsThrown() {
291 assertFailsWith<UncompletedCoroutinesError> {
292 runBlockingTest {
293 val uncompleted = CompletableDeferred<Unit>()
294 launch {
295 uncompleted.await()
296 }
297 }
298 }
299 }
300
301 @Test
302 fun runBlockingTestBuilder_throwsOnBadDispatcher() {
303 assertFailsWith<IllegalArgumentException> {
304 runBlockingTest(Dispatchers.Default) {
305
306 }
307 }
308 }
309
310 @Test
311 fun runBlockingTestBuilder_throwsOnBadHandler() {
312 assertFailsWith<IllegalArgumentException> {
313 runBlockingTest(CoroutineExceptionHandler { _, _ -> }) {
314
315 }
316 }
317 }
318
319 @Test
320 fun testWithTestContextThrowingAnAssertionError() {
321 assertFailsWith<TestException> {
322 runBlockingTest {
323 val expectedError = TestException("hello")
324
325 launch {
326 throw expectedError
327 }
328
329 // don't rethrow or handle the exception
330 }
331 }
332 }
333
334 @Test
335 fun testExceptionHandlingWithLaunch() {
336 assertFailsWith<TestException> {
337 runBlockingTest {
338 val expectedError = TestException("hello")
339
340 launch {
341 throw expectedError
342 }
343 }
344 }
345 }
346
347 @Test
348 fun testExceptions_notThrownImmediately() {
349 assertFailsWith<TestException> {
350 runBlockingTest {
351 val expectedException = TestException("hello")
352 val result = runCatching {
353 launch {
354 throw expectedException
355 }
356 }
357 runCurrent()
358 assertEquals(true, result.isSuccess)
359 }
360 }
361 }
362
363
364 private val exceptionHandler = TestCoroutineExceptionHandler()
365
366 @Test
367 fun testPartialContextOverride() = runBlockingTest(CoroutineName("named")) {
368 assertEquals(CoroutineName("named"), coroutineContext[CoroutineName])
369 assertNotNull(coroutineContext[CoroutineExceptionHandler])
370 assertNotSame(coroutineContext[CoroutineExceptionHandler], exceptionHandler)
371 }
372
373 @Test
374 fun testPartialDispatcherOverride() {
375 assertFailsWith<IllegalArgumentException> {
376 runBlockingTest(Dispatchers.Unconfined) {
377 fail("Unreached")
378 }
379 }
380 }
381
382 @Test
383 fun testOverrideExceptionHandler() = runBlockingTest(exceptionHandler) {
384 assertSame(coroutineContext[CoroutineExceptionHandler], exceptionHandler)
385 }
386
387 @Test
388 fun testOverrideExceptionHandlerError() {
389 assertFailsWith<IllegalArgumentException> {
390 runBlockingTest(CoroutineExceptionHandler { _, _ -> }) {
391 fail("Unreached")
392 }
393 }
394 }
395 }
396