From 9b0229ed85cbb59c6ad7c965f6365bf659ca5af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Salcedo=20Garc=C3=ADa?= Date: Sun, 10 Mar 2024 23:40:01 +0100 Subject: [PATCH] fix: tests --- .../data/datastore/SessionDataStoreTest.kt | 6 +++--- .../usecases/ClearActiveSessionUseCaseTest.kt | 17 +++++++++++++-- .../usecases/DeleteAnilistTokenUseCaseTest.kt | 17 +++++++++++++-- .../usecases/GetAnilistTokenUseCaseTest.kt | 17 +++++++++++++-- .../domain/usecases/LogOutUseCaseTest.kt | 17 +++++++++++++-- .../ObserveActiveSessionUseCaseTest.kt | 17 +++++++++++++-- .../usecases/SaveAnilistTokenUseCaseTest.kt | 17 +++++++++++++-- .../user/data/managers/UserIdManagerTest.kt | 12 +++++++++-- .../user/domain/usecases/GetUserIdUseCase.kt | 2 +- .../domain/usecases/GetUserIdUseCaseTest.kt | 17 +++++++++++++-- .../usecases/ObserveUserInfoUseCaseTest.kt | 17 +++++++++++++-- .../domain/usecases/SaveUserIdUseCaseTest.kt | 17 +++++++++++++-- .../common/coroutines/AppKatanaDispatcher.kt | 10 +++++++++ .../common/coroutines/KatanaDispatcher.kt | 15 +++++-------- .../dev/alvr/katana/core/common/di/module.kt | 9 +++++++- core/tests/build.gradle.kts | 2 ++ .../alvr/katana/core/tests/KoinExtension.kt | 21 +++++++++---------- .../tests/coroutines/TestKatanaDispatcher.kt | 13 ++++++++++++ .../dev/alvr/katana/core/tests/di/module.kt | 15 +++++++++++++ .../usecases/ObserveAnimeListUseCaseTest.kt | 17 +++++++++++++-- .../usecases/ObserveMangaListUseCaseTest.kt | 17 +++++++++++++-- .../domain/usecases/UpdateListUseCaseTest.kt | 17 +++++++++++++-- gradle/libs.versions.toml | 2 +- 23 files changed, 258 insertions(+), 53 deletions(-) create mode 100644 core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/coroutines/AppKatanaDispatcher.kt create mode 100644 core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/coroutines/TestKatanaDispatcher.kt create mode 100644 core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/di/module.kt diff --git a/common/session/data/src/commonTest/kotlin/dev/alvr/katana/common/session/data/datastore/SessionDataStoreTest.kt b/common/session/data/src/commonTest/kotlin/dev/alvr/katana/common/session/data/datastore/SessionDataStoreTest.kt index 76ebbcbd7..8f275f115 100644 --- a/common/session/data/src/commonTest/kotlin/dev/alvr/katana/common/session/data/datastore/SessionDataStoreTest.kt +++ b/common/session/data/src/commonTest/kotlin/dev/alvr/katana/common/session/data/datastore/SessionDataStoreTest.kt @@ -8,7 +8,7 @@ import dev.alvr.katana.common.session.data.di.deleteDataStoreFiles import dev.alvr.katana.common.session.data.di.testDataStoreModule import dev.alvr.katana.common.session.data.models.Session import dev.alvr.katana.common.session.domain.models.AnilistToken -import dev.alvr.katana.core.tests.KoinExtension +import dev.alvr.katana.core.tests.koinExtension import io.kotest.core.spec.style.FreeSpec import io.kotest.core.test.TestCase import io.kotest.matchers.equals.shouldBeEqual @@ -55,9 +55,9 @@ internal class SessionDataStoreTest : FreeSpec(), KoinTest { } } - override fun extensions() = listOf(KoinExtension(testDataStoreModule())) - override suspend fun beforeEach(testCase: TestCase) { deleteDataStoreFiles() } + + override fun extensions() = listOf(koinExtension(testDataStoreModule())) } diff --git a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/ClearActiveSessionUseCaseTest.kt b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/ClearActiveSessionUseCaseTest.kt index 99bd8c226..7101fd828 100644 --- a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/ClearActiveSessionUseCaseTest.kt +++ b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/ClearActiveSessionUseCaseTest.kt @@ -4,8 +4,11 @@ import arrow.core.left import arrow.core.right import dev.alvr.katana.common.session.domain.failures.SessionFailure import dev.alvr.katana.common.session.domain.repositories.SessionRepository +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.failures.Failure import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.mokkery.answering.returns @@ -13,11 +16,15 @@ import dev.mokkery.everySuspend import dev.mokkery.mock import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase +import org.koin.test.KoinTest +import org.koin.test.inject -internal class ClearActiveSessionUseCaseTest : FreeSpec() { +internal class ClearActiveSessionUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = ClearActiveSessionUseCase(repo) + private lateinit var useCase: ClearActiveSessionUseCase init { "successfully clearing the session" { @@ -37,4 +44,10 @@ internal class ClearActiveSessionUseCaseTest : FreeSpec() { } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = ClearActiveSessionUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/DeleteAnilistTokenUseCaseTest.kt b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/DeleteAnilistTokenUseCaseTest.kt index b49da20ae..c9a798f77 100644 --- a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/DeleteAnilistTokenUseCaseTest.kt +++ b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/DeleteAnilistTokenUseCaseTest.kt @@ -4,8 +4,11 @@ import arrow.core.left import arrow.core.right import dev.alvr.katana.common.session.domain.failures.SessionFailure import dev.alvr.katana.common.session.domain.repositories.SessionRepository +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.failures.Failure import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.mokkery.answering.returns @@ -13,11 +16,15 @@ import dev.mokkery.everySuspend import dev.mokkery.mock import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase +import org.koin.test.KoinTest +import org.koin.test.inject -internal class DeleteAnilistTokenUseCaseTest : FreeSpec() { +internal class DeleteAnilistTokenUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = DeleteAnilistTokenUseCase(repo) + private lateinit var useCase: DeleteAnilistTokenUseCase init { "successfully deleting the token" { @@ -37,4 +44,10 @@ internal class DeleteAnilistTokenUseCaseTest : FreeSpec() { } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = DeleteAnilistTokenUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/GetAnilistTokenUseCaseTest.kt b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/GetAnilistTokenUseCaseTest.kt index 9e9e00c5a..39b8317ea 100644 --- a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/GetAnilistTokenUseCaseTest.kt +++ b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/GetAnilistTokenUseCaseTest.kt @@ -4,7 +4,10 @@ import arrow.core.none import arrow.core.some import dev.alvr.katana.common.session.domain.anilistTokenMock import dev.alvr.katana.common.session.domain.repositories.SessionRepository +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeNone import dev.alvr.katana.core.tests.shouldBeSome import dev.mokkery.answering.returns @@ -12,11 +15,15 @@ import dev.mokkery.everySuspend import dev.mokkery.mock import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase +import org.koin.test.KoinTest +import org.koin.test.inject -internal class GetAnilistTokenUseCaseTest : FreeSpec() { +internal class GetAnilistTokenUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = GetAnilistTokenUseCase(repo) + private lateinit var useCase: GetAnilistTokenUseCase init { "successfully getting the token" { @@ -31,4 +38,10 @@ internal class GetAnilistTokenUseCaseTest : FreeSpec() { verifySuspend { repo.getAnilistToken() } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = GetAnilistTokenUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/LogOutUseCaseTest.kt b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/LogOutUseCaseTest.kt index 1a9ce78e3..477cb53f6 100644 --- a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/LogOutUseCaseTest.kt +++ b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/LogOutUseCaseTest.kt @@ -4,8 +4,11 @@ import arrow.core.left import arrow.core.right import dev.alvr.katana.common.session.domain.failures.SessionFailure import dev.alvr.katana.common.session.domain.repositories.SessionRepository +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.failures.Failure import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.mokkery.answering.returns @@ -13,11 +16,15 @@ import dev.mokkery.everySuspend import dev.mokkery.mock import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase +import org.koin.test.KoinTest +import org.koin.test.inject -internal class LogOutUseCaseTest : FreeSpec() { +internal class LogOutUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = LogOutUseCase(repo) + private lateinit var useCase: LogOutUseCase init { "successfully saving the session" { @@ -37,4 +44,10 @@ internal class LogOutUseCaseTest : FreeSpec() { } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = LogOutUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/ObserveActiveSessionUseCaseTest.kt b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/ObserveActiveSessionUseCaseTest.kt index 743af76e5..4ba6832d3 100644 --- a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/ObserveActiveSessionUseCaseTest.kt +++ b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/ObserveActiveSessionUseCaseTest.kt @@ -5,7 +5,10 @@ import arrow.core.left import arrow.core.right import dev.alvr.katana.common.session.domain.failures.SessionFailure import dev.alvr.katana.common.session.domain.repositories.SessionRepository +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.mokkery.answering.returns @@ -13,13 +16,17 @@ import dev.mokkery.every import dev.mokkery.mock import dev.mokkery.verify import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf +import org.koin.test.KoinTest +import org.koin.test.inject -internal class ObserveActiveSessionUseCaseTest : FreeSpec() { +internal class ObserveActiveSessionUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = ObserveActiveSessionUseCase(repo) + private lateinit var useCase: ObserveActiveSessionUseCase init { "successfully observing the session" { @@ -59,4 +66,10 @@ internal class ObserveActiveSessionUseCaseTest : FreeSpec() { verify { repo.sessionActive } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = ObserveActiveSessionUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/SaveAnilistTokenUseCaseTest.kt b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/SaveAnilistTokenUseCaseTest.kt index 20b5f213c..063114bae 100644 --- a/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/SaveAnilistTokenUseCaseTest.kt +++ b/common/session/domain/src/commonTest/kotlin/dev/alvr/katana/common/session/domain/usecases/SaveAnilistTokenUseCaseTest.kt @@ -5,7 +5,10 @@ import arrow.core.right import dev.alvr.katana.common.session.domain.anilistTokenMock import dev.alvr.katana.common.session.domain.failures.SessionFailure import dev.alvr.katana.common.session.domain.repositories.SessionRepository +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.failures.Failure +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.mokkery.answering.returns @@ -13,11 +16,15 @@ import dev.mokkery.everySuspend import dev.mokkery.mock import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase +import org.koin.test.KoinTest +import org.koin.test.inject -internal class SaveAnilistTokenUseCaseTest : FreeSpec() { +internal class SaveAnilistTokenUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = SaveSessionUseCase(repo) + private lateinit var useCase: SaveSessionUseCase init { "successfully saving the session" { @@ -37,4 +44,10 @@ internal class SaveAnilistTokenUseCaseTest : FreeSpec() { } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = SaveSessionUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/common/user/data/src/commonTest/kotlin/dev/alvr/katana/common/user/data/managers/UserIdManagerTest.kt b/common/user/data/src/commonTest/kotlin/dev/alvr/katana/common/user/data/managers/UserIdManagerTest.kt index 576b52c7a..509f67f65 100644 --- a/common/user/data/src/commonTest/kotlin/dev/alvr/katana/common/user/data/managers/UserIdManagerTest.kt +++ b/common/user/data/src/commonTest/kotlin/dev/alvr/katana/common/user/data/managers/UserIdManagerTest.kt @@ -7,7 +7,10 @@ import dev.alvr.katana.common.user.domain.managers.UserIdManager import dev.alvr.katana.common.user.domain.models.UserId import dev.alvr.katana.common.user.domain.repositories.UserRepository import dev.alvr.katana.common.user.domain.usecases.GetUserIdUseCase +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.mokkery.answering.returns @@ -15,11 +18,14 @@ import dev.mokkery.everySuspend import dev.mokkery.mock import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec +import org.koin.test.KoinTest +import org.koin.test.inject -internal class UserIdManagerTest : FreeSpec() { +internal class UserIdManagerTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = GetUserIdUseCase(repo) + private val useCase = GetUserIdUseCase(dispatcher, repo) private val manager: UserIdManager = UserIdManagerImpl(useCase) init { @@ -35,4 +41,6 @@ internal class UserIdManagerTest : FreeSpec() { verifySuspend { useCase() } } } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/common/user/domain/src/commonMain/kotlin/dev/alvr/katana/common/user/domain/usecases/GetUserIdUseCase.kt b/common/user/domain/src/commonMain/kotlin/dev/alvr/katana/common/user/domain/usecases/GetUserIdUseCase.kt index 52e12f6ee..147cb3d24 100644 --- a/common/user/domain/src/commonMain/kotlin/dev/alvr/katana/common/user/domain/usecases/GetUserIdUseCase.kt +++ b/common/user/domain/src/commonMain/kotlin/dev/alvr/katana/common/user/domain/usecases/GetUserIdUseCase.kt @@ -5,7 +5,7 @@ import dev.alvr.katana.common.user.domain.repositories.UserRepository import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.usecases.EitherUseCase -class GetUserIdUseCase( +open class GetUserIdUseCase( dispatcher: KatanaDispatcher, private val repository: UserRepository, ) : EitherUseCase(dispatcher) { diff --git a/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/GetUserIdUseCaseTest.kt b/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/GetUserIdUseCaseTest.kt index 612c15c64..bddaa4442 100644 --- a/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/GetUserIdUseCaseTest.kt +++ b/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/GetUserIdUseCaseTest.kt @@ -5,8 +5,11 @@ import arrow.core.right import dev.alvr.katana.common.user.domain.failures.UserFailure import dev.alvr.katana.common.user.domain.repositories.UserRepository import dev.alvr.katana.common.user.domain.userIdMock +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.failures.Failure import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.mokkery.answering.returns @@ -14,11 +17,15 @@ import dev.mokkery.everySuspend import dev.mokkery.mock import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase +import org.koin.test.KoinTest +import org.koin.test.inject -internal class GetUserIdUseCaseTest : FreeSpec() { +internal class GetUserIdUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = GetUserIdUseCase(repo) + private lateinit var useCase: GetUserIdUseCase init { "successfully getting user id" { @@ -38,4 +45,10 @@ internal class GetUserIdUseCaseTest : FreeSpec() { } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = GetUserIdUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/ObserveUserInfoUseCaseTest.kt b/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/ObserveUserInfoUseCaseTest.kt index b1bbc036d..61a6e6da9 100644 --- a/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/ObserveUserInfoUseCaseTest.kt +++ b/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/ObserveUserInfoUseCaseTest.kt @@ -6,7 +6,10 @@ import arrow.core.right import dev.alvr.katana.common.user.domain.failures.UserFailure import dev.alvr.katana.common.user.domain.repositories.UserRepository import dev.alvr.katana.common.user.domain.userInfoMock +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.mokkery.answering.returns @@ -14,13 +17,17 @@ import dev.mokkery.every import dev.mokkery.mock import dev.mokkery.verify import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf +import org.koin.test.KoinTest +import org.koin.test.inject -internal class ObserveUserInfoUseCaseTest : FreeSpec() { +internal class ObserveUserInfoUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = ObserveUserInfoUseCase(repo) + private lateinit var useCase: ObserveUserInfoUseCase init { "successfully observing user info" { @@ -49,4 +56,10 @@ internal class ObserveUserInfoUseCaseTest : FreeSpec() { verify { repo.userInfo } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = ObserveUserInfoUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/SaveUserIdUseCaseTest.kt b/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/SaveUserIdUseCaseTest.kt index 544e49913..d71bb8213 100644 --- a/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/SaveUserIdUseCaseTest.kt +++ b/common/user/domain/src/commonTest/kotlin/dev/alvr/katana/common/user/domain/usecases/SaveUserIdUseCaseTest.kt @@ -4,8 +4,11 @@ import arrow.core.left import arrow.core.right import dev.alvr.katana.common.user.domain.failures.UserFailure import dev.alvr.katana.common.user.domain.repositories.UserRepository +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.failures.Failure import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.mokkery.answering.returns @@ -13,11 +16,15 @@ import dev.mokkery.everySuspend import dev.mokkery.mock import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase +import org.koin.test.KoinTest +import org.koin.test.inject -internal class SaveUserIdUseCaseTest : FreeSpec() { +internal class SaveUserIdUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = SaveUserIdUseCase(repo) + private lateinit var useCase: SaveUserIdUseCase init { "successfully saving user id" { @@ -38,4 +45,10 @@ internal class SaveUserIdUseCaseTest : FreeSpec() { } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = SaveUserIdUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/coroutines/AppKatanaDispatcher.kt b/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/coroutines/AppKatanaDispatcher.kt new file mode 100644 index 000000000..74b144b6d --- /dev/null +++ b/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/coroutines/AppKatanaDispatcher.kt @@ -0,0 +1,10 @@ +package dev.alvr.katana.core.common.coroutines + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.IO + +internal class AppKatanaDispatcher : KatanaDispatcher { + override val main = Dispatchers.Main + override val io = Dispatchers.IO + override val default = Dispatchers.Default +} diff --git a/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/coroutines/KatanaDispatcher.kt b/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/coroutines/KatanaDispatcher.kt index 6b160e5af..064a5edd6 100644 --- a/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/coroutines/KatanaDispatcher.kt +++ b/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/coroutines/KatanaDispatcher.kt @@ -1,14 +1,9 @@ package dev.alvr.katana.core.common.coroutines -import kotlin.jvm.JvmField import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.IO -import kotlinx.coroutines.MainCoroutineDispatcher -@Suppress("UseDataClass") -class KatanaDispatcher internal constructor( - @JvmField val main: MainCoroutineDispatcher = Dispatchers.Main, - @JvmField val io: CoroutineDispatcher = Dispatchers.IO, - @JvmField val default: CoroutineDispatcher = Dispatchers.Default, -) +interface KatanaDispatcher { + val main: CoroutineDispatcher + val io: CoroutineDispatcher + val default: CoroutineDispatcher +} diff --git a/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/di/module.kt b/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/di/module.kt index 0e6784498..8d1a1bfd8 100644 --- a/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/di/module.kt +++ b/core/common/src/commonMain/kotlin/dev/alvr/katana/core/common/di/module.kt @@ -1,8 +1,15 @@ package dev.alvr.katana.core.common.di +import dev.alvr.katana.core.common.coroutines.AppKatanaDispatcher import dev.alvr.katana.core.common.coroutines.KatanaDispatcher +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.bind import org.koin.dsl.module +private val dispatcherModule = module { + singleOf(::AppKatanaDispatcher) bind KatanaDispatcher::class +} + val coreCommonModule = module { - single { KatanaDispatcher() } + includes(dispatcherModule) } diff --git a/core/tests/build.gradle.kts b/core/tests/build.gradle.kts index 9e3e63910..7252b5033 100644 --- a/core/tests/build.gradle.kts +++ b/core/tests/build.gradle.kts @@ -4,6 +4,8 @@ plugins { katanaMultiplatform { commonMainDependencies { + implementation(projects.core.common) + implementation(libs.arrow) implementation(libs.koin) implementation(libs.koin.test.get().toString()) { exclude(group = "junit", module = "junit") } diff --git a/core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/KoinExtension.kt b/core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/KoinExtension.kt index 0de3efdc2..ec277078e 100644 --- a/core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/KoinExtension.kt +++ b/core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/KoinExtension.kt @@ -11,18 +11,17 @@ import org.koin.core.module.Module import org.koin.test.mock.MockProvider import org.koin.test.mock.Provider -class KoinExtension( +fun koinExtension( + vararg modules: Module, + mockProvider: Provider<*>? = null, + mode: KoinLifecycleMode = KoinLifecycleMode.Test, +): TestCaseExtension = KoinExtensionImpl(modules.toList(), mockProvider, mode) + +private class KoinExtensionImpl( private val modules: List, private val mockProvider: Provider<*>? = null, private val mode: KoinLifecycleMode = KoinLifecycleMode.Test, ) : TestCaseExtension { - - constructor( - module: Module, - mockProvider: Provider<*>? = null, - mode: KoinLifecycleMode = KoinLifecycleMode.Test, - ) : this(listOf(module), mockProvider, mode) - @Suppress("TooGenericExceptionCaught") override suspend fun intercept(testCase: TestCase, execute: suspend (TestCase) -> TestResult): TestResult { return if (testCase.isApplicable()) { @@ -46,8 +45,8 @@ class KoinExtension( private fun TestCase.isApplicable() = mode == KoinLifecycleMode.Root && isRootTest() || mode == KoinLifecycleMode.Test && type == TestType.Test +} - enum class KoinLifecycleMode { - Root, Test - } +enum class KoinLifecycleMode { + Root, Test } diff --git a/core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/coroutines/TestKatanaDispatcher.kt b/core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/coroutines/TestKatanaDispatcher.kt new file mode 100644 index 000000000..185e6f40c --- /dev/null +++ b/core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/coroutines/TestKatanaDispatcher.kt @@ -0,0 +1,13 @@ +package dev.alvr.katana.core.tests.coroutines + +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.UnconfinedTestDispatcher + +@OptIn(ExperimentalCoroutinesApi::class) +internal class TestKatanaDispatcher : KatanaDispatcher { + override val main = StandardTestDispatcher(name = "main") + override val io = UnconfinedTestDispatcher(name = "io") + override val default = UnconfinedTestDispatcher(name = "default") +} diff --git a/core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/di/module.kt b/core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/di/module.kt new file mode 100644 index 000000000..16a9933bf --- /dev/null +++ b/core/tests/src/commonMain/kotlin/dev/alvr/katana/core/tests/di/module.kt @@ -0,0 +1,15 @@ +package dev.alvr.katana.core.tests.di + +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher +import dev.alvr.katana.core.tests.coroutines.TestKatanaDispatcher +import org.koin.core.module.dsl.singleOf +import org.koin.dsl.bind +import org.koin.dsl.module + +private val dispatcherModule = module { + singleOf(::TestKatanaDispatcher) bind KatanaDispatcher::class +} + +val coreTestsModule = module { + includes(dispatcherModule) +} diff --git a/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/ObserveAnimeListUseCaseTest.kt b/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/ObserveAnimeListUseCaseTest.kt index f7829800c..daf1e33ee 100644 --- a/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/ObserveAnimeListUseCaseTest.kt +++ b/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/ObserveAnimeListUseCaseTest.kt @@ -3,7 +3,10 @@ package dev.alvr.katana.features.lists.domain.usecases import app.cash.turbine.test import arrow.core.left import arrow.core.right +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.alvr.katana.features.lists.domain.failures.ListsFailure @@ -15,13 +18,17 @@ import dev.mokkery.every import dev.mokkery.mock import dev.mokkery.verify import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf +import org.koin.test.KoinTest +import org.koin.test.inject -internal class ObserveAnimeListUseCaseTest : FreeSpec() { +internal class ObserveAnimeListUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = ObserveAnimeListUseCase(repo) + private lateinit var useCase: ObserveAnimeListUseCase init { "successfully observe the anime lists" { @@ -54,4 +61,10 @@ internal class ObserveAnimeListUseCaseTest : FreeSpec() { verify { repo.animeCollection } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = ObserveAnimeListUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/ObserveMangaListUseCaseTest.kt b/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/ObserveMangaListUseCaseTest.kt index 7faf8c9ca..8fe223ef9 100644 --- a/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/ObserveMangaListUseCaseTest.kt +++ b/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/ObserveMangaListUseCaseTest.kt @@ -3,7 +3,10 @@ package dev.alvr.katana.features.lists.domain.usecases import app.cash.turbine.test import arrow.core.left import arrow.core.right +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.usecases.invoke +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.alvr.katana.features.lists.domain.failures.ListsFailure @@ -15,13 +18,17 @@ import dev.mokkery.every import dev.mokkery.mock import dev.mokkery.verify import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf +import org.koin.test.KoinTest +import org.koin.test.inject -internal class ObserveMangaListUseCaseTest : FreeSpec() { +internal class ObserveMangaListUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = ObserveMangaListUseCase(repo) + private lateinit var useCase: ObserveMangaListUseCase init { "successfully observe the manga lists" { @@ -54,4 +61,10 @@ internal class ObserveMangaListUseCaseTest : FreeSpec() { verify { repo.mangaCollection } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = ObserveMangaListUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/UpdateListUseCaseTest.kt b/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/UpdateListUseCaseTest.kt index a8e063d2c..892febb35 100644 --- a/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/UpdateListUseCaseTest.kt +++ b/features/lists/domain/src/commonTest/kotlin/dev/alvr/katana/features/lists/domain/usecases/UpdateListUseCaseTest.kt @@ -2,7 +2,10 @@ package dev.alvr.katana.features.lists.domain.usecases import arrow.core.left import arrow.core.right +import dev.alvr.katana.core.common.coroutines.KatanaDispatcher import dev.alvr.katana.core.domain.failures.Failure +import dev.alvr.katana.core.tests.koinExtension +import dev.alvr.katana.core.tests.di.coreTestsModule import dev.alvr.katana.core.tests.shouldBeLeft import dev.alvr.katana.core.tests.shouldBeRight import dev.alvr.katana.features.lists.domain.failures.ListsFailure @@ -14,11 +17,15 @@ import dev.mokkery.matcher.any import dev.mokkery.mock import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec +import io.kotest.core.test.TestCase +import org.koin.test.KoinTest +import org.koin.test.inject -internal class UpdateListUseCaseTest : FreeSpec() { +internal class UpdateListUseCaseTest : FreeSpec(), KoinTest { + private val dispatcher by inject() private val repo = mock() - private val useCase = UpdateListUseCase(repo) + private lateinit var useCase: UpdateListUseCase init { "successfully updating the list" { @@ -38,4 +45,10 @@ internal class UpdateListUseCaseTest : FreeSpec() { } } } + + override suspend fun beforeEach(testCase: TestCase) { + useCase = UpdateListUseCase(dispatcher, repo) + } + + override fun extensions() = listOf(koinExtension(coreTestsModule)) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0ba9a12cd..6370e7c0e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -android = "8.2.2" +android = "8.3.0" androidx-activity = "1.8.2" androidx-lifecycle = "2.7.0" androidx-splashscreen = "1.0.1"