@@ -13,31 +13,35 @@ import kotlin.coroutines.*
13
13
* The testable main dispatcher used by kotlinx-coroutines-test.
14
14
* It is a [MainCoroutineDispatcher] that delegates all actions to a settable delegate.
15
15
*/
16
- internal class TestMainDispatcher (delegate : CoroutineDispatcher ):
16
+ internal class TestMainDispatcher (delegate : CoroutineDispatcher ? ):
17
17
MainCoroutineDispatcher (),
18
18
Delay
19
19
{
20
20
private val mainDispatcher = delegate
21
- private var delegate = NonConcurrentlyModifiable (mainDispatcher, " Dispatchers.Main" )
21
+
22
+ private var _delegate = NonConcurrentlyModifiable (mainDispatcher, " Dispatchers.Main" )
23
+
24
+ private val delegate
25
+ get() = _delegate .value ? : UnsetMainDispatcher
22
26
23
27
private val delay
24
- get() = delegate.value as ? Delay ? : defaultDelay
28
+ get() = delegate as ? Delay ? : nonMockedDelay
25
29
26
30
override val immediate: MainCoroutineDispatcher
27
- get() = (delegate.value as ? MainCoroutineDispatcher )?.immediate ? : this
31
+ get() = (delegate as ? MainCoroutineDispatcher )?.immediate ? : this
28
32
29
- override fun dispatch (context : CoroutineContext , block : Runnable ) = delegate.value. dispatch(context, block)
33
+ override fun dispatch (context : CoroutineContext , block : Runnable ) = delegate.dispatch(context, block)
30
34
31
- override fun isDispatchNeeded (context : CoroutineContext ): Boolean = delegate.value. isDispatchNeeded(context)
35
+ override fun isDispatchNeeded (context : CoroutineContext ): Boolean = delegate.isDispatchNeeded(context)
32
36
33
- override fun dispatchYield (context : CoroutineContext , block : Runnable ) = delegate.value. dispatchYield(context, block)
37
+ override fun dispatchYield (context : CoroutineContext , block : Runnable ) = delegate.dispatchYield(context, block)
34
38
35
39
fun setDispatcher (dispatcher : CoroutineDispatcher ) {
36
- delegate .value = dispatcher
40
+ _delegate .value = dispatcher
37
41
}
38
42
39
43
fun resetDispatcher () {
40
- delegate .value = mainDispatcher
44
+ _delegate .value = mainDispatcher
41
45
}
42
46
43
47
override fun scheduleResumeAfterDelay (timeMillis : Long , continuation : CancellableContinuation <Unit >) =
@@ -46,9 +50,11 @@ internal class TestMainDispatcher(delegate: CoroutineDispatcher):
46
50
override fun invokeOnTimeout (timeMillis : Long , block : Runnable , context : CoroutineContext ): DisposableHandle =
47
51
delay.invokeOnTimeout(timeMillis, block, context)
48
52
53
+ override fun toString (): String = " TestMainDispatcher[delegate=$delegate ]"
54
+
49
55
companion object {
50
56
internal val currentTestDispatcher
51
- get() = (Dispatchers .Main as ? TestMainDispatcher )?.delegate?.value as ? TestDispatcher
57
+ get() = (Dispatchers .Main as ? TestMainDispatcher )?.delegate as ? TestDispatcher
52
58
53
59
internal val currentTestScheduler
54
60
get() = currentTestDispatcher?.scheduler
@@ -86,11 +92,22 @@ internal class TestMainDispatcher(delegate: CoroutineDispatcher):
86
92
if (readers.value != 0 ) throw concurrentRW()
87
93
}
88
94
}
95
+
96
+ private object UnsetMainDispatcher : MainCoroutineDispatcher() {
97
+ override val immediate: MainCoroutineDispatcher get() = this
98
+ override fun isDispatchNeeded (context : CoroutineContext ): Boolean = missing()
99
+ override fun limitedParallelism (parallelism : Int ): CoroutineDispatcher = missing()
100
+ override fun dispatch (context : CoroutineContext , block : Runnable ) = missing()
101
+
102
+ private fun missing (): Nothing =
103
+ throw IllegalStateException (
104
+ " Dispatchers.Main is not available was not provided for tests via Dispatchers.setMain."
105
+ )
106
+
107
+ override fun toString (): String = " missing"
108
+ }
89
109
}
90
110
91
- @Suppress(" INVISIBLE_MEMBER" )
92
- private val defaultDelay
93
- inline get() = DefaultDelay
111
+ internal expect val nonMockedDelay: Delay
94
112
95
- @Suppress(" INVISIBLE_MEMBER" )
96
- internal expect fun Dispatchers.getTestMainDispatcher (): TestMainDispatcher
113
+ internal expect fun Dispatchers.getTestMainDispatcher (): TestMainDispatcher
0 commit comments