1 /* 2 * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.coroutines 6 7 import platform.CoreFoundation.* 8 import platform.darwin.* 9 import kotlin.coroutines.* 10 import kotlin.test.* 11 12 class MainDispatcherTest : TestBase() { 13 isMainThreadnull14 private fun isMainThread(): Boolean = CFRunLoopGetCurrent() == CFRunLoopGetMain() 15 private fun canTestMainDispatcher() = !isMainThread() 16 17 private fun runTestNotOnMainDispatcher(block: suspend CoroutineScope.() -> Unit) { 18 // skip if already on the main thread, run blocking doesn't really work well with that 19 if (!canTestMainDispatcher()) return 20 runTest(block = block) 21 } 22 23 @Test <lambda>null24 fun testDispatchNecessityCheckWithMainImmediateDispatcher() = runTestNotOnMainDispatcher { 25 val main = Dispatchers.Main.immediate 26 assertTrue(main.isDispatchNeeded(EmptyCoroutineContext)) 27 withContext(Dispatchers.Default) { 28 assertTrue(main.isDispatchNeeded(EmptyCoroutineContext)) 29 withContext(Dispatchers.Main) { 30 assertFalse(main.isDispatchNeeded(EmptyCoroutineContext)) 31 } 32 assertTrue(main.isDispatchNeeded(EmptyCoroutineContext)) 33 } 34 } 35 36 @Test <lambda>null37 fun testWithContext() = runTestNotOnMainDispatcher { 38 expect(1) 39 assertFalse(isMainThread()) 40 withContext(Dispatchers.Main) { 41 assertTrue(isMainThread()) 42 expect(2) 43 } 44 assertFalse(isMainThread()) 45 finish(3) 46 } 47 48 @Test <lambda>null49 fun testWithContextDelay() = runTestNotOnMainDispatcher { 50 expect(1) 51 withContext(Dispatchers.Main) { 52 assertTrue(isMainThread()) 53 expect(2) 54 delay(100) 55 assertTrue(isMainThread()) 56 expect(3) 57 } 58 assertFalse(isMainThread()) 59 finish(4) 60 } 61 62 @Test <lambda>null63 fun testWithTimeoutContextDelayNoTimeout() = runTestNotOnMainDispatcher { 64 expect(1) 65 withTimeout(1000) { 66 withContext(Dispatchers.Main) { 67 assertTrue(isMainThread()) 68 expect(2) 69 delay(100) 70 assertTrue(isMainThread()) 71 expect(3) 72 } 73 } 74 assertFalse(isMainThread()) 75 finish(4) 76 } 77 78 @Test <lambda>null79 fun testWithTimeoutContextDelayTimeout() = runTestNotOnMainDispatcher { 80 expect(1) 81 assertFailsWith<TimeoutCancellationException> { 82 withTimeout(100) { 83 withContext(Dispatchers.Main) { 84 assertTrue(isMainThread()) 85 expect(2) 86 delay(1000) 87 expectUnreached() 88 } 89 } 90 expectUnreached() 91 } 92 assertFalse(isMainThread()) 93 finish(3) 94 } 95 96 @Test <lambda>null97 fun testWithContextTimeoutDelayNoTimeout() = runTestNotOnMainDispatcher { 98 expect(1) 99 withContext(Dispatchers.Main) { 100 withTimeout(1000) { 101 assertTrue(isMainThread()) 102 expect(2) 103 delay(100) 104 assertTrue(isMainThread()) 105 expect(3) 106 } 107 } 108 assertFalse(isMainThread()) 109 finish(4) 110 } 111 112 @Test <lambda>null113 fun testWithContextTimeoutDelayTimeout() = runTestNotOnMainDispatcher { 114 expect(1) 115 assertFailsWith<TimeoutCancellationException> { 116 withContext(Dispatchers.Main) { 117 withTimeout(100) { 118 assertTrue(isMainThread()) 119 expect(2) 120 delay(1000) 121 expectUnreached() 122 } 123 } 124 expectUnreached() 125 } 126 assertFalse(isMainThread()) 127 finish(3) 128 } 129 } 130