• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 @file:Suppress("NAMED_ARGUMENTS_NOT_ALLOWED", "DEPRECATION") // KT-21913
6 
7 package kotlinx.coroutines
8 
9 import kotlin.test.*
10 
11 class CompletableDeferredTest : TestBase() {
12     @Test
testFreshnull13     fun testFresh() {
14         val c = CompletableDeferred<String>()
15         checkFresh(c)
16     }
17 
18     @Test
testCompletenull19     fun testComplete() {
20         val c = CompletableDeferred<String>()
21         assertEquals(true, c.complete("OK"))
22         checkCompleteOk(c)
23         assertEquals("OK", c.getCompleted())
24         assertEquals(false, c.complete("OK"))
25         checkCompleteOk(c)
26         assertEquals("OK", c.getCompleted())
27     }
28 
29     @Test
testCompleteWithIncompleteResultnull30     fun testCompleteWithIncompleteResult() {
31         val c = CompletableDeferred<DisposableHandle>()
32         assertEquals(true, c.complete(c.invokeOnCompletion {  }))
33         checkCompleteOk(c)
34         assertEquals(false,  c.complete(c.invokeOnCompletion {  }))
35         checkCompleteOk(c)
36         assertTrue(c.getCompleted() is Incomplete)
37     }
38 
checkFreshnull39     private fun checkFresh(c: CompletableDeferred<*>) {
40         assertEquals(true, c.isActive)
41         assertEquals(false, c.isCancelled)
42         assertEquals(false, c.isCompleted)
43         assertThrows<IllegalStateException> { c.getCancellationException() }
44         assertThrows<IllegalStateException> { c.getCompleted() }
45         assertThrows<IllegalStateException> { c.getCompletionExceptionOrNull() }
46     }
47 
checkCompleteOknull48     private fun checkCompleteOk(c: CompletableDeferred<*>) {
49         assertEquals(false, c.isActive)
50         assertEquals(false, c.isCancelled)
51         assertEquals(true, c.isCompleted)
52         assertTrue(c.getCancellationException() is JobCancellationException)
53         assertNull(c.getCompletionExceptionOrNull())
54     }
55 
checkCancelnull56     private fun checkCancel(c: CompletableDeferred<String>) {
57         assertEquals(false, c.isActive)
58         assertEquals(true, c.isCancelled)
59         assertEquals(true, c.isCompleted)
60         assertThrows<CancellationException> { c.getCompleted() }
61         assertTrue(c.getCompletionExceptionOrNull() is CancellationException)
62     }
63 
64     @Test
testCancelWithExceptionnull65     fun testCancelWithException() {
66         val c = CompletableDeferred<String>()
67         assertEquals(true, c.completeExceptionally(TestException()))
68         checkCancelWithException(c)
69         assertEquals(false, c.completeExceptionally(TestException()))
70         checkCancelWithException(c)
71     }
72 
checkCancelWithExceptionnull73     private fun checkCancelWithException(c: CompletableDeferred<String>) {
74         assertEquals(false, c.isActive)
75         assertEquals(true, c.isCancelled)
76         assertEquals(true, c.isCompleted)
77         assertTrue(c.getCancellationException() is JobCancellationException)
78         assertThrows<TestException> { c.getCompleted() }
79         assertTrue(c.getCompletionExceptionOrNull() is TestException)
80     }
81 
82     @Test
testCompleteWithResultOKnull83     fun testCompleteWithResultOK() {
84         val c = CompletableDeferred<String>()
85         assertEquals(true, c.completeWith(Result.success("OK")))
86         checkCompleteOk(c)
87         assertEquals("OK", c.getCompleted())
88         assertEquals(false, c.completeWith(Result.success("OK")))
89         checkCompleteOk(c)
90         assertEquals("OK", c.getCompleted())
91     }
92 
93     @Test
testCompleteWithResultExceptionnull94     fun testCompleteWithResultException() {
95         val c = CompletableDeferred<String>()
96         assertEquals(true, c.completeWith(Result.failure(TestException())))
97         checkCancelWithException(c)
98         assertEquals(false, c.completeWith(Result.failure(TestException())))
99         checkCancelWithException(c)
100     }
101 
102     @Test
testParentCancelsChildnull103     fun testParentCancelsChild() {
104         val parent = Job()
105         val c = CompletableDeferred<String>(parent)
106         checkFresh(c)
107         parent.cancel()
108         assertEquals(false, parent.isActive)
109         assertEquals(true, parent.isCancelled)
110         assertEquals(false, c.isActive)
111         assertEquals(true, c.isCancelled)
112         assertEquals(true, c.isCompleted)
113         assertThrows<CancellationException> { c.getCompleted() }
114         assertTrue(c.getCompletionExceptionOrNull() is CancellationException)
115     }
116 
117     @Test
testParentActiveOnChildCompletionnull118     fun testParentActiveOnChildCompletion() {
119         val parent = Job()
120         val c = CompletableDeferred<String>(parent)
121         checkFresh(c)
122         assertEquals(true, parent.isActive)
123         assertEquals(true, c.complete("OK"))
124         checkCompleteOk(c)
125         assertEquals(true, parent.isActive)
126     }
127 
128     @Test
testParentCancelledOnChildExceptionnull129     fun testParentCancelledOnChildException() {
130         val parent = Job()
131         val c = CompletableDeferred<String>(parent)
132         checkFresh(c)
133         assertEquals(true, parent.isActive)
134         assertEquals(true, c.completeExceptionally(TestException()))
135         checkCancelWithException(c)
136         assertEquals(false, parent.isActive)
137         assertEquals(true, parent.isCancelled)
138     }
139 
140     @Test
testParentActiveOnChildCancellationnull141     fun testParentActiveOnChildCancellation() {
142         val parent = Job()
143         val c = CompletableDeferred<String>(parent)
144         checkFresh(c)
145         assertEquals(true, parent.isActive)
146         c.cancel()
147         checkCancel(c)
148         assertEquals(true, parent.isActive)
149     }
150 
151     @Test
<lambda>null152     fun testAwait() = runTest {
153         expect(1)
154         val c = CompletableDeferred<String>()
155         launch(start = CoroutineStart.UNDISPATCHED) {
156             expect(2)
157             assertEquals("OK", c.await()) // suspends
158             expect(5)
159             assertEquals("OK", c.await()) // does not suspend
160             expect(6)
161         }
162         expect(3)
163         c.complete("OK")
164         expect(4)
165         yield() // to launch
166         finish(7)
167     }
168 
169     @Test
<lambda>null170     fun testCancelAndAwaitParentWaitChildren() = runTest {
171         expect(1)
172         val parent = CompletableDeferred<String>()
173         launch(parent, start = CoroutineStart.UNDISPATCHED) {
174             expect(2)
175             try {
176                 yield() // will get cancelled
177             } finally {
178                 expect(5)
179             }
180         }
181         expect(3)
182         parent.cancel()
183         expect(4)
184         try {
185             parent.await()
186         } catch (e: CancellationException) {
187             finish(6)
188         }
189     }
190 
191     @Test
<lambda>null192     fun testCompleteAndAwaitParentWaitChildren() = runTest {
193         expect(1)
194         val parent = CompletableDeferred<String>()
195         launch(parent, start = CoroutineStart.UNDISPATCHED) {
196             expect(2)
197             try {
198                 yield() // will get cancelled
199             } finally {
200                 expect(5)
201             }
202         }
203         expect(3)
204         parent.complete("OK")
205         expect(4)
206         assertEquals("OK", parent.await())
207         finish(6)
208     }
209 
assertThrowsnull210     private inline fun <reified T: Throwable> assertThrows(block: () -> Unit) {
211         try {
212             block()
213             fail("Should not complete normally")
214         } catch (e: Throwable) {
215             assertTrue(e is T)
216         }
217     }
218 }