I have a question regarding custom `rememberSaveab...
# compose
o
I have a question regarding custom
rememberSaveable
and testing 🧵
Copy code
@Stable
class CastState(
    scope: CoroutineScope,
    initialCastState: CastPlayerState,
    initialCastStateEvent: CastStateEvent? = null
) {

    var isReconnect = false
    val castState = MutableStateFlow(initialCastState)
    val castStateEvent = MutableStateFlow(initialCastStateEvent)

    init {
        castStateEvent.filterNotNull().onEach { castStateEvent ->
            isReconnect = initialCastStateEvent == null && castStateEvent == CastStateConnected
            val state = when (castStateEvent) {
                CastStateConnecting -> CastPlayerState.Connecting
                CastStateConnected -> CastPlayerState.Connected
                CastStateNotConnected -> CastPlayerState.NotConnected
                CastStateNoDevicesAvailable -> CastPlayerState.NoDevicesAvailable
            }
            castState.update { state }
        }
            // .launchIn(scope)
    }

    fun updateCastStateEvent(event: CastStateEvent) {
        castStateEvent.update { event }
    }
}

@Parcelize
sealed class CastPlayerState : Parcelable {
    object NoDevicesAvailable : CastPlayerState()
    object NotConnected : CastPlayerState()
    object Connecting : CastPlayerState()
    object Connected : CastPlayerState()
}

fun CastPlayerState.isConnectedOrConnecting() = this is CastPlayerState.Connected || this is CastPlayerState.Connecting

@Composable
fun rememberCastState(
    scope: CoroutineScope,
    initialCastState: CastPlayerState = CastPlayerState.NoDevicesAvailable,
    initialCastStateEvent: CastStateEvent? = null
): CastState {
    return rememberSaveable(
        scope,
        initialCastState,
        initialCastStateEvent,
        saver = Saver(
            save = {
                println("Debug: saving last cast state ${it.castState.value}")
                it.castState.value
            },
            restore = {
                println("Debug: restore last cast state ${it}")
                CastState(
                    scope,
                    it,
                    initialCastStateEvent
                )
            }
        )
    ) {
        CastState(scope, initialCastState, initialCastStateEvent)
    }
}
Copy code
@RunWith(AndroidJUnit4::class)
class CastStateTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    private val testDispatcher = StandardTestDispatcher()
    private val testScope = TestScope(testDispatcher)

    private lateinit var scenario: ActivityScenario<ComponentActivity>

    @Before
    fun setup() {
        scenario = ActivityScenario.launch(ComponentActivity::class.java)
    }

    @Test
    fun onRecreation_stateIsRestored() {
        val restorationTester = StateRestorationTester(composeTestRule)

        val initialCastState = CastPlayerState.NoDevicesAvailable
        val initialCastStateEvent = null

        var castState: CastState? = null
        restorationTester.setContent {
            castState = rememberCastState(testScope, initialCastState, initialCastStateEvent)
            castState?.updateCastStateEvent(CastStateConnecting)
        }

        restorationTester.emulateSavedInstanceStateRestore()

        println(castState?.castState?.value)
    }
}
I see that my
castState
is not updated as requested once the
castStateEvent
is updated. i only see the initial value being returned. can someone guide me with this?