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

commonTest.com.zegreatrob.testmints.action.async.SuspendActionTest.kt Maven / Gradle / Ivy

There is a newer version: 12.1.17
Show newest version
package com.zegreatrob.testmints.action.async

import com.zegreatrob.minassert.assertIsEqualTo
import com.zegreatrob.minspy.SpyData
import com.zegreatrob.minspy.spyFunction
import com.zegreatrob.testmints.action.Action
import com.zegreatrob.testmints.action.ExecutableActionExecuteSyntax
import com.zegreatrob.testmints.action.SimpleExecutableAction
import com.zegreatrob.testmints.async.asyncSetup
import kotlinx.coroutines.coroutineScope
import kotlin.test.Test

class SuspendActionTest : SuspendActionExecuteSyntax {

    data class MultiplyAction(val left: Int, val right: Int) : SimpleSuspendAction {
        override val performFunc = link(MultiplyActionDispatcher::invoke)
    }

    interface MultiplyActionDispatcher {
        suspend fun invoke(action: MultiplyAction) = coroutineScope {
            (1..action.left)
                .fold(0) { current, _ -> current + action.right }
        }
    }

    @Test
    fun usingTheActionWithTheDispatcherDoesTheWorkOfTheDispatchFunction() = asyncSetup(object {
        val action = MultiplyAction(2, 3)
        val dispatcher = object : MultiplyActionDispatcher {}
    }) exercise {
        dispatcher.execute(action)
    } verify { result ->
        result.assertIsEqualTo(6)
    }

    @Test
    fun executingActionMerelyPassesActionToDispatcherWhereWorkCanBeDone() = asyncSetup(object {
        val action = MultiplyAction(2, 3)
        val expectedReturn = 42
        val spy = SpyData().apply { spyWillReturn(expectedReturn) }
        val spyDispatcher = object : MultiplyActionDispatcher {
            override suspend fun invoke(action: MultiplyAction) = spy.spyFunction(action)
        }
    }) exercise {
        spyDispatcher.execute(action)
    } verify { result ->
        result.assertIsEqualTo(expectedReturn)
        spy.spyReceivedValues.assertIsEqualTo(listOf(action))
    }

    class Dispatcher : SuspendActionExecuteSyntax, ExecutableActionExecuteSyntax {

        data class AddAction(val left: Int, val right: Int) : SimpleSuspendAction {
            override val performFunc = link(AddActionDispatcher::invoke)
        }

        interface AddActionDispatcher {
            suspend operator fun invoke(addAction: AddAction) = with(addAction) { left + right }
        }

        @Test
        fun singleDispatcherObjectCanExecuteManyActions() = asyncSetup(object {
            val dispatcher = object : AddActionDispatcher, MultiplyActionDispatcher {}
            val addAction = AddAction(7, 22)
            val multiplyAction = MultiplyAction(13, 41)
        }) exercise {
            Pair(
                dispatcher.execute(addAction),
                dispatcher.execute(multiplyAction)
            )
        } verify { result ->
            with(result) {
                first.assertIsEqualTo(29)
                second.assertIsEqualTo(533)
            }
        }

        data class SubtractAction(val left: Int, val right: Int) :
            SimpleExecutableAction {
            override val performFunc = link(SubtractActionDispatcher::invoke)
        }

        interface SubtractActionDispatcher {
            operator fun invoke(SubtractAction: SubtractAction) = with(SubtractAction) { left - right }
        }

        @Test
        fun singleDispatcherObjectCanWorkWithBothExecuteAndSuspendActions() = asyncSetup(object {
            val dispatcher = object : AddActionDispatcher, SubtractActionDispatcher {}
            val addAction = AddAction(7, 22)
            val subtractAction = SubtractAction(41, 13)
        }) exercise {
            Pair(
                dispatcher.execute(addAction),
                dispatcher.execute(subtractAction)
            )
        } verify { result ->
            result.assertIsEqualTo(
                29 to 28
            )
        }

        @Test
        fun usingSuspendActionSyntaxAllowsInterceptionOfAnyAction() = asyncSetup(object : SuspendActionExecuteSyntax {
            val dispatcher = object : AddActionDispatcher, MultiplyActionDispatcher {}
            val addAction = AddAction(7, 22)
            val multiplyAction = MultiplyAction(13, 41)

            val allExecutedActions = mutableListOf()
            override suspend fun  D.execute(action: SuspendAction) = action.execute(this)
                .also { allExecutedActions.add(action) }
        }) exercise {
            Pair(
                dispatcher.execute(addAction),
                dispatcher.execute(multiplyAction)
            )
        } verify {
            allExecutedActions.assertIsEqualTo(
                listOf(addAction, multiplyAction)
            )
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy