Skip to content

Commit

Permalink
Merge pull request #16 from floschu/feature/state-flow
Browse files Browse the repository at this point in the history
Use StateFlow
  • Loading branch information
floschu authored May 10, 2020
2 parents 2e011f3 + 9b9cc3a commit e98c862
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.BroadcastChannel
import kotlinx.coroutines.channels.Channel.Factory.BUFFERED
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
Expand Down Expand Up @@ -46,23 +46,23 @@ internal class ControllerImplementation<Action, Mutation, State>(
internal val stateJob: Job // internal for testing

private val actionChannel = BroadcastChannel<Action>(BUFFERED)
private val stateChannel = ConflatedBroadcastChannel<State>()
private val stateFlow = MutableStateFlow(initialState)
private val controllerStub by lazy { ControllerStubImplementation<Action, State>(initialState) }

override val state: Flow<State>
get() = if (!stubEnabled) {
if (!stateJob.isActive) startStateJob()
stateChannel.asFlow()
stateFlow
} else {
controllerStub.stateChannel.asFlow()
controllerStub.stateFlow
}

override val currentState: State
get() = if (!stubEnabled) {
if (!stateJob.isActive) startStateJob()
stateChannel.value
stateFlow.value
} else {
controllerStub.stateChannel.value
controllerStub.stateFlow.value
}

override fun dispatch(action: Action) {
Expand Down Expand Up @@ -117,7 +117,7 @@ internal class ControllerImplementation<Action, Mutation, State>(
.onStart { controllerLog.log(ControllerEvent.Started(tag)) }
.onEach { state ->
controllerLog.log(ControllerEvent.State(tag, state.toString()))
stateChannel.send(state)
this@ControllerImplementation.stateFlow.value = state
}
.onCompletion { controllerLog.log(ControllerEvent.Completed(tag)) }
.collect()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package at.florianschuster.control

import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.ConflatedBroadcastChannel
import kotlinx.coroutines.flow.MutableStateFlow

/**
* Use this [ControllerStub] for view testing.
Expand Down Expand Up @@ -30,11 +30,11 @@ internal class ControllerStubImplementation<Action, State>(
) : ControllerStub<Action, State> {

internal val mutableActions = mutableListOf<Action>()
internal val stateChannel = ConflatedBroadcastChannel(initialState)
internal val stateFlow = MutableStateFlow(initialState)

override val actions: List<Action> get() = mutableActions

override fun setState(state: State) {
stateChannel.offer(state)
stateFlow.value = state
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ internal class ImplementationTest {
}

@Test
fun `synchronous controller builder`() {
fun `synchronous controller`() {
val counterSut = testCoroutineScope.createSynchronousController<Int, Int>(
tag = "counter",
initialState = 0,
Expand All @@ -96,6 +96,19 @@ internal class ImplementationTest {
assertEquals(6, counterSut.currentState)
}

@Test
fun `only distinct states are emitted`() {
val sut = testCoroutineScope.createSynchronousController<Unit, Int>(
0,
reducer = { _, previousState -> previousState }
)
val testFlow = sut.state.testIn(testCoroutineScope)
sut.dispatch(Unit)
sut.dispatch(Unit)
sut.dispatch(Unit)
testFlow expect emissionCount(1) // no state changes
}

@Test
fun `collector receives latest and following states`() {
val sut = testCoroutineScope.counterController() // 0
Expand Down
6 changes: 6 additions & 0 deletions examples/example-counter/lint.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<lint>
<!-- Temporary until https://github.com/Kotlin/kotlinx.coroutines/issues/2004 is resolved. -->
<issue id="InvalidPackage">
<ignore path="**/kotlinx-coroutines-core-*.jar"/>
</issue>
</lint>
6 changes: 6 additions & 0 deletions examples/example-github/lint.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<lint>
<!-- Temporary until https://github.com/Kotlin/kotlinx.coroutines/issues/2004 is resolved. -->
<issue id="InvalidPackage">
<ignore path="**/kotlinx-coroutines-core-*.jar"/>
</issue>
</lint>

0 comments on commit e98c862

Please sign in to comment.