@@ -21,27 +21,30 @@ import com.apollographql.apollo3.integration.normalizer.EpisodeHeroNameWithIdQue
21
21
import com.apollographql.apollo3.integration.normalizer.HeroAndFriendsNamesWithIDsQuery
22
22
import com.apollographql.apollo3.integration.normalizer.StarshipByIdQuery
23
23
import com.apollographql.apollo3.integration.normalizer.type.Episode
24
- import com.apollographql.mockserver.MockResponse
25
- import com.apollographql.mockserver.MockServer
26
- import com.apollographql.mockserver.enqueueString
27
24
import com.apollographql.apollo3.testing.QueueTestNetworkTransport
28
- import com.apollographql.apollo3.testing.assertNoElement
29
- import com.apollographql.apollo3.testing.awaitElement
30
- import com.apollographql.apollo3.testing.enqueue
31
25
import com.apollographql.apollo3.testing.enqueueTestNetworkError
32
26
import com.apollographql.apollo3.testing.enqueueTestResponse
33
27
import com.apollographql.apollo3.testing.internal.runTest
28
+ import com.apollographql.mockserver.MockResponse
29
+ import com.apollographql.mockserver.MockServer
30
+ import com.apollographql.mockserver.enqueueString
31
+ import kotlinx.coroutines.CoroutineScope
34
32
import kotlinx.coroutines.CoroutineStart
33
+ import kotlinx.coroutines.Dispatchers
34
+ import kotlinx.coroutines.ExperimentalCoroutinesApi
35
+ import kotlinx.coroutines.TimeoutCancellationException
35
36
import kotlinx.coroutines.cancelAndJoin
36
37
import kotlinx.coroutines.channels.Channel
37
38
import kotlinx.coroutines.delay
38
39
import kotlinx.coroutines.flow.first
39
40
import kotlinx.coroutines.launch
41
+ import kotlinx.coroutines.withContext
40
42
import kotlinx.coroutines.withTimeout
41
43
import kotlin.test.Test
42
44
import kotlin.test.assertEquals
43
45
import kotlin.test.assertIs
44
46
import kotlin.test.assertNull
47
+ import kotlin.time.Duration.Companion.minutes
45
48
46
49
class WatcherTest {
47
50
private lateinit var apolloClient: ApolloClient
@@ -72,14 +75,24 @@ class WatcherTest {
72
75
HeroAndFriendsNamesWithIDsQuery .Friend (" 1003" , " Leia Organa" ),
73
76
)))
74
77
78
+ @OptIn(ExperimentalCoroutinesApi ::class )
79
+ private fun myRunTest (block : suspend CoroutineScope .() -> Unit ) {
80
+ kotlinx.coroutines.test.runTest(timeout = 10 .minutes) {
81
+ withContext(Dispatchers .Default .limitedParallelism(1 )) {
82
+ block()
83
+ }
84
+ }
85
+ }
75
86
/* *
76
87
* Executing the same query out of band should update the watcher
77
88
*
78
89
* Also, this test checks that the watcher gets control fast enough to subscribe to
79
90
* cache changes
80
91
*/
81
92
@Test
82
- fun sameQueryTriggersWatcher () = runTest(before = { setUp() }) {
93
+ fun sameQueryTriggersWatcher () = myRunTest {
94
+ setUp()
95
+
83
96
val query = EpisodeHeroNameQuery (Episode .EMPIRE )
84
97
val channel = Channel <EpisodeHeroNameQuery .Data ?>()
85
98
@@ -191,7 +204,7 @@ class WatcherTest {
191
204
apolloClient.enqueueTestResponse(query, episodeHeroNameData)
192
205
apolloClient.query(query).fetchPolicy(FetchPolicy .NetworkOnly ).execute()
193
206
194
- channel.assertNoElement ()
207
+ channel.assertEmpty ()
195
208
196
209
job.cancel()
197
210
}
@@ -256,7 +269,7 @@ class WatcherTest {
256
269
.fetchPolicy(FetchPolicy .NetworkOnly )
257
270
.execute()
258
271
259
- channel.assertNoElement ()
272
+ channel.assertEmpty ()
260
273
261
274
job.cancel()
262
275
}
@@ -322,7 +335,7 @@ class WatcherTest {
322
335
}
323
336
job.cancelAndJoin()
324
337
325
- channel.assertNoElement ()
338
+ channel.assertEmpty ()
326
339
}
327
340
328
341
/* *
@@ -373,7 +386,7 @@ class WatcherTest {
373
386
374
387
// Should see 1 cache miss values
375
388
assertIs<CacheMissException >(channel.awaitElement().exception)
376
- channel.assertNoElement ()
389
+ channel.assertEmpty ()
377
390
378
391
job.cancel()
379
392
}
@@ -578,7 +591,7 @@ class WatcherTest {
578
591
579
592
// 2. Exception from the network (null data)
580
593
assertNull(channel.awaitElement())
581
- channel.assertNoElement ()
594
+ channel.assertEmpty ()
582
595
583
596
// Another newer call updates the cache with "ArTwo"
584
597
apolloClient.enqueueTestResponse(query, episodeHeroNameChangedTwoData)
@@ -624,9 +637,24 @@ class WatcherTest {
624
637
625
638
}
626
639
627
- suspend fun <D > Channel<D>.assertCount (count : Int ) {
640
+ internal suspend fun <D > Channel<D>.assertCount (count : Int ) {
628
641
repeat(count) {
629
642
awaitElement()
630
643
}
631
- assertNoElement()
644
+ assertEmpty()
645
+ }
646
+
647
+ internal suspend fun <T > Channel<T>.awaitElement (timeoutMillis : Long = 30000) = withTimeout(timeoutMillis) {
648
+ receive()
649
+ }
650
+
651
+ internal suspend fun <T > Channel<T>.assertEmpty (timeoutMillis : Long = 300): Unit {
652
+ try {
653
+ withTimeout(timeoutMillis) {
654
+ receive()
655
+ }
656
+ error(" An item was unexpectedly received" )
657
+ } catch (_: TimeoutCancellationException ) {
658
+ // nothing
659
+ }
632
660
}
0 commit comments