From e92f2a66bb4ec81c8a6183025f6366147e63802f Mon Sep 17 00:00:00 2001 From: Jean Silva Date: Thu, 3 Aug 2023 15:55:38 -0300 Subject: [PATCH] change: return CoroutineScope-based Loadable-Flow-creator functions return type to MutableStateFlow --- buildSrc/src/main/java/Versions.kt | 4 +- .../loadable/flow/Flow.extensions.kt | 43 ------------------- .../flow/MutableStateFlow.extensions.kt | 42 ++++++++++++++++++ .../loadable/flow/FlowExtensionsTests.kt | 12 +----- .../flow/MutableStateFlowExtensionsTests.kt | 18 ++++++++ 5 files changed, 64 insertions(+), 55 deletions(-) create mode 100644 loadable/src/test/java/com/jeanbarrossilva/loadable/flow/MutableStateFlowExtensionsTests.kt diff --git a/buildSrc/src/main/java/Versions.kt b/buildSrc/src/main/java/Versions.kt index aee4617..9a0a04d 100644 --- a/buildSrc/src/main/java/Versions.kt +++ b/buildSrc/src/main/java/Versions.kt @@ -16,8 +16,8 @@ object Versions { val java = JavaVersion.VERSION_11 object Loadable { - const val CODE = 18 - const val NAME = "1.6.5" + const val CODE = 19 + const val NAME = "1.6.6" const val SDK_COMPILE = 33 const val SDK_MIN = 21 const val SDK_TARGET = SDK_COMPILE diff --git a/loadable/src/main/java/com/jeanbarrossilva/loadable/flow/Flow.extensions.kt b/loadable/src/main/java/com/jeanbarrossilva/loadable/flow/Flow.extensions.kt index 32170f1..773020d 100644 --- a/loadable/src/main/java/com/jeanbarrossilva/loadable/flow/Flow.extensions.kt +++ b/loadable/src/main/java/com/jeanbarrossilva/loadable/flow/Flow.extensions.kt @@ -6,20 +6,15 @@ import com.jeanbarrossilva.loadable.ifLoaded import com.jeanbarrossilva.loadable.map import java.io.Serializable import kotlin.experimental.ExperimentalTypeInference -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.ProducerScope import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.channelFlow -import kotlinx.coroutines.flow.emitAll import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.withIndex -import kotlinx.coroutines.launch /** Returns a [Flow] containing only [failed][Loadable.Failed] values. **/ fun Flow>.filterIsFailed(): Flow> { @@ -46,21 +41,6 @@ fun Flow>.innerMap(transform: } } -/** - * Maps each emission made to this [Flow] to a [Loadable]. - * - * Emits, initially, [Loadable.Loading], [Loadable.Loaded] for each value and [Loadable.Failed] for - * thrown [Throwable]s. - * - * @param coroutineScope [CoroutineScope] in which the resulting [StateFlow] will be started and its - * value will be shared. - **/ -fun Flow.loadable(coroutineScope: CoroutineScope): StateFlow> { - return loadableFlow(coroutineScope) { - collect(::load) - } -} - /** * Maps each emission made to this [Flow] to a [Loadable]. * @@ -124,29 +104,6 @@ fun Flow>.unwrapContent(): Flow> { } as Flow> } -/** - * Creates a [StateFlow] of [Loadable]s that's started and shared in the [coroutineScope] and emits - * them through [load] with a [LoadableScope]. Its initial [value][StateFlow.value] is - * [loading][Loadable.Loading]. - * - * @param coroutineScope [CoroutineScope] in which the resulting [StateFlow] will be started and its - * value will be shared. - * @param load Operations to be made on the [LoadableScope] responsible for emitting [Loadable]s - * sent to it to the created [StateFlow]. - **/ -fun loadableFlow( - coroutineScope: CoroutineScope, - load: suspend LoadableScope.() -> Unit -): StateFlow> { - return loadableFlow() - .apply { - coroutineScope.launch { - emitAll(emptyLoadableFlow(load)) - } - } - .asStateFlow() -} - /** * Creates a [Flow] of [Loadable]s that emits them through [load] with a [LoadableScope] and has an * initial [loading][Loadable.Loading] value. diff --git a/loadable/src/main/java/com/jeanbarrossilva/loadable/flow/MutableStateFlow.extensions.kt b/loadable/src/main/java/com/jeanbarrossilva/loadable/flow/MutableStateFlow.extensions.kt index 77b9a9f..47473cd 100644 --- a/loadable/src/main/java/com/jeanbarrossilva/loadable/flow/MutableStateFlow.extensions.kt +++ b/loadable/src/main/java/com/jeanbarrossilva/loadable/flow/MutableStateFlow.extensions.kt @@ -1,8 +1,50 @@ package com.jeanbarrossilva.loadable.flow import com.jeanbarrossilva.loadable.Loadable +import com.jeanbarrossilva.loadable.LoadableScope import java.io.Serializable +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.launch + +/** + * Maps each emission made to this [Flow] to a [Loadable]. + * + * Emits, initially, [Loadable.Loading], [Loadable.Loaded] for each value and [Loadable.Failed] for + * thrown [Throwable]s. + * + * @param coroutineScope [CoroutineScope] in which the resulting [MutableStateFlow] will be started + * and its [value][MutableStateFlow.value] will be shared. + **/ +fun Flow.loadable(coroutineScope: CoroutineScope): + MutableStateFlow> { + return loadableFlow(coroutineScope) { + collect(::load) + } +} + +/** + * Creates a [MutableStateFlow] of [Loadable]s that's started and shared in the [coroutineScope] and + * emits them through [load] with a [LoadableScope]. Its initial [value][MutableStateFlow.value] is + * [loading][Loadable.Loading]. + * + * @param coroutineScope [CoroutineScope] in which the resulting [MutableStateFlow] will be started + * and its [value][MutableStateFlow.value] will be shared. + * @param load Operations to be made on the [LoadableScope] responsible for emitting [Loadable]s + * sent to it to the created [MutableStateFlow]. + **/ +fun loadableFlow( + coroutineScope: CoroutineScope, + load: suspend LoadableScope.() -> Unit +): MutableStateFlow> { + return loadableFlow().apply { + coroutineScope.launch { + emitAll(emptyLoadableFlow(load)) + } + } +} /** Creates a [MutableStateFlow] with a [Loadable.Loading] as its initial value. **/ fun loadableFlow(): MutableStateFlow> { diff --git a/loadable/src/test/java/com/jeanbarrossilva/loadable/flow/FlowExtensionsTests.kt b/loadable/src/test/java/com/jeanbarrossilva/loadable/flow/FlowExtensionsTests.kt index c98cd33..9005604 100644 --- a/loadable/src/test/java/com/jeanbarrossilva/loadable/flow/FlowExtensionsTests.kt +++ b/loadable/src/test/java/com/jeanbarrossilva/loadable/flow/FlowExtensionsTests.kt @@ -50,15 +50,6 @@ internal class FlowExtensionsTests { } } - @Test - fun `GIVEN a Loadable Flow with an initial content WHEN collecting it THEN the value that's emitted first is a Loaded one`() { // ktlint-disable max-line-length - runTest { - loadableFlowOf(0).test { - assertEquals(Loadable.Loaded(0), awaitItem()) - } - } - } - @Test fun `GIVEN a Loadable Flow WHEN filtering Failed values THEN they're all emitted`() { runTest { @@ -158,9 +149,10 @@ internal class FlowExtensionsTests { @Test fun `GIVEN a Flow WHEN converting it into a Loadable one in a CoroutineScope THEN Loading is only emitted once as an initial value`() { // ktlint-disable max-line-length runTest { - flowOf(0).loadable(this).test { + flowOf(0).loadable().test { assertIs>(awaitItem()) assertEquals(Loadable.Loaded(0), awaitItem()) + awaitComplete() } } } diff --git a/loadable/src/test/java/com/jeanbarrossilva/loadable/flow/MutableStateFlowExtensionsTests.kt b/loadable/src/test/java/com/jeanbarrossilva/loadable/flow/MutableStateFlowExtensionsTests.kt new file mode 100644 index 0000000..db95e63 --- /dev/null +++ b/loadable/src/test/java/com/jeanbarrossilva/loadable/flow/MutableStateFlowExtensionsTests.kt @@ -0,0 +1,18 @@ +package com.jeanbarrossilva.loadable.flow + +import app.cash.turbine.test +import com.jeanbarrossilva.loadable.Loadable +import kotlin.test.Test +import kotlinx.coroutines.test.runTest +import org.junit.Assert + +internal class MutableStateFlowExtensionsTests { + @Test + fun `GIVEN a Loadable Flow with an initial content WHEN collecting it THEN the value that's emitted first is a Loaded one`() { // ktlint-disable max-line-length + runTest { + loadableFlowOf(0).test { + Assert.assertEquals(Loadable.Loaded(0), awaitItem()) + } + } + } +}