5
5
package kotlinx.coroutines.test
6
6
7
7
import kotlinx.coroutines.*
8
- import kotlin.coroutines.*
9
8
import kotlin.test.*
10
9
11
10
class TestCoroutineSchedulerTest {
12
11
/* * Tests that `TestCoroutineScheduler` attempts to detect if there are several instances of it. */
13
12
@Test
14
- fun testContextElement () = runBlockingTest {
13
+ fun testContextElement () = runTest {
15
14
assertFailsWith<IllegalStateException > {
16
15
withContext(TestCoroutineDispatcher ()) {
17
16
}
@@ -21,7 +20,7 @@ class TestCoroutineSchedulerTest {
21
20
/* * Tests that, as opposed to [DelayController.advanceTimeBy] or [TestCoroutineScope.advanceTimeBy],
22
21
* [TestCoroutineScheduler.advanceTimeBy] doesn't run the tasks scheduled at the target moment. */
23
22
@Test
24
- fun testAdvanceTimeByDoesNotRunCurrent () = runBlockingTest {
23
+ fun testAdvanceTimeByDoesNotRunCurrent () = runTest {
25
24
var entered = false
26
25
launch {
27
26
delay(15 )
@@ -45,7 +44,7 @@ class TestCoroutineSchedulerTest {
45
44
/* * Tests that if [TestCoroutineScheduler.advanceTimeBy] encounters an arithmetic overflow, all the tasks scheduled
46
45
* until the moment [Long.MAX_VALUE] get run. */
47
46
@Test
48
- fun testAdvanceTimeByEnormousDelays () = runBlockingTest {
47
+ fun testAdvanceTimeByEnormousDelays () = runTest {
49
48
val initialDelay = 10L
50
49
delay(initialDelay)
51
50
assertEquals(initialDelay, currentTime)
@@ -99,7 +98,7 @@ class TestCoroutineSchedulerTest {
99
98
100
99
/* * Tests the basic functionality of [TestCoroutineScheduler.runCurrent]. */
101
100
@Test
102
- fun testRunCurrent () = runBlockingTest {
101
+ fun testRunCurrent () = runTest {
103
102
var stage = 0
104
103
launch {
105
104
delay(1 )
@@ -182,4 +181,79 @@ class TestCoroutineSchedulerTest {
182
181
stage = 1
183
182
scope.runCurrent()
184
183
}
184
+
185
+ private fun TestCoroutineScope.checkTimeout (
186
+ timesOut : Boolean , timeoutMillis : Long = SLOW , block : suspend () -> Unit
187
+ ) = assertRunsFast {
188
+ var caughtException = false
189
+ launch {
190
+ try {
191
+ withTimeout(timeoutMillis) {
192
+ block()
193
+ }
194
+ } catch (e: TimeoutCancellationException ) {
195
+ caughtException = true
196
+ }
197
+ }
198
+ advanceUntilIdle()
199
+ cleanupTestCoroutines()
200
+ if (timesOut)
201
+ assertTrue(caughtException)
202
+ else
203
+ assertFalse(caughtException)
204
+ }
205
+
206
+ /* * Tests that timeouts get triggered. */
207
+ @Test
208
+ fun testSmallTimeouts () {
209
+ val scope = TestCoroutineScope ()
210
+ scope.checkTimeout(true ) {
211
+ val half = SLOW / 2
212
+ delay(half)
213
+ delay(SLOW - half)
214
+ }
215
+ }
216
+
217
+ /* * Tests that timeouts don't get triggered if the code finishes in time. */
218
+ @Test
219
+ fun testLargeTimeouts () {
220
+ val scope = TestCoroutineScope ()
221
+ scope.checkTimeout(false ) {
222
+ val half = SLOW / 2
223
+ delay(half)
224
+ delay(SLOW - half - 1 )
225
+ }
226
+ }
227
+
228
+ /* * Tests that timeouts get triggered if the code fails to finish in time asynchronously. */
229
+ @Test
230
+ fun testSmallAsynchronousTimeouts () {
231
+ val scope = TestCoroutineScope ()
232
+ val deferred = CompletableDeferred <Unit >()
233
+ scope.launch {
234
+ val half = SLOW / 2
235
+ delay(half)
236
+ delay(SLOW - half)
237
+ deferred.complete(Unit )
238
+ }
239
+ scope.checkTimeout(true ) {
240
+ deferred.await()
241
+ }
242
+ }
243
+
244
+ /* * Tests that timeouts don't get triggered if the code finishes in time, even if it does so asynchronously. */
245
+ @Test
246
+ fun testLargeAsynchronousTimeouts () {
247
+ val scope = TestCoroutineScope ()
248
+ val deferred = CompletableDeferred <Unit >()
249
+ scope.launch {
250
+ val half = SLOW / 2
251
+ delay(half)
252
+ delay(SLOW - half - 1 )
253
+ deferred.complete(Unit )
254
+ }
255
+ scope.checkTimeout(false ) {
256
+ deferred.await()
257
+ }
258
+ }
185
259
}
0 commit comments