1 /*
2  * Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 
5 package kotlinx.coroutines.test
6 
7 import kotlinx.coroutines.*
8 import org.junit.Test
9 import kotlin.test.*
10 
11 class TestCoroutineDispatcherTest {
12     @Test
whenStringCalled_itReturnsStringnull13     fun whenStringCalled_itReturnsString() {
14         val subject = TestCoroutineDispatcher()
15         assertEquals("TestCoroutineDispatcher[currentTime=0ms, queued=0]", subject.toString())
16     }
17 
18     @Test
whenStringCalled_itReturnsCurrentTimenull19     fun whenStringCalled_itReturnsCurrentTime() {
20         val subject = TestCoroutineDispatcher()
21         subject.advanceTimeBy(1000)
22         assertEquals("TestCoroutineDispatcher[currentTime=1000ms, queued=0]", subject.toString())
23     }
24 
25     @Test
whenStringCalled_itShowsQueuedJobsnull26     fun whenStringCalled_itShowsQueuedJobs() {
27         val subject = TestCoroutineDispatcher()
28         val scope = TestCoroutineScope(subject)
29         scope.pauseDispatcher()
30         scope.launch {
31             delay(1_000)
32         }
33         assertEquals("TestCoroutineDispatcher[currentTime=0ms, queued=1]", subject.toString())
34         scope.advanceTimeBy(50)
35         assertEquals("TestCoroutineDispatcher[currentTime=50ms, queued=1]", subject.toString())
36         scope.advanceUntilIdle()
37         assertEquals("TestCoroutineDispatcher[currentTime=1000ms, queued=0]", subject.toString())
38     }
39 
40     @Test
whenDispatcherPaused_doesntAutoProgressCurrentnull41     fun whenDispatcherPaused_doesntAutoProgressCurrent() {
42         val subject = TestCoroutineDispatcher()
43         subject.pauseDispatcher()
44         val scope = CoroutineScope(subject)
45         var executed = 0
46         scope.launch {
47             executed++
48         }
49         assertEquals(0, executed)
50     }
51 
52     @Test
whenDispatcherResumed_doesAutoProgressCurrentnull53     fun whenDispatcherResumed_doesAutoProgressCurrent() {
54         val subject = TestCoroutineDispatcher()
55         val scope = CoroutineScope(subject)
56         var executed = 0
57         scope.launch {
58             executed++
59         }
60 
61         assertEquals(1, executed)
62     }
63 
64     @Test
whenDispatcherResumed_doesNotAutoProgressTimenull65     fun whenDispatcherResumed_doesNotAutoProgressTime() {
66         val subject = TestCoroutineDispatcher()
67         val scope = CoroutineScope(subject)
68         var executed = 0
69         scope.launch {
70             delay(1_000)
71             executed++
72         }
73 
74         assertEquals(0, executed)
75         subject.advanceUntilIdle()
76         assertEquals(1, executed)
77     }
78 
79     @Test
whenDispatcherPaused_thenResume_itDoesDispatchCurrentnull80     fun whenDispatcherPaused_thenResume_itDoesDispatchCurrent() {
81         val subject = TestCoroutineDispatcher()
82         subject.pauseDispatcher()
83         val scope = CoroutineScope(subject)
84         var executed = 0
85         scope.launch {
86             executed++
87         }
88 
89         assertEquals(0, executed)
90         subject.resumeDispatcher()
91         assertEquals(1, executed)
92     }
93 
94     @Test(expected = UncompletedCoroutinesError::class)
whenDispatcherHasUncompletedCoroutines_itThrowsErrorInCleanupnull95     fun whenDispatcherHasUncompletedCoroutines_itThrowsErrorInCleanup() {
96         val subject = TestCoroutineDispatcher()
97         subject.pauseDispatcher()
98         val scope = CoroutineScope(subject)
99         scope.launch {
100             delay(1_000)
101         }
102         subject.cleanupTestCoroutines()
103     }
104 
105     @Test
whenDispatchCalled_runsOnCurrentThreadnull106     fun whenDispatchCalled_runsOnCurrentThread() {
107         val currentThread = Thread.currentThread()
108         val subject = TestCoroutineDispatcher()
109         val scope = TestCoroutineScope(subject)
110 
111         val deferred = scope.async(Dispatchers.Default) {
112             withContext(subject) {
113                 assertNotSame(currentThread, Thread.currentThread())
114                 3
115             }
116         }
117 
118         runBlocking {
119             // just to ensure the above code terminates
120             assertEquals(3, deferred.await())
121         }
122     }
123 
124     @Test
whenAllDispatchersMocked_runsOnSameThreadnull125     fun whenAllDispatchersMocked_runsOnSameThread() {
126         val currentThread = Thread.currentThread()
127         val subject = TestCoroutineDispatcher()
128         val scope = TestCoroutineScope(subject)
129 
130         val deferred = scope.async(subject) {
131             withContext(subject) {
132                 assertSame(currentThread, Thread.currentThread())
133                 3
134             }
135         }
136 
137         runBlocking {
138             // just to ensure the above code terminates
139             assertEquals(3, deferred.await())
140         }
141     }
142 }