From 247654ab090c5e44169b671069e40fb6bfa33537 Mon Sep 17 00:00:00 2001 From: Lachlan McKee Date: Mon, 18 Nov 2024 20:21:45 +0000 Subject: [PATCH 1/2] Fixed BackStack store causing Mockito failures on Java 17 --- .../routing/source/backstack/BackStack.kt | 18 ++- .../root/RootInteractorAuthStateTest.kt | 112 +++++++++------- .../rib/switcher/SwitcherInteractorTest.kt | 126 ++++++++++-------- 3 files changed, 152 insertions(+), 104 deletions(-) diff --git a/libraries/rib-base/src/main/java/com/badoo/ribs/routing/source/backstack/BackStack.kt b/libraries/rib-base/src/main/java/com/badoo/ribs/routing/source/backstack/BackStack.kt index b1abf03f3..24ab83a52 100644 --- a/libraries/rib-base/src/main/java/com/badoo/ribs/routing/source/backstack/BackStack.kt +++ b/libraries/rib-base/src/main/java/com/badoo/ribs/routing/source/backstack/BackStack.kt @@ -5,9 +5,9 @@ import android.os.Parcelable import com.badoo.ribs.core.modality.BuildParams import com.badoo.ribs.minimal.reactive.Cancellable import com.badoo.ribs.minimal.reactive.Source +import com.badoo.ribs.minimal.reactive.map import com.badoo.ribs.minimal.state.Store import com.badoo.ribs.minimal.state.TimeCapsule -import com.badoo.ribs.minimal.reactive.map import com.badoo.ribs.routing.Routing import com.badoo.ribs.routing.history.RoutingHistory import com.badoo.ribs.routing.history.RoutingHistoryElement @@ -72,7 +72,9 @@ class BackStack internal constructor( override fun baseLineState(fromRestored: Boolean): RoutingHistory = timeCapsule.initialState() - private val store = object : Store>(timeCapsule.initialState()) { + private val store = BackStackStore() + + private inner class BackStackStore : Store>(timeCapsule.initialState()) { init { timeCapsule.register(timeCapsuleKey) { state } initializeBackstack() @@ -114,7 +116,10 @@ class BackStack internal constructor( ) } - private fun routingWithCorrectId(element: RoutingHistoryElement, index: Int): Routing = + private fun routingWithCorrectId( + element: RoutingHistoryElement, + index: Int + ): Routing = element.routing.copy( identifier = state.contentIdForPosition( index, @@ -122,7 +127,10 @@ class BackStack internal constructor( ) ) - private fun overlaysWithCorrectId(element: RoutingHistoryElement, index: Int): List> = + private fun overlaysWithCorrectId( + element: RoutingHistoryElement, + index: Int + ): List> = element.overlays.mapIndexed { overlayIndex, overlay -> overlay.copy( identifier = state.overlayIdForPosition( @@ -144,7 +152,7 @@ class BackStack internal constructor( } val activeConfiguration: C - get()= state.elements + get() = state.elements .last() .routing .configuration diff --git a/samples/app/unsplash-client/src/test/java/com/badoo/ribs/example/root/RootInteractorAuthStateTest.kt b/samples/app/unsplash-client/src/test/java/com/badoo/ribs/example/root/RootInteractorAuthStateTest.kt index 74a379029..e98f3bd81 100644 --- a/samples/app/unsplash-client/src/test/java/com/badoo/ribs/example/root/RootInteractorAuthStateTest.kt +++ b/samples/app/unsplash-client/src/test/java/com/badoo/ribs/example/root/RootInteractorAuthStateTest.kt @@ -1,49 +1,67 @@ package com.badoo.ribs.example.root -// TODO: Uncomment once Mockito issues with BackStack are fixed. -// This blocked the update to AGP 8.2.2 -//@ExtendWith(RxSchedulerExtension::class) -//class RootInteractorAuthStateTest { -// -// private val backStack: BackStack = mock() -// -// private val stateRelay = PublishRelay.create() -// private val authDataSource = mock().apply { -// whenever(authUpdates).thenReturn(stateRelay) -// } -// private lateinit var interactor: RootInteractor -// private lateinit var interactorTestHelper: InteractorTestHelper -// -// @BeforeEach -// fun setup() { -// interactor = RootInteractor( -// buildParams = emptyBuildParams(), -// backStack = backStack, -// authDataSource = authDataSource, -// networkErrors = PublishRelay.create() -// ) -// interactorTestHelper = InteractorTestHelper(interactor) -// } -// -// @ParameterizedTest -// @MethodSource("data") -// fun `an example test with some conditions should pass`( -// authState: AuthState, -// expectedConfiguration: Configuration -// ) { -// interactorTestHelper.moveToStateAndCheck(Lifecycle.State.CREATED) { -// stateRelay.accept(authState) -// -// verify(backStack).replace(expectedConfiguration) -// } -// } -// -// companion object { -// @JvmStatic -// fun data(): Stream = Stream.of( -// Arguments.of(AuthState.Unauthenticated, Configuration.Content.LoggedOut), -// Arguments.of(AuthState.Anonymous, Configuration.Content.LoggedIn), -// Arguments.of(AuthState.Authenticated(""), Configuration.Content.LoggedIn) -// ) -// } -//} +import androidx.lifecycle.Lifecycle +import com.badoo.ribs.example.RxSchedulerExtension +import com.badoo.ribs.example.auth.AuthDataSource +import com.badoo.ribs.example.auth.AuthState +import com.badoo.ribs.example.root.routing.RootRouter.Configuration +import com.badoo.ribs.routing.source.backstack.BackStack +import com.badoo.ribs.routing.source.backstack.operation.replace +import com.badoo.ribs.test.InteractorTestHelper +import com.badoo.ribs.test.emptyBuildParams +import com.jakewharton.rxrelay2.PublishRelay +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.extension.ExtendWith +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever +import java.util.stream.Stream + +@ExtendWith(RxSchedulerExtension::class) +class RootInteractorAuthStateTest { + + private val backStack: BackStack = mock() + + private val stateRelay = PublishRelay.create() + private val authDataSource = mock().apply { + whenever(authUpdates).thenReturn(stateRelay) + } + private lateinit var interactor: RootInteractor + private lateinit var interactorTestHelper: InteractorTestHelper + + @BeforeEach + fun setup() { + interactor = RootInteractor( + buildParams = emptyBuildParams(), + backStack = backStack, + authDataSource = authDataSource, + networkErrors = PublishRelay.create() + ) + interactorTestHelper = InteractorTestHelper(interactor) + } + + @ParameterizedTest + @MethodSource("data") + fun `an example test with some conditions should pass`( + authState: AuthState, + expectedConfiguration: Configuration + ) { + interactorTestHelper.moveToStateAndCheck(Lifecycle.State.CREATED) { + stateRelay.accept(authState) + + verify(backStack).replace(expectedConfiguration) + } + } + + companion object { + @JvmStatic + fun data(): Stream = Stream.of( + Arguments.of(AuthState.Unauthenticated, Configuration.Content.LoggedOut), + Arguments.of(AuthState.Anonymous, Configuration.Content.LoggedIn), + Arguments.of(AuthState.Authenticated(""), Configuration.Content.LoggedIn) + ) + } +} diff --git a/sandbox/src/test/java/com/badoo/ribs/sandbox/rib/switcher/SwitcherInteractorTest.kt b/sandbox/src/test/java/com/badoo/ribs/sandbox/rib/switcher/SwitcherInteractorTest.kt index c084dcade..c13cf824f 100644 --- a/sandbox/src/test/java/com/badoo/ribs/sandbox/rib/switcher/SwitcherInteractorTest.kt +++ b/sandbox/src/test/java/com/badoo/ribs/sandbox/rib/switcher/SwitcherInteractorTest.kt @@ -1,54 +1,76 @@ package com.badoo.ribs.sandbox.rib.switcher -// TODO: Uncomment once Mockito issues with BackStack are fixed. -// This blocked the update to AGP 8.2.2 -//@RunWith(RobolectricTestRunner::class) -//class SwitcherInteractorTest { -// -// private val backStack: BackStack = mock() -// private val dialogToTestOverlay: DialogToTestOverlay = mock() -// -// private val viewEventRelay = PublishRelay.create() -// private lateinit var interactor: SwitcherInteractor -// private lateinit var interactorTestHelper: InteractorTestHelper -// -// @Before -// fun setup() { -// interactor = SwitcherInteractor( -// buildParams = emptyBuildParams(), -// backStack = backStack, -// dialogToTestOverlay = dialogToTestOverlay, -// transitions = Observable.just(SETTLED), -// transitionSettled = { true } -// ) -// -// interactorTestHelper = createInteractorTestHelper(interactor, viewEventRelay) -// } -// -// @Test -// fun `router open overlay dialog when show overlay dialog clicked`(){ -// interactorTestHelper.moveToStateAndCheck(STARTED) { -// viewEventRelay.accept(Event.ShowOverlayDialogClicked) -// -// verify(backStack).pushOverlay(Overlay.Dialog) -// } -// } -// -// @Test -// fun `router open blocker when show blocker clicked`(){ -// interactorTestHelper.moveToStateAndCheck(STARTED) { -// viewEventRelay.accept(Event.ShowBlockerClicked) -// -// verify(backStack).push(Content.Blocker) -// } -// } -// -// @Test -// fun `skip view event when view not resumed`(){ -// interactorTestHelper.moveToStateAndCheck(CREATED) { -// viewEventRelay.accept(Event.ShowBlockerClicked) -// -// verify(backStack, never()).push(Content.Blocker) -// } -// } -//} +import androidx.lifecycle.Lifecycle.State.CREATED +import androidx.lifecycle.Lifecycle.State.STARTED +import com.badoo.common.ribs.rx2.createInteractorTestHelper +import com.badoo.ribs.routing.router.Router.TransitionState.SETTLED +import com.badoo.ribs.routing.source.backstack.BackStack +import com.badoo.ribs.routing.source.backstack.operation.push +import com.badoo.ribs.routing.source.backstack.operation.pushOverlay +import com.badoo.ribs.sandbox.rib.switcher.SwitcherView.Event +import com.badoo.ribs.sandbox.rib.switcher.dialog.DialogToTestOverlay +import com.badoo.ribs.sandbox.rib.switcher.routing.SwitcherRouter.Configuration +import com.badoo.ribs.sandbox.rib.switcher.routing.SwitcherRouter.Configuration.Content +import com.badoo.ribs.sandbox.rib.switcher.routing.SwitcherRouter.Configuration.Overlay +import com.badoo.ribs.test.InteractorTestHelper +import com.badoo.ribs.test.emptyBuildParams +import com.jakewharton.rxrelay2.PublishRelay +import io.reactivex.Observable +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +class SwitcherInteractorTest { + + private val backStack: BackStack = mock() + private val dialogToTestOverlay: DialogToTestOverlay = mock() + + private val viewEventRelay = PublishRelay.create() + private lateinit var interactor: SwitcherInteractor + private lateinit var interactorTestHelper: InteractorTestHelper + + @Before + fun setup() { + interactor = SwitcherInteractor( + buildParams = emptyBuildParams(), + backStack = backStack, + dialogToTestOverlay = dialogToTestOverlay, + transitions = Observable.just(SETTLED), + transitionSettled = { true } + ) + + interactorTestHelper = createInteractorTestHelper(interactor, viewEventRelay) + } + + @Test + fun `router open overlay dialog when show overlay dialog clicked`() { + interactorTestHelper.moveToStateAndCheck(STARTED) { + viewEventRelay.accept(Event.ShowOverlayDialogClicked) + + verify(backStack).pushOverlay(Overlay.Dialog) + } + } + + @Test + fun `router open blocker when show blocker clicked`() { + interactorTestHelper.moveToStateAndCheck(STARTED) { + viewEventRelay.accept(Event.ShowBlockerClicked) + + verify(backStack).push(Content.Blocker) + } + } + + @Test + fun `skip view event when view not resumed`() { + interactorTestHelper.moveToStateAndCheck(CREATED) { + viewEventRelay.accept(Event.ShowBlockerClicked) + + verify(backStack, never()).push(Content.Blocker) + } + } +} From 2367fc1d0b235d19350011ae63ea421904d10af3 Mon Sep 17 00:00:00 2001 From: Lachlan McKee Date: Mon, 18 Nov 2024 20:22:17 +0000 Subject: [PATCH 2/2] Release 0.40.4 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 38bedbee7..5789b1c2c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,7 +14,7 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 org.gradle.caching=true org.gradle.parallel=true -VERSION_NAME=0.40.3 +VERSION_NAME=0.40.4 android.useAndroidX=true android.defaults.buildfeatures.buildconfig=true