• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 @file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED", "DEPRECATION") // KT-21913
2 
3 package kotlinx.coroutines
4 
5 import kotlinx.coroutines.testing.*
6 import kotlin.test.*
7 
8 class CompletableDeferredTest : TestBase() {
9     @Test
testFreshnull10     fun testFresh() {
11         val c = CompletableDeferred<String>()
12         checkFresh(c)
13     }
14 
15     @Test
testCompletenull16     fun testComplete() {
17         val c = CompletableDeferred<String>()
18         assertEquals(true, c.complete("OK"))
19         checkCompleteOk(c)
20         assertEquals("OK", c.getCompleted())
21         assertEquals(false, c.complete("OK"))
22         checkCompleteOk(c)
23         assertEquals("OK", c.getCompleted())
24     }
25 
26     @Test
testCompleteWithIncompleteResultnull27     fun testCompleteWithIncompleteResult() {
28         val c = CompletableDeferred<DisposableHandle>()
29         assertEquals(true, c.complete(c.invokeOnCompletion { }))
30         checkCompleteOk(c)
31         assertEquals(false, c.complete(c.invokeOnCompletion { }))
32         checkCompleteOk(c)
33         assertIs<Incomplete>(c.getCompleted())
34     }
35 
checkFreshnull36     private fun checkFresh(c: CompletableDeferred<*>) {
37         assertEquals(true, c.isActive)
38         assertEquals(false, c.isCancelled)
39         assertEquals(false, c.isCompleted)
40         assertThrows<IllegalStateException> { c.getCancellationException() }
41         assertThrows<IllegalStateException> { c.getCompleted() }
42         assertThrows<IllegalStateException> { c.getCompletionExceptionOrNull() }
43     }
44 
checkCompleteOknull45     private fun checkCompleteOk(c: CompletableDeferred<*>) {
46         assertEquals(false, c.isActive)
47         assertEquals(false, c.isCancelled)
48         assertEquals(true, c.isCompleted)
49         assertIs<JobCancellationException>(c.getCancellationException())
50         assertNull(c.getCompletionExceptionOrNull())
51     }
52 
checkCancelnull53     private fun checkCancel(c: CompletableDeferred<String>) {
54         assertEquals(false, c.isActive)
55         assertEquals(true, c.isCancelled)
56         assertEquals(true, c.isCompleted)
57         assertThrows<CancellationException> { c.getCompleted() }
58         assertIs<CancellationException>(c.getCompletionExceptionOrNull())
59     }
60 
61     @Test
testCancelWithExceptionnull62     fun testCancelWithException() {
63         val c = CompletableDeferred<String>()
64         assertEquals(true, c.completeExceptionally(TestException()))
65         checkCancelWithException(c)
66         assertEquals(false, c.completeExceptionally(TestException()))
67         checkCancelWithException(c)
68     }
69 
checkCancelWithExceptionnull70     private fun checkCancelWithException(c: CompletableDeferred<String>) {
71         assertEquals(false, c.isActive)
72         assertEquals(true, c.isCancelled)
73         assertEquals(true, c.isCompleted)
74         assertIs<JobCancellationException>(c.getCancellationException())
75         assertThrows<TestException> { c.getCompleted() }
76         assertIs<TestException>(c.getCompletionExceptionOrNull())
77     }
78 
79     @Test
testCompleteWithResultOKnull80     fun testCompleteWithResultOK() {
81         val c = CompletableDeferred<String>()
82         assertEquals(true, c.completeWith(Result.success("OK")))
83         checkCompleteOk(c)
84         assertEquals("OK", c.getCompleted())
85         assertEquals(false, c.completeWith(Result.success("OK")))
86         checkCompleteOk(c)
87         assertEquals("OK", c.getCompleted())
88     }
89 
90     @Test
testCompleteWithResultExceptionnull91     fun testCompleteWithResultException() {
92         val c = CompletableDeferred<String>()
93         assertEquals(true, c.completeWith(Result.failure(TestException())))
94         checkCancelWithException(c)
95         assertEquals(false, c.completeWith(Result.failure(TestException())))
96         checkCancelWithException(c)
97     }
98 
99     @Test
testParentCancelsChildnull100     fun testParentCancelsChild() {
101         val parent = Job()
102         val c = CompletableDeferred<String>(parent)
103         checkFresh(c)
104         parent.cancel()
105         assertEquals(false, parent.isActive)
106         assertEquals(true, parent.isCancelled)
107         assertEquals(false, c.isActive)
108         assertEquals(true, c.isCancelled)
109         assertEquals(true, c.isCompleted)
110         assertThrows<CancellationException> { c.getCompleted() }
111         assertIs<CancellationException>(c.getCompletionExceptionOrNull())
112     }
113 
114     @Test
testParentActiveOnChildCompletionnull115     fun testParentActiveOnChildCompletion() {
116         val parent = Job()
117         val c = CompletableDeferred<String>(parent)
118         checkFresh(c)
119         assertEquals(true, parent.isActive)
120         assertEquals(true, c.complete("OK"))
121         checkCompleteOk(c)
122         assertEquals(true, parent.isActive)
123     }
124 
125     @Test
testParentCancelledOnChildExceptionnull126     fun testParentCancelledOnChildException() {
127         val parent = Job()
128         val c = CompletableDeferred<String>(parent)
129         checkFresh(c)
130         assertEquals(true, parent.isActive)
131         assertEquals(true, c.completeExceptionally(TestException()))
132         checkCancelWithException(c)
133         assertEquals(false, parent.isActive)
134         assertEquals(true, parent.isCancelled)
135     }
136 
137     @Test
testParentActiveOnChildCancellationnull138     fun testParentActiveOnChildCancellation() {
139         val parent = Job()
140         val c = CompletableDeferred<String>(parent)
141         checkFresh(c)
142         assertEquals(true, parent.isActive)
143         c.cancel()
144         checkCancel(c)
145         assertEquals(true, parent.isActive)
146     }
147 
148     @Test
<lambda>null149     fun testAwait() = runTest {
150         expect(1)
151         val c = CompletableDeferred<String>()
152         launch(start = CoroutineStart.UNDISPATCHED) {
153             expect(2)
154             assertEquals("OK", c.await()) // suspends
155             expect(5)
156             assertEquals("OK", c.await()) // does not suspend
157             expect(6)
158         }
159         expect(3)
160         c.complete("OK")
161         expect(4)
162         yield() // to launch
163         finish(7)
164     }
165 
166     @Test
<lambda>null167     fun testCancelAndAwaitParentWaitChildren() = runTest {
168         expect(1)
169         val parent = CompletableDeferred<String>()
170         launch(parent, start = CoroutineStart.UNDISPATCHED) {
171             expect(2)
172             try {
173                 yield() // will get cancelled
174             } finally {
175                 expect(5)
176             }
177         }
178         expect(3)
179         parent.cancel()
180         expect(4)
181         try {
182             parent.await()
183         } catch (e: CancellationException) {
184             finish(6)
185         }
186     }
187 
188     @Test
<lambda>null189     fun testCompleteAndAwaitParentWaitChildren() = runTest {
190         expect(1)
191         val parent = CompletableDeferred<String>()
192         launch(parent, start = CoroutineStart.UNDISPATCHED) {
193             expect(2)
194             try {
195                 yield() // will get cancelled
196             } finally {
197                 expect(5)
198             }
199         }
200         expect(3)
201         parent.complete("OK")
202         expect(4)
203         assertEquals("OK", parent.await())
204         finish(6)
205     }
206 
assertThrowsnull207     private inline fun <reified T: Throwable> assertThrows(block: () -> Unit) {
208         try {
209             block()
210             fail("Should not complete normally")
211         } catch (e: Throwable) {
212             assertIs<T>(e)
213         }
214     }
215 }
216