All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.copperleaf.ballast.test.internal.vm.TestInterceptorWrapper.kt Maven / Gradle / Ivy

There is a newer version: 4.2.1
Show newest version
package com.copperleaf.ballast.test.internal.vm

import com.copperleaf.ballast.BallastInterceptor
import com.copperleaf.ballast.BallastLogger
import com.copperleaf.ballast.BallastNotification
import com.copperleaf.ballast.BallastViewModel

/**
 * This class wraps a standard Interceptor to pull Inputs out of the TestViewModel wrapped INput type, and convert it
 * back to the intended Input that the test is running against.
 */
internal class TestInterceptorWrapper(
    private val delegate: BallastInterceptor,
) : BallastInterceptor, Events, State> {

    private var startedViewModel: BallastViewModel, Events, State>? = null
    private var startedViewModelWrapped: BallastViewModel? = null

    private suspend inline fun TestViewModel.Inputs.unwrap(
        logger: BallastLogger,
        block: (Inputs) -> BallastNotification
    ) {
        when (this) {
            is TestViewModel.Inputs.AwaitInput -> {
                block(this.normalInput).let { delegate.onNotify(logger, it) }
            }
            is TestViewModel.Inputs.ProcessInput -> {
                block(this.normalInput).let { delegate.onNotify(logger, it) }
            }
            is TestViewModel.Inputs.TestCompleted -> {
            }
        }
    }

    @Suppress("UNCHECKED_CAST")
    override suspend fun onNotify(
        logger: BallastLogger,
        notification: BallastNotification, Events, State>
    ) {
        when (notification) {
            is BallastNotification.ViewModelStarted -> {
                startedViewModel = notification.vm
                startedViewModelWrapped = ViewModelWrapper(startedViewModel!!)
                delegate.onNotify(logger, BallastNotification.ViewModelStarted(startedViewModelWrapped!!))
            }
            is BallastNotification.ViewModelCleared -> {
                check(notification.vm === startedViewModel)
                delegate.onNotify(logger, BallastNotification.ViewModelCleared(startedViewModelWrapped!!))
                startedViewModel = null
                startedViewModelWrapped = null
            }

            is BallastNotification.InputAccepted -> {
                notification.input.unwrap(logger) {
                    BallastNotification.InputAccepted(startedViewModelWrapped!!, it)
                }
            }
            is BallastNotification.InputRejected -> {
                notification.input.unwrap(logger) {
                    BallastNotification.InputRejected(startedViewModelWrapped!!, notification.stateWhenRejected, it)
                }
            }
            is BallastNotification.InputDropped -> {
                notification.input.unwrap(logger) {
                    BallastNotification.InputDropped(startedViewModelWrapped!!, it)
                }
            }
            is BallastNotification.InputHandledSuccessfully -> {
                notification.input.unwrap(logger) {
                    BallastNotification.InputHandledSuccessfully(startedViewModelWrapped!!, it)
                }
            }
            is BallastNotification.InputCancelled -> {
                notification.input.unwrap(logger) {
                    BallastNotification.InputCancelled(startedViewModelWrapped!!, it)
                }
            }
            is BallastNotification.InputHandlerError -> {
                notification.input.unwrap(logger) {
                    BallastNotification.InputHandlerError(startedViewModelWrapped!!, it, notification.throwable)
                }
            }

            else -> {
                // should be safe to cast, since none of the properties of the remaining Notifications include an
                //    Input parameter, which is the only type that has changed from this to the delegate
                delegate.onNotify(logger, notification as BallastNotification)
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy