1 /* <lambda>null2 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.coroutines.future 6 7 import kotlinx.coroutines.* 8 import org.junit.Test 9 import java.io.* 10 import java.util.concurrent.* 11 import kotlin.test.* 12 13 class FutureExceptionsTest : TestBase() { 14 15 @Test 16 fun testAwait() { 17 testException(IOException(), { it is IOException }) 18 } 19 20 @Test 21 fun testAwaitChained() { 22 testException(IOException(), { it is IOException }, { f -> f.thenApply { it + 1 } }) 23 } 24 25 @Test 26 fun testAwaitDeepChain() { 27 testException(IOException(), { it is IOException }, 28 { f -> f 29 .thenApply { it + 1 } 30 .thenApply { it + 2 } }) 31 } 32 33 @Test 34 fun testAwaitCompletionException() { 35 testException(CompletionException("test", IOException()), { it is IOException }) 36 } 37 38 @Test 39 fun testAwaitChainedCompletionException() { 40 testException(CompletionException("test", IOException()), { it is IOException }, { f -> f.thenApply { it + 1 } }) 41 } 42 43 @Test 44 fun testAwaitTestException() { 45 testException(TestException(), { it is TestException }) 46 } 47 48 @Test 49 fun testAwaitChainedTestException() { 50 testException(TestException(), { it is TestException }, { f -> f.thenApply { it + 1 } }) 51 } 52 53 private fun testException( 54 exception: Throwable, 55 expected: ((Throwable) -> Boolean), 56 transformer: (CompletableFuture<Int>) -> CompletableFuture<Int> = { it } 57 ) { 58 59 // Fast path 60 runTest { 61 val future = CompletableFuture<Int>() 62 val chained = transformer(future) 63 future.completeExceptionally(exception) 64 try { 65 chained.await() 66 } catch (e: Throwable) { 67 assertTrue(expected(e)) 68 } 69 } 70 71 // Slow path 72 runTest { 73 val future = CompletableFuture<Int>() 74 val chained = transformer(future) 75 76 launch { 77 future.completeExceptionally(exception) 78 } 79 80 try { 81 chained.await() 82 } catch (e: Throwable) { 83 assertTrue(expected(e)) 84 } 85 } 86 } 87 } 88