16
16
17
17
package kotlinx.coroutines.experimental.future
18
18
19
- import kotlinx.coroutines.experimental.CoroutineDispatcher
19
+ import kotlinx.coroutines.experimental.*
20
+ import org.hamcrest.core.IsEqual
21
+ import org.junit.Assert.*
20
22
import org.junit.Test
21
23
import java.util.concurrent.CompletableFuture
24
+ import java.util.concurrent.CompletionStage
22
25
import java.util.concurrent.ExecutionException
23
26
import java.util.concurrent.atomic.AtomicInteger
24
27
import kotlin.coroutines.experimental.CoroutineContext
25
- import org.junit.Assert.*
26
- import java.util.concurrent.CompletionStage
27
28
28
- class FutureTest {
29
+ class FutureTest : TestBase () {
29
30
@Test
30
- fun testSimple () {
31
+ fun testSimpleAwait () {
31
32
val future = future {
32
33
CompletableFuture .supplyAsync {
33
34
" O"
34
35
}.await() + " K"
35
36
}
36
- assertEquals(" OK" , future.get())
37
+ assertThat(future.get(), IsEqual (" OK" ))
38
+ }
39
+
40
+ @Test
41
+ fun testCompletedFuture () {
42
+ val toAwait = CompletableFuture <String >()
43
+ toAwait.complete(" O" )
44
+ val future = future {
45
+ toAwait.await() + " K"
46
+ }
47
+ assertThat(future.get(), IsEqual (" OK" ))
48
+ }
49
+
50
+ @Test
51
+ fun testCompletedCompletionStage () {
52
+ val completable = CompletableFuture <String >()
53
+ completable.complete(" O" )
54
+ val toAwait: CompletionStage <String > = completable
55
+ val future = future {
56
+ toAwait.await() + " K"
57
+ }
58
+ assertThat(future.get(), IsEqual (" OK" ))
37
59
}
38
60
39
61
@Test
@@ -44,7 +66,7 @@ class FutureTest {
44
66
}
45
67
assertFalse(future.isDone)
46
68
toAwait.complete(" O" )
47
- assertEquals( " OK " , future.get())
69
+ assertThat( future.get(), IsEqual ( " OK " ))
48
70
}
49
71
50
72
@Test
@@ -56,11 +78,11 @@ class FutureTest {
56
78
}
57
79
assertFalse(future.isDone)
58
80
completable.complete(" O" )
59
- assertEquals( " OK " , future.get())
81
+ assertThat( future.get(), IsEqual ( " OK " ))
60
82
}
61
83
62
84
@Test
63
- fun testDoneFutureExceptionally () {
85
+ fun testCompletedFutureExceptionally () {
64
86
val toAwait = CompletableFuture <String >()
65
87
toAwait.completeExceptionally(RuntimeException (" O" ))
66
88
val future = future<String > {
@@ -70,11 +92,11 @@ class FutureTest {
70
92
e.message!!
71
93
} + " K"
72
94
}
73
- assertEquals( " OK " , future.get())
95
+ assertThat( future.get(), IsEqual ( " OK " ))
74
96
}
75
97
76
98
@Test
77
- fun testDoneCompletionStageExceptionally () {
99
+ fun testCompletedCompletionStageExceptionally () {
78
100
val completable = CompletableFuture <String >()
79
101
val toAwait: CompletionStage <String > = completable
80
102
completable.completeExceptionally(RuntimeException (" O" ))
@@ -85,11 +107,11 @@ class FutureTest {
85
107
e.message!!
86
108
} + " K"
87
109
}
88
- assertEquals( " OK " , future.get())
110
+ assertThat( future.get(), IsEqual ( " OK " ))
89
111
}
90
112
91
113
@Test
92
- fun testAwaitedFutureCompletedExceptionally () {
114
+ fun testWaitForFutureWithException () {
93
115
val toAwait = CompletableFuture <String >()
94
116
val future = future<String > {
95
117
try {
@@ -100,11 +122,11 @@ class FutureTest {
100
122
}
101
123
assertFalse(future.isDone)
102
124
toAwait.completeExceptionally(RuntimeException (" O" ))
103
- assertEquals( " OK " , future.get())
125
+ assertThat( future.get(), IsEqual ( " OK " ))
104
126
}
105
127
106
128
@Test
107
- fun testAwaitedCompletionStageCompletedExceptionally () {
129
+ fun testWaitForCompletionStageWithException () {
108
130
val completable = CompletableFuture <String >()
109
131
val toAwait: CompletionStage <String > = completable
110
132
val future = future<String > {
@@ -116,7 +138,7 @@ class FutureTest {
116
138
}
117
139
assertFalse(future.isDone)
118
140
completable.completeExceptionally(RuntimeException (" O" ))
119
- assertEquals( " OK " , future.get())
141
+ assertThat( future.get(), IsEqual ( " OK " ))
120
142
}
121
143
122
144
@Test
@@ -125,15 +147,80 @@ class FutureTest {
125
147
if (CompletableFuture .supplyAsync { true }.await()) {
126
148
throw IllegalStateException (" OK" )
127
149
}
128
- CompletableFuture .supplyAsync { " fail" }.await()
150
+ " fail"
129
151
}
130
152
try {
131
153
future.get()
132
154
fail(" 'get' should've throw an exception" )
133
155
} catch (e: ExecutionException ) {
134
156
assertTrue(e.cause is IllegalStateException )
135
- assertEquals(" OK" , e.cause!! .message)
157
+ assertThat(e.cause!! .message, IsEqual (" OK" ))
158
+ }
159
+ }
160
+
161
+ @Test
162
+ fun testCompletedDeferredAsCompletableFuture () = runBlocking {
163
+ expect(1 )
164
+ val deferred = async(context, CoroutineStart .UNDISPATCHED ) {
165
+ expect(2 ) // completed right away
166
+ " OK"
167
+ }
168
+ expect(3 )
169
+ val future = deferred.asCompletableFuture()
170
+ assertThat(future.await(), IsEqual (" OK" ))
171
+ finish(4 )
172
+ }
173
+
174
+ @Test
175
+ fun testWaitForDeferredAsCompletableFuture () = runBlocking {
176
+ expect(1 )
177
+ val deferred = async(context) {
178
+ expect(3 ) // will complete later
179
+ " OK"
180
+ }
181
+ expect(2 )
182
+ val future = deferred.asCompletableFuture()
183
+ assertThat(future.await(), IsEqual (" OK" )) // await yields main thread to deferred coroutine
184
+ finish(4 )
185
+ }
186
+
187
+ @Test
188
+ fun testCancellableAwaitFuture () = runBlocking {
189
+ expect(1 )
190
+ val toAwait = CompletableFuture <String >()
191
+ val job = launch(context, CoroutineStart .UNDISPATCHED ) {
192
+ expect(2 )
193
+ try {
194
+ toAwait.await() // suspends
195
+ } catch (e: CancellationException ) {
196
+ expect(5 ) // should throw cancellation exception
197
+ throw e
198
+ }
199
+ }
200
+ expect(3 )
201
+ job.cancel() // cancel the job
202
+ toAwait.complete(" fail" ) // too late, the waiting job was already cancelled
203
+ expect(4 ) // job processing of cancellation was scheduled, not executed yet
204
+ yield () // yield main thread to job
205
+ finish(6 )
206
+ }
207
+
208
+ @Test
209
+ fun testNonCancellableAwaitCompletionStage () = runBlocking {
210
+ expect(1 )
211
+ val completable = CompletableFuture <String >()
212
+ val toAwait: CompletionStage <String > = completable
213
+ val job = launch(context, CoroutineStart .UNDISPATCHED ) {
214
+ expect(2 )
215
+ assertThat(toAwait.await(), IsEqual (" OK" )) // suspends
216
+ expect(5 )
136
217
}
218
+ expect(3 )
219
+ job.cancel() // cancel the job
220
+ completable.complete(" OK" ) // ok, because await on completion stage is not cancellable
221
+ expect(4 ) // job processing of was scheduled, not executed yet
222
+ yield () // yield main thread to job
223
+ finish(6 )
137
224
}
138
225
139
226
@Test
@@ -159,7 +246,7 @@ class FutureTest {
159
246
}.await()
160
247
result
161
248
}
162
- assertEquals( " OK " , future.get())
249
+ assertThat( future.get(), IsEqual ( " OK " ))
163
250
}
164
251
165
252
private fun wrapContinuation (wrapper : (() -> Unit ) -> Unit ): CoroutineDispatcher = object : CoroutineDispatcher () {
0 commit comments