Skip to content

Commit

Permalink
Add FlowCycler funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
janseeger committed Dec 5, 2023
1 parent 84657e7 commit c7838cd
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package de.sipgate.dachlatten.flow

import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flow
import kotlin.time.Duration

fun tickEvery(time: Duration) = flow {
while (true) {
emit(Unit)
delay(time)
}
}

fun <T> cycleBetween(
tickerInterval: Duration,
flow1: Flow<T>,
flow2: Flow<T>,
): Flow<T> = cycleBetween(tickEvery(tickerInterval), flow1, flow2)

fun <I,T> cycleBetween(
ticker: Flow<I>,
flow1: Flow<T>,
flow2: Flow<T>,
): Flow<T> {
var first = false
return combine(ticker, flow1, flow2) { _, a, b ->
first = !first
return@combine when {
first -> a
else -> b
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package de.sipgate.dachlatten.flow

import app.cash.turbine.test
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.advanceTimeBy
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import kotlin.time.Duration.Companion.seconds

class FlowCyclerTest {

@Test
fun cycleBetweenSwitchesTheFlowBeingEmitted() = runTest {
val flow1 = flowOf("flow1")
val flow2 = flowOf("flow2")

val trigger = MutableStateFlow(1)

cycleBetween(trigger, flow1, flow2).test {
assertEquals("flow1", awaitItem())
trigger.value++
assertEquals("flow2", awaitItem())
trigger.value++
assertEquals("flow1", awaitItem())
}
}

@Test
fun cycleBetweenWorksWithNullValues() = runTest {
val flow1 = flowOf("flow1")
val flow2 = flowOf<String?>(null)

val trigger = MutableStateFlow(1)

cycleBetween(trigger, flow1, flow2).test {
assertEquals("flow1", awaitItem())
trigger.value++
assertEquals(null, awaitItem())
trigger.value++
assertEquals("flow1", awaitItem())
}
}

@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun cycleBetweenWithDurationWorks() = runTest {
val flow1 = flowOf("flow1")
val flow2 = flowOf<String?>("flow2")

val trigger = MutableStateFlow(1)

cycleBetween(5.seconds, flow1, flow2).test {
assertEquals("flow1", awaitItem())
expectNoEvents()
advanceTimeBy(5.seconds)
assertEquals("flow2", awaitItem())
expectNoEvents()
advanceTimeBy(5.seconds)
assertEquals("flow1", awaitItem())
}
}
}

0 comments on commit c7838cd

Please sign in to comment.