Skip to content

Commit 4c76489

Browse files
committed
Add FlowCollectionKtTest
1 parent e938770 commit 4c76489

File tree

2 files changed

+218
-1
lines changed

2 files changed

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

0 commit comments

Comments
 (0)