@@ -13,7 +13,7 @@ import kotlin.coroutines.*
13
13
* This is similar to [runBlocking] but it will immediately progress past delays and into [launch] and [async] blocks.
14
14
* You can use this to write tests that execute in the presence of calls to [delay] without causing your test to take
15
15
* extra time.
16
- **
16
+ *
17
17
* ```
18
18
* @Test
19
19
* fun exampleTest() = runBlockingTest {
@@ -37,17 +37,14 @@ import kotlin.coroutines.*
37
37
* @throws UncompletedCoroutinesError If the [testBody] does not complete (or cancel) all coroutines that it launches
38
38
* (including coroutines suspended on join/await).
39
39
*
40
- * @param context An optional context that MUST contain a [DelayController] and/or [TestCoroutineExceptionHandler]
40
+ * @param context additional context elements. If [context] contains [CoroutineDispatcher] or [CoroutineExceptionHandler],
41
+ * then they must implement [DelayController] and [TestCoroutineExceptionHandler] respectively.
41
42
* @param testBody The code of the unit-test.
42
43
*/
43
44
@ExperimentalCoroutinesApi // Since 1.2.1, tentatively till 1.3.0
44
- public fun runBlockingTest (context : CoroutineContext ? = null , testBody : suspend TestCoroutineScope .() -> Unit ) {
45
+ public fun runBlockingTest (context : CoroutineContext = EmptyCoroutineContext , testBody : suspend TestCoroutineScope .() -> Unit ) {
45
46
val (safeContext, dispatcher) = context.checkArguments()
46
- // smart cast dispatcher to expose interface
47
- dispatcher as DelayController
48
-
49
47
val startingJobs = safeContext.activeJobs()
50
-
51
48
val scope = TestCoroutineScope (safeContext)
52
49
val deferred = scope.async {
53
50
scope.testBody()
@@ -72,37 +69,28 @@ private fun CoroutineContext.activeJobs(): Set<Job> {
72
69
*/
73
70
// todo: need documentation on how this extension is supposed to be used
74
71
@ExperimentalCoroutinesApi // Since 1.2.1, tentatively till 1.3.0
75
- public fun TestCoroutineScope.runBlockingTest (block : suspend TestCoroutineScope .() -> Unit ) {
76
- runBlockingTest(coroutineContext, block)
77
- }
72
+ public fun TestCoroutineScope.runBlockingTest (block : suspend TestCoroutineScope .() -> Unit ) = runBlockingTest(coroutineContext, block)
78
73
79
74
/* *
80
75
* Convenience method for calling [runBlockingTest] on an existing [TestCoroutineDispatcher].
81
76
*/
82
77
@ExperimentalCoroutinesApi // Since 1.2.1, tentatively till 1.3.0
83
- public fun TestCoroutineDispatcher.runBlockingTest (block : suspend TestCoroutineScope .() -> Unit ) {
84
- runBlockingTest(this , block)
85
- }
78
+ public fun TestCoroutineDispatcher.runBlockingTest (block : suspend TestCoroutineScope .() -> Unit ) = runBlockingTest(this , block)
86
79
87
- private fun CoroutineContext?.checkArguments (): Pair <CoroutineContext , ContinuationInterceptor > {
88
- var safeContext = this ? : TestCoroutineExceptionHandler () + TestCoroutineDispatcher ()
89
-
90
- val dispatcher = safeContext[ContinuationInterceptor ].run {
91
- this ?.let {
92
- require(this is DelayController ) { " Dispatcher must implement DelayController" }
93
- }
80
+ private fun CoroutineContext.checkArguments (): Pair <CoroutineContext , DelayController > {
81
+ // TODO optimize it
82
+ val dispatcher = get(ContinuationInterceptor ).run {
83
+ this ?.let { require(this is DelayController ) { " Dispatcher must implement DelayController: $this " } }
94
84
this ? : TestCoroutineDispatcher ()
95
85
}
96
86
97
- val exceptionHandler = safeContext[ CoroutineExceptionHandler ] .run {
87
+ val exceptionHandler = get( CoroutineExceptionHandler ) .run {
98
88
this ?.let {
99
- require(this is UncaughtExceptionCaptor ) { " coroutineExceptionHandler must implement UncaughtExceptionCaptor" }
89
+ require(this is UncaughtExceptionCaptor ) { " coroutineExceptionHandler must implement UncaughtExceptionCaptor: $this " }
100
90
}
101
91
this ? : TestCoroutineExceptionHandler ()
102
92
}
103
93
104
- val job = safeContext[Job ] ? : SupervisorJob ()
105
-
106
- safeContext = safeContext + dispatcher + exceptionHandler + job
107
- return Pair (safeContext, dispatcher)
108
- }
94
+ val job = get(Job ) ? : SupervisorJob ()
95
+ return Pair (this + dispatcher + exceptionHandler + job, dispatcher as DelayController )
96
+ }
0 commit comments