Skip to content

Commit

Permalink
Update dependencies and remove unneeded code
Browse files Browse the repository at this point in the history
  • Loading branch information
floschu committed Apr 11, 2022
1 parent 6b2ff31 commit 6bd9d72
Show file tree
Hide file tree
Showing 33 changed files with 724 additions and 729 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# changelog

## `[1.0.0]` - Unreleased
## `[1.0.0]` - 2022-04-11

- binary compatibility will now be verified and held up on every release.
- Remove `Controller.currentState`.
- Remove `Flow.bind` and `Flow.distinctMap` extensions.
- Binary compatibility will now be verified and held up on every release.

## `[0.15.0]` - 2021-10-20

Expand Down
16 changes: 8 additions & 8 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
buildscript {
repositories {
google()
jcenter()
mavenCentral()
maven(url = "https://plugins.gradle.org/m2/")
}

dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31")
classpath("info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.7.0")
classpath("org.jetbrains.kotlinx:binary-compatibility-validator:0.7.1")
classpath("com.vanniktech:gradle-maven-publish-plugin:0.18.0")
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.5.31")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.10")
classpath("info.solidsoft.gradle.pitest:gradle-pitest-plugin:1.7.4")
classpath("org.jetbrains.kotlinx:binary-compatibility-validator:0.8.0")
classpath("com.vanniktech:gradle-maven-publish-plugin:0.19.0")
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.6.10")

classpath("com.android.tools.build:gradle:7.0.3")
classpath("org.jetbrains.kotlin:kotlin-serialization:1.5.31")
classpath("com.android.tools.build:gradle:7.0.4")
classpath("org.jetbrains.kotlin:kotlin-serialization:1.6.20")
}
}

Expand All @@ -23,6 +22,7 @@ plugins {
id("org.jlleitschuh.gradle.ktlint").version("10.0.0")
`maven-publish`
signing
id("com.github.ben-manes.versions").version("0.42.0")
}

// ---- api-validation --- //
Expand Down
15 changes: 6 additions & 9 deletions control-core/api/control-core.api
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
public abstract interface class at/florianschuster/control/Controller {
public abstract fun dispatch (Ljava/lang/Object;)V
public abstract fun getCurrentState ()Ljava/lang/Object;
public abstract fun getState ()Lkotlinx/coroutines/flow/StateFlow;
}

Expand Down Expand Up @@ -98,14 +97,6 @@ public abstract interface class at/florianschuster/control/EffectReducerContext
public abstract interface class at/florianschuster/control/EffectTransformerContext : at/florianschuster/control/EffectEmitter, at/florianschuster/control/TransformerContext {
}

public final class at/florianschuster/control/ExtensionsKt {
public static final fun bind (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
public static final fun distinctMap (Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
public static final fun takeUntil (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
public static final fun takeUntil (Lkotlinx/coroutines/flow/Flow;ZLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
public static synthetic fun takeUntil$default (Lkotlinx/coroutines/flow/Flow;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
}

public abstract interface class at/florianschuster/control/LoggerContext {
public abstract fun getEvent ()Lat/florianschuster/control/ControllerEvent;
}
Expand All @@ -123,6 +114,12 @@ public final class at/florianschuster/control/StubKt {
public static final fun toStub (Lat/florianschuster/control/EffectController;)Lat/florianschuster/control/EffectControllerStub;
}

public final class at/florianschuster/control/TakeUntilKt {
public static final fun takeUntil (Lkotlinx/coroutines/flow/Flow;Lkotlinx/coroutines/flow/Flow;)Lkotlinx/coroutines/flow/Flow;
public static final fun takeUntil (Lkotlinx/coroutines/flow/Flow;ZLkotlin/jvm/functions/Function2;)Lkotlinx/coroutines/flow/Flow;
public static synthetic fun takeUntil$default (Lkotlinx/coroutines/flow/Flow;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/flow/Flow;
}

public abstract interface class at/florianschuster/control/TransformerContext {
}

59 changes: 29 additions & 30 deletions control-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,41 @@ plugins {
}

dependencies {
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2")
testImplementation("io.mockk:mockk:1.12.0")
testImplementation("at.florianschuster.test:coroutines-test-extensions:0.1.2")
}

// ---- kotlin --- //
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1")

tasks.compileTestKotlin {
kotlinOptions.freeCompilerArgs = listOf(
"-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-Xuse-experimental=kotlinx.coroutines.FlowPreview"
)
testImplementation(kotlin("test"))
testImplementation("io.mockk:mockk:1.12.3")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.1")
}

// ---- end kotlin --- //

// ---- jacoco --- //

tasks.jacocoTestCoverageVerification {
violationRules {
rule { limit { minimum = "0.94".toBigDecimal() } }
rule { limit { minimum = "0.95".toBigDecimal() } }
}
classDirectories.setFrom(
sourceSets.main.get().output.asFileTree.matching {
// jacoco cannot handle inline functions properly
exclude(
"at/florianschuster/control/DefaultTagKt*",
"at/florianschuster/control/TakeUntilKt*",
)
// builders
exclude(
"at/florianschuster/control/ControllerKt*",
"at/florianschuster/control/EffectControllerKt*",
)
}
)
}

tasks.jacocoTestReport {
reports {
xml.isEnabled = true
html.isEnabled = true
csv.isEnabled = false
xml.required.set(true)
html.required.set(true)
csv.required.set(false)
}
classDirectories.setFrom(
files(classDirectories.files.map { file ->
fileTree(file) {
// jacoco cannot handle inline functions properly
exclude(
"at/florianschuster/control/DefaultTagKt.class",
"at/florianschuster/control/ExtensionsKt.class"
)
}
})
)
}

// ---- end jacoco --- //
Expand All @@ -57,8 +51,13 @@ pitest {
targetClasses.add("at.florianschuster.control.*")
mutationThreshold.set(100)
excludedClasses.addAll(
"at.florianschuster.control.DefaultTagKt**", // inline function
"at.florianschuster.control.ExtensionsKt**", // too many inline collects
// inline function
"at.florianschuster.control.DefaultTagKt**",
"at.florianschuster.control.TakeUntilKt**",

// builder
"at.florianschuster.control.Controller**",
"at.florianschuster.control.EffectController**",

// inlined invokeSuspend
"at.florianschuster.control.ControllerImplementation\$stateJob\$1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package at.florianschuster.control
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
Expand Down Expand Up @@ -42,15 +41,6 @@ interface Controller<Action, State> {
*/
fun dispatch(action: Action)

/**
* The current [State].
*/
@Deprecated(
message = "Use state.value instead.",
replaceWith = ReplaceWith("state.value")
)
val currentState: State

/**
* The [State]. Use this to collect [State] changes
* or get the current [State] via [StateFlow.value].
Expand Down Expand Up @@ -100,7 +90,6 @@ interface Controller<Action, State> {
* 3. [Transformer]
* 4. [ControllerImplementation]
*/
@ExperimentalCoroutinesApi
@FlowPreview
fun <Action, Mutation, State> CoroutineScope.createController(

Expand Down Expand Up @@ -188,7 +177,7 @@ fun <Action, Mutation, State> CoroutineScope.createController(
typealias Mutator<Action, Mutation, State> = MutatorContext<Action, State>.(action: Action) -> Flow<Mutation>

/**
* The [MutatorContext] provides access to the [currentState] and the [actions] [Flow] in
* The [MutatorContext] provides access to the current [State] and the [actions] [Flow] in
* a [Mutator].
*/
interface MutatorContext<Action, State> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package at.florianschuster.control
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
Expand Down Expand Up @@ -37,7 +36,6 @@ interface EffectController<Action, State, Effect> : Controller<Action, State> {
* An [Effect] can be emitted either in [mutator], [reducer], [actionsTransformer],
* [mutationsTransformer] or [statesTransformer].
*/
@ExperimentalCoroutinesApi
@FlowPreview
fun <Action, Mutation, State, Effect> CoroutineScope.createEffectController(

Expand Down Expand Up @@ -99,7 +97,7 @@ fun <Action, Mutation, State, Effect> CoroutineScope.createEffectController(
* This is implemented by the respective context's of [EffectMutator], [EffectReducer]
* and [EffectTransformer].
*/
interface EffectEmitter<Effect> {
fun interface EffectEmitter<Effect> {

/**
* Emits an [Effect].
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import kotlin.coroutines.ContinuationInterceptor
*/
internal fun CoroutineScope.defaultScopeDispatcher(): CoroutineDispatcher {
val continuationInterceptor = coroutineContext[ContinuationInterceptor]
checkNotNull(continuationInterceptor) {
requireNotNull(continuationInterceptor) {
"CoroutineScope does not have a ContinuationInterceptor"
}
return continuationInterceptor as CoroutineDispatcher
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel
Expand All @@ -28,7 +27,6 @@ import kotlinx.coroutines.launch
/**
* An implementation of [Controller].
*/
@ExperimentalCoroutinesApi
@FlowPreview
internal class ControllerImplementation<Action, Mutation, State, Effect>(
val scope: CoroutineScope,
Expand Down Expand Up @@ -61,9 +59,8 @@ internal class ControllerImplementation<Action, Mutation, State, Effect>(
) {
val transformerContext = createTransformerContext(effectEmitter)

val actionFlow: Flow<Action> = transformerContext.actionsTransformer(
actionSharedFlow.asSharedFlow()
)
val actionFlow: Flow<Action> = transformerContext
.actionsTransformer(actionSharedFlow.asSharedFlow())

val mutatorContext = createMutatorContext(
stateAccessor = { state.value },
Expand Down Expand Up @@ -116,15 +113,6 @@ internal class ControllerImplementation<Action, Mutation, State, Effect>(
mutableStateFlow.asStateFlow()
}

@Suppress("OverridingDeprecatedMember")
override val currentState: State
get() = if (stubEnabled) {
stubbedStateFlow.value
} else {
if (controllerStart is ControllerStart.Lazy) start()
mutableStateFlow.value
}

override fun dispatch(action: Action) {
if (stubEnabled) {
stubbedActions.add(action)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package at.florianschuster.control

import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import org.jetbrains.annotations.TestOnly

Expand Down Expand Up @@ -28,7 +27,6 @@ interface ControllerStub<Action, State> : Controller<Action, State> {
*
* Custom implementations of [Controller] cannot be stubbed.
*/
@ExperimentalCoroutinesApi
@FlowPreview
@TestOnly
fun <Action, State> Controller<Action, State>.toStub(): ControllerStub<Action, State> {
Expand Down Expand Up @@ -60,7 +58,6 @@ interface EffectControllerStub<Action, State, Effect> : ControllerStub<Action, S
*
* Custom implementations of [EffectController] cannot be stubbed.
*/
@ExperimentalCoroutinesApi
@FlowPreview
@TestOnly
fun <Action, State, Effect> EffectController<Action, State, Effect>.toStub(): EffectControllerStub<Action, State, Effect> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,11 @@
package at.florianschuster.control

import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch

/**
* Binds a [Flow] to an non suspending block.
*/
fun <T> Flow<T>.bind(
to: (T) -> Unit
): Flow<T> = onEach { to(it) }

/**
* Maps emissions of a [Flow] and only emits those that are distinct from their immediate
* predecessors.
*/
@ExperimentalCoroutinesApi
fun <State, SubState> Flow<State>.distinctMap(
by: (State) -> SubState
): Flow<SubState> = map { by(it) }.distinctUntilChanged()

/**
* Discard any emissions by a [Flow] of [T] if emission matches [predicate].
* If [inclusive] is true, the last emission matching the [predicate] will be emitted.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ package at.florianschuster.control
import io.mockk.mockk
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.cancelChildren
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.single
import kotlinx.coroutines.flow.singleOrNull
import kotlinx.coroutines.test.runBlockingTest
import kotlinx.coroutines.test.runTest
import org.junit.Test
import kotlin.test.assertEquals

Expand All @@ -16,7 +17,7 @@ import kotlin.test.assertEquals
internal class CreateControllerTest {

@Test
fun `default parameters of controller builder`() = runBlockingTest {
fun `controller builder`() = runTest {
val expectedInitialState = 42
val sut = createController<Int, Int, Int>(
initialState = expectedInitialState
Expand All @@ -37,10 +38,12 @@ internal class CreateControllerTest {

assertEquals(ControllerStart.Lazy, sut.controllerStart)
assertEquals(defaultScopeDispatcher(), sut.dispatcher)

coroutineContext.cancelChildren()
}

@Test
fun `default parameters of effect controller builder`() = runBlockingTest {
fun `effect controller builder`() = runTest {
val expectedInitialState = 42
val sut = createEffectController<Int, Int, Int, Int>(
initialState = expectedInitialState
Expand All @@ -61,5 +64,7 @@ internal class CreateControllerTest {

assertEquals(ControllerStart.Lazy, sut.controllerStart)
assertEquals(defaultScopeDispatcher(), sut.dispatcher)

coroutineContext.cancelChildren()
}
}
Loading

0 comments on commit 6bd9d72

Please sign in to comment.