Skip to content

Commit 76b7b0e

Browse files
committed
Add FlowCollectionKtTest
1 parent 39352b8 commit 76b7b0e

File tree

2 files changed

+221
-1
lines changed

2 files changed

+221
-1
lines changed

composed-core/src/test/kotlin/com/w2sv/composed/core/DisposableEffectsKtTest.kt renamed to composed-core/src/test/kotlin/com/w2sv/composed/core/DisposableEffectKtTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import org.junit.runner.RunWith
1515
import org.robolectric.RobolectricTestRunner
1616

1717
@RunWith(RobolectricTestRunner::class)
18-
class DisposableEffectsKtTest {
18+
class DisposableEffectKtTest {
1919

2020
@get:Rule
2121
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
package com.w2sv.composed.core
2+
3+
import androidx.activity.ComponentActivity
4+
import androidx.compose.runtime.getValue
5+
import androidx.compose.runtime.mutableStateOf
6+
import androidx.compose.runtime.setValue
7+
import androidx.compose.ui.test.junit4.createAndroidComposeRule
8+
import kotlinx.coroutines.flow.MutableSharedFlow
9+
import kotlinx.coroutines.flow.flowOf
10+
import kotlinx.coroutines.test.runTest
11+
import org.junit.Assert.assertEquals
12+
import org.junit.Rule
13+
import org.junit.Test
14+
import org.junit.runner.RunWith
15+
import org.robolectric.RobolectricTestRunner
16+
17+
@RunWith(RobolectricTestRunner::class)
18+
class FlowCollectionKtTest {
19+
20+
@get:Rule
21+
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
22+
23+
// ------------------------------------------------------------
24+
// CollectFromFlow
25+
// ------------------------------------------------------------
26+
27+
@Test
28+
fun `CollectFromFlow collects initial emissions`() =
29+
runTest {
30+
val flow = MutableSharedFlow<Int>()
31+
val collected = mutableListOf<Int>()
32+
33+
composeTestRule.setContent {
34+
CollectFromFlow(flow) { value -> collected.add(value) }
35+
}
36+
37+
flow.emit(1)
38+
flow.emit(2)
39+
40+
assertEquals(listOf(1, 2), collected)
41+
}
42+
43+
@Test
44+
fun `CollectFromFlow restarts collection when key changes`() =
45+
runTest {
46+
val flow = flowOf(1, 2)
47+
val collected = mutableListOf<Int>()
48+
var key by mutableStateOf("A")
49+
50+
composeTestRule.setContent {
51+
CollectFromFlow(
52+
flow = flow,
53+
key1 = key,
54+
collector = { collected.add(it) }
55+
)
56+
}
57+
58+
composeTestRule.runOnIdle { key = "B" }
59+
composeTestRule.waitForIdle()
60+
61+
assertEquals(listOf(1, 2, 1, 2), collected)
62+
}
63+
64+
@Test
65+
fun `CollectFromFlow updates collector`() =
66+
runTest {
67+
val flow = MutableSharedFlow<Int>()
68+
69+
var firstCount = 0
70+
var secondCount = 0
71+
72+
var collector: suspend (Int) -> Unit by mutableStateOf({ firstCount++ })
73+
74+
composeTestRule.setContent {
75+
CollectFromFlow(flow, collector = collector)
76+
}
77+
78+
flow.emit(1)
79+
composeTestRule.runOnIdle { collector = { secondCount++ } } // should be picked up
80+
composeTestRule.waitForIdle()
81+
flow.emit(1)
82+
83+
assertEquals(1, firstCount)
84+
assertEquals(1, secondCount)
85+
}
86+
87+
// ------------------------------------------------------------
88+
// CollectLatestFromFlow
89+
// ------------------------------------------------------------
90+
91+
@Test
92+
fun `CollectLatestFromFlow collects values`() =
93+
runTest {
94+
val flow = MutableSharedFlow<Int>()
95+
val received = mutableListOf<Int>()
96+
97+
composeTestRule.setContent {
98+
CollectLatestFromFlow(flow) { received.add(it) }
99+
}
100+
101+
flow.emit(10)
102+
flow.emit(20)
103+
104+
assertEquals(listOf(10, 20), received)
105+
}
106+
107+
@Test
108+
fun `CollectLatestFromFlow restarts when key changes`() {
109+
val flow = flowOf(1, 2)
110+
val collected = mutableListOf<Int>()
111+
var key by mutableStateOf("A")
112+
113+
composeTestRule.setContent {
114+
CollectLatestFromFlow(
115+
flow = flow,
116+
key1 = key,
117+
action = { collected.add(it) }
118+
)
119+
}
120+
121+
composeTestRule.runOnIdle { key = "B" }
122+
composeTestRule.waitForIdle()
123+
124+
assertEquals(listOf(1, 2, 1, 2), collected)
125+
}
126+
127+
@Test
128+
fun `CollectLatestFromFlow updates action`() =
129+
runTest {
130+
val flow = MutableSharedFlow<Int>()
131+
132+
var first = 0
133+
var second = 0
134+
var action: suspend (Int) -> Unit by mutableStateOf({ first++ })
135+
136+
composeTestRule.setContent {
137+
CollectLatestFromFlow(flow, action = action)
138+
}
139+
140+
flow.emit(1)
141+
142+
composeTestRule.runOnIdle { action = { second++ } }
143+
composeTestRule.waitForIdle()
144+
145+
flow.emit(1)
146+
147+
assertEquals(1, first)
148+
assertEquals(1, second)
149+
}
150+
151+
// ------------------------------------------------------------
152+
// OnChange
153+
// ------------------------------------------------------------
154+
155+
@Test
156+
fun `OnChange triggers callback for initial value`() {
157+
var count = 0
158+
159+
composeTestRule.setContent {
160+
OnChange(value = "Hello") { count++ }
161+
}
162+
163+
assertEquals(1, count)
164+
}
165+
166+
@Test
167+
fun `OnChange triggers only when value changes`() {
168+
var count = 0
169+
var value by mutableStateOf("A")
170+
171+
composeTestRule.setContent {
172+
OnChange(value) { count++ }
173+
}
174+
175+
composeTestRule.runOnIdle { value = "B" }
176+
composeTestRule.runOnIdle { value = "C" }
177+
composeTestRule.waitForIdle()
178+
179+
assertEquals(3, count) // A → B → C
180+
}
181+
182+
@Test
183+
fun `OnChange updates callback`() {
184+
var first = 0
185+
var second = 0
186+
187+
var callback: suspend (String) -> Unit by mutableStateOf({ first++ })
188+
var value by mutableStateOf("Initial")
189+
190+
composeTestRule.setContent {
191+
OnChange(value, callback = callback)
192+
}
193+
194+
composeTestRule.runOnIdle {
195+
callback = { second++ }
196+
value = "Updated"
197+
}
198+
composeTestRule.waitForIdle()
199+
200+
assertEquals(1, first)
201+
assertEquals(1, second)
202+
}
203+
204+
@Test
205+
fun `OnChange restarts when keys change`() {
206+
var count = 0
207+
var value by mutableStateOf("A")
208+
var key by mutableStateOf(0)
209+
210+
composeTestRule.setContent {
211+
OnChange(value, key1 = key) { count++ }
212+
}
213+
214+
composeTestRule.runOnIdle { key = 1 }
215+
composeTestRule.runOnIdle { key = 2 }
216+
composeTestRule.waitForIdle()
217+
218+
assertEquals(3, count) // initial + 2 relaunches
219+
}
220+
}

0 commit comments

Comments
 (0)