@@ -25,6 +25,8 @@ import java.util.concurrent.CompletableFuture
25
25
import java.util.concurrent.CompletionStage
26
26
import java.util.concurrent.ExecutionException
27
27
import java.util.concurrent.atomic.AtomicInteger
28
+ import java.util.concurrent.locks.ReentrantLock
29
+ import kotlin.concurrent.withLock
28
30
import kotlin.coroutines.experimental.CoroutineContext
29
31
30
32
class FutureTest : TestBase () {
@@ -240,13 +242,13 @@ class FutureTest : TestBase() {
240
242
assertEquals(" Part before first suspension must be wrapped" , 1 , depth.get())
241
243
val result =
242
244
CompletableFuture .supplyAsync {
243
- while (depth.get() > 0 ) ;
245
+ while (depth.get() > 0 );
244
246
assertEquals(" Part inside suspension point should not be wrapped" , 0 , depth.get())
245
247
" OK"
246
248
}.await()
247
249
assertEquals(" Part after first suspension should be wrapped" , 1 , depth.get())
248
250
CompletableFuture .supplyAsync {
249
- while (depth.get() > 0 ) ;
251
+ while (depth.get() > 0 );
250
252
assertEquals(" Part inside suspension point should not be wrapped" , 0 , depth.get())
251
253
" ignored"
252
254
}.await()
@@ -255,6 +257,63 @@ class FutureTest : TestBase() {
255
257
assertThat(future.get(), IsEqual (" OK" ))
256
258
}
257
259
260
+ @Test
261
+ fun testCompletableFutureStageAsDeferred () = runBlocking {
262
+ val lock = ReentrantLock ().apply { lock() }
263
+
264
+ val deferred: Deferred <Int > = CompletableFuture .supplyAsync {
265
+ lock.withLock { 42 }
266
+ }.asDeferred()
267
+
268
+ assertFalse(deferred.isCompleted)
269
+ lock.unlock()
270
+
271
+ assertEquals(42 , deferred.await())
272
+ assertTrue(deferred.isCompleted)
273
+ }
274
+
275
+ @Test
276
+ fun testCompletedFutureAsDeferred () = runBlocking {
277
+ val deferred: Deferred <Int > = CompletableFuture .completedFuture(42 ).asDeferred()
278
+ assertEquals(42 , deferred.await())
279
+ }
280
+
281
+ @Test
282
+ fun testFailedFutureAsDeferred () = runBlocking {
283
+ val future = CompletableFuture <Int >().apply { completeExceptionally(Exception (" something went wrong" )) }
284
+ val deferred = future.asDeferred()
285
+
286
+ assertTrue(deferred.isCompletedExceptionally)
287
+ assertEquals(" something went wrong" , deferred.getCompletionExceptionOrNull()!! .cause!! .message)
288
+
289
+ try {
290
+ deferred.await()
291
+ fail(" deferred.await() should throw an exception" )
292
+ } catch (e: Exception ) {
293
+ assertEquals(" something went wrong" , e.cause!! .message)
294
+ }
295
+ }
296
+
297
+ @Test
298
+ fun testCompletableFutureWithExceptionAsDeferred () = runBlocking {
299
+ val lock = ReentrantLock ().apply { lock() }
300
+
301
+ val deferred: Deferred <Int > = CompletableFuture .supplyAsync {
302
+ lock.withLock { throw Exception (" something went wrong" ) }
303
+ }.asDeferred()
304
+
305
+ assertFalse(deferred.isCompleted)
306
+ lock.unlock()
307
+
308
+ try {
309
+ deferred.await()
310
+ fail(" deferred.await() should throw an exception" )
311
+ } catch (e: Exception ) {
312
+ assertTrue(deferred.isCompletedExceptionally)
313
+ assertEquals(" something went wrong" , e.cause!! .message)
314
+ }
315
+ }
316
+
258
317
private fun wrapContinuation (wrapper : (() -> Unit ) -> Unit ): CoroutineDispatcher = object : CoroutineDispatcher () {
259
318
override fun dispatch (context : CoroutineContext , block : Runnable ) {
260
319
wrapper {
0 commit comments