From bdc1e73912fdbd6be24d60a93bc600de4162b39a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Salcedo=20Garc=C3=ADa?= Date: Mon, 26 Feb 2024 00:44:35 +0100 Subject: [PATCH] feat: mokkery --- .../katana-convention/build.gradle.kts | 2 +- .../mp/core/KatanaMultiplatformCorePlugin.kt | 4 +- .../KatanaMultiplatformMobileBasePlugin.kt | 4 +- build.gradle.kts | 2 +- common/tests/build.gradle.kts | 1 - .../katana/common/tests/MockerExtension.kt | 15 --- .../EncryptedPreferencesSerializerTest.kt | 54 ++++----- .../session/mocks/SessionDataStore.kt | 6 - .../data/preferences/session/mocks/mocks.kt | 14 +++ .../repositories/SessionRepositoryTest.kt | 71 ++++++------ .../session/sources/SessionLocalSourceTest.kt | 104 +++++++++--------- .../alvr/katana/data/remote/lists/mocks.kt | 78 +++++++++++++ .../lists/repositories/ListsRepositoryTest.kt | 64 +++++------ .../sources/ApolloListsRemoteSourceTest.kt | 46 ++++---- .../sources/CommonListsRemoteSourceTest.kt | 59 ++++------ .../lists/sources/ListsRemoteSourceTest.kt | 19 ++-- .../remote/user/managers/UserIdManagerTest.kt | 22 ++-- .../dev/alvr/katana/data/remote/user/mocks.kt | 8 ++ .../user/repositories/UserRepositoryTest.kt | 53 ++++----- .../sources/info/UserInfoRemoteSourceTest.kt | 3 - .../dev/alvr/katana/domain/lists/mocks.kt | 27 +++++ .../usecases/ObserveAnimeListUseCaseTest.kt | 22 ++-- .../usecases/ObserveMangaListUseCaseTest.kt | 22 ++-- .../lists/usecases/UpdateListUseCaseTest.kt | 32 +++--- .../dev/alvr/katana/domain/session/mocks.kt | 2 +- .../usecases/ClearActiveSessionUseCaseTest.kt | 22 ++-- .../usecases/DeleteAnilistTokenUseCaseTest.kt | 22 ++-- .../usecases/GetAnilistTokenUseCaseTest.kt | 26 ++--- .../session/usecases/LogOutUseCaseTest.kt | 22 ++-- .../ObserveActiveSessionUseCaseTest.kt | 22 ++-- .../usecases/SaveAnilistTokenUseCaseTest.kt | 28 ++--- .../dev/alvr/katana/domain/user/mocks.kt | 16 +++ .../user/usecases/GetUserIdUseCaseTest.kt | 29 ++--- .../usecases/ObserveUserInfoUseCaseTest.kt | 29 ++--- .../user/usecases/SaveUserIdUseCaseTest.kt | 22 ++-- gradle/libs.versions.toml | 9 +- 36 files changed, 491 insertions(+), 490 deletions(-) delete mode 100644 common/tests/src/commonMain/kotlin/dev/alvr/katana/common/tests/MockerExtension.kt delete mode 100644 data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/mocks/SessionDataStore.kt create mode 100644 data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/mocks/mocks.kt create mode 100644 data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/mocks.kt create mode 100644 data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/mocks.kt create mode 100644 domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/mocks.kt create mode 100644 domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/mocks.kt diff --git a/build-logic/katana-convention/build.gradle.kts b/build-logic/katana-convention/build.gradle.kts index 09a03358d..92d334ea4 100644 --- a/build-logic/katana-convention/build.gradle.kts +++ b/build-logic/katana-convention/build.gradle.kts @@ -18,7 +18,7 @@ dependencies { implementation(libs.gradle.kotlin) implementation(libs.gradle.kover) implementation(libs.gradle.ksp) - implementation(libs.gradle.mockmp) + implementation(libs.gradle.mokkery) implementation(libs.gradle.sentry) implementation(libs.kotlinpoet) implementation(libs.yamlbeans) diff --git a/build-logic/katana-convention/src/main/kotlin/dev/alvr/katana/buildlogic/mp/core/KatanaMultiplatformCorePlugin.kt b/build-logic/katana-convention/src/main/kotlin/dev/alvr/katana/buildlogic/mp/core/KatanaMultiplatformCorePlugin.kt index c0359ca18..e36cd6c21 100644 --- a/build-logic/katana-convention/src/main/kotlin/dev/alvr/katana/buildlogic/mp/core/KatanaMultiplatformCorePlugin.kt +++ b/build-logic/katana-convention/src/main/kotlin/dev/alvr/katana/buildlogic/mp/core/KatanaMultiplatformCorePlugin.kt @@ -17,7 +17,6 @@ import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.get import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.kodein.mock.gradle.MocKMPGradlePlugin internal class KatanaMultiplatformCorePlugin : Plugin { @@ -26,14 +25,13 @@ internal class KatanaMultiplatformCorePlugin : Plugin { apply(plugin = "com.google.devtools.ksp") apply(plugin = "io.kotest.multiplatform") apply(plugin = "org.jetbrains.kotlinx.kover") - apply(plugin = "org.kodein.mock.mockmp") + apply(plugin = "dev.mokkery") with(extensions) { create(KATANA_MULTIPLATFORM_EXTENSION) commonExtensions() configure { configureMultiplatform() } - configure { installWorkaround() } } with(tasks) { diff --git a/build-logic/katana-convention/src/main/kotlin/dev/alvr/katana/buildlogic/mp/mobile/KatanaMultiplatformMobileBasePlugin.kt b/build-logic/katana-convention/src/main/kotlin/dev/alvr/katana/buildlogic/mp/mobile/KatanaMultiplatformMobileBasePlugin.kt index 0b6871a3f..47a450a3c 100644 --- a/build-logic/katana-convention/src/main/kotlin/dev/alvr/katana/buildlogic/mp/mobile/KatanaMultiplatformMobileBasePlugin.kt +++ b/build-logic/katana-convention/src/main/kotlin/dev/alvr/katana/buildlogic/mp/mobile/KatanaMultiplatformMobileBasePlugin.kt @@ -22,7 +22,6 @@ import org.gradle.kotlin.dsl.getValue import org.gradle.kotlin.dsl.getting import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet -import org.kodein.mock.gradle.MocKMPGradlePlugin internal abstract class KatanaMultiplatformMobileBasePlugin( private val androidPlugin: String, @@ -37,7 +36,7 @@ internal abstract class KatanaMultiplatformMobileBasePlugin( apply(plugin = "com.google.devtools.ksp") apply(plugin = "io.kotest.multiplatform") apply(plugin = "org.jetbrains.kotlinx.kover") - apply(plugin = "org.kodein.mock.mockmp") + apply(plugin = "dev.mokkery") with(extensions) { create(KATANA_MULTIPLATFORM_EXTENSION) @@ -46,7 +45,6 @@ internal abstract class KatanaMultiplatformMobileBasePlugin( configureAndroid() configure { configureBuildConfig() } configure { configureMultiplatform() } - configure { installWorkaround() } } tasks.commonTasks() diff --git a/build.gradle.kts b/build.gradle.kts index 0ea2807d8..00bdfbb7a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,6 +14,6 @@ plugins { alias(libs.plugins.kotlin) apply false alias(libs.plugins.kover) apply false alias(libs.plugins.ksp) apply false - alias(libs.plugins.mockmp) apply false + alias(libs.plugins.mokkery) apply false alias(libs.plugins.sentry) apply false } diff --git a/common/tests/build.gradle.kts b/common/tests/build.gradle.kts index 0c8a4d406..9e3e63910 100644 --- a/common/tests/build.gradle.kts +++ b/common/tests/build.gradle.kts @@ -7,6 +7,5 @@ katanaMultiplatform { implementation(libs.arrow) implementation(libs.koin) implementation(libs.koin.test.get().toString()) { exclude(group = "junit", module = "junit") } - implementation(libs.mockmp) } } diff --git a/common/tests/src/commonMain/kotlin/dev/alvr/katana/common/tests/MockerExtension.kt b/common/tests/src/commonMain/kotlin/dev/alvr/katana/common/tests/MockerExtension.kt deleted file mode 100644 index 710ac6937..000000000 --- a/common/tests/src/commonMain/kotlin/dev/alvr/katana/common/tests/MockerExtension.kt +++ /dev/null @@ -1,15 +0,0 @@ -package dev.alvr.katana.common.tests - -import io.kotest.core.extensions.TestCaseExtension -import io.kotest.core.test.TestCase -import io.kotest.core.test.TestResult -import org.kodein.mock.Mocker - -private class MockerExtension(private val mocker: Mocker) : TestCaseExtension { - override suspend fun intercept( - testCase: TestCase, - execute: suspend (TestCase) -> TestResult - ) = execute(testCase).also { mocker.reset() } -} - -operator fun Mocker.invoke(): TestCaseExtension = MockerExtension(this) diff --git a/data/preferences/base/src/commonTest/kotlin/dev/alvr/katana/data/preferences/base/serializers/EncryptedPreferencesSerializerTest.kt b/data/preferences/base/src/commonTest/kotlin/dev/alvr/katana/data/preferences/base/serializers/EncryptedPreferencesSerializerTest.kt index c6ab78bc5..6f712e8c5 100644 --- a/data/preferences/base/src/commonTest/kotlin/dev/alvr/katana/data/preferences/base/serializers/EncryptedPreferencesSerializerTest.kt +++ b/data/preferences/base/src/commonTest/kotlin/dev/alvr/katana/data/preferences/base/serializers/EncryptedPreferencesSerializerTest.kt @@ -1,9 +1,13 @@ package dev.alvr.katana.data.preferences.base.serializers import androidx.datastore.core.CorruptionException -import dev.alvr.katana.common.tests.invoke -import dev.alvr.katana.data.preferences.base.encrypt.MockPreferencesEncrypt import dev.alvr.katana.data.preferences.base.encrypt.PreferencesEncrypt +import dev.mokkery.answering.calls +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.matcher.any +import dev.mokkery.mock +import dev.mokkery.verify import io.kotest.assertions.throwables.shouldThrowExactlyUnit import io.kotest.core.spec.style.FreeSpec import io.kotest.matchers.shouldBe @@ -15,13 +19,9 @@ import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import okio.Buffer -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(PreferencesEncrypt::class) internal class EncryptedPreferencesSerializerTest : FreeSpec() { - private val mocker = Mocker() - private val encrypt = MockPreferencesEncrypt(mocker) + private val encrypt = mock() private val serializer = EncryptedPreferencesSerializer( encrypt = encrypt, @@ -33,73 +33,69 @@ internal class EncryptedPreferencesSerializerTest : FreeSpec() { "writing and reading from the buffer" { val source = Buffer() - mocker.every { encrypt.encrypt(isAny()) } runs { it.first() as ByteArray } - mocker.every { encrypt.decrypt(isAny()) } runs { it.first() as ByteArray } + every { encrypt.encrypt(any()) } calls { it.arg(0) as ByteArray } + every { encrypt.decrypt(any()) } calls { it.arg(0) as ByteArray } serializer.writeTo(Color(0x123456), source) serializer.readFrom(source) shouldBe Color(0x123456) - mocker.verify { - encrypt.encrypt(isAny()) - encrypt.decrypt(isAny()) + verify { + encrypt.encrypt(any()) + encrypt.decrypt(any()) } } "reading from an empty buffer" { val source = Buffer() - mocker.every { encrypt.encrypt(isAny()) } returns byteArrayOf() - mocker.every { encrypt.decrypt(isAny()) } returns byteArrayOf() + every { encrypt.encrypt(any()) } returns byteArrayOf() + every { encrypt.decrypt(any()) } returns byteArrayOf() shouldThrowExactlyUnit { serializer.readFrom(source) }.message shouldBe "secured read" - mocker.verify { encrypt.decrypt(isAny()) } + verify { encrypt.decrypt(any()) } } "reading an invalid data" { val source = Buffer() source.write(byteArrayOf()) - mocker.every { encrypt.encrypt(isAny()) } returns byteArrayOf() - mocker.every { encrypt.decrypt(isAny()) } returns byteArrayOf() + every { encrypt.encrypt(any()) } returns byteArrayOf() + every { encrypt.decrypt(any()) } returns byteArrayOf() shouldThrowExactlyUnit { serializer.readFrom(source) }.message shouldBe "secured read" - mocker.verify { encrypt.decrypt(isAny()) } + verify { encrypt.decrypt(any()) } } "error when writing secure data" { val source = Buffer() - mocker.every { encrypt.encrypt(isAny()) } runs { error("oops") } - mocker.every { encrypt.decrypt(isAny()) } returns byteArrayOf() + every { encrypt.encrypt(any()) } calls { error("oops") } + every { encrypt.decrypt(any()) } returns byteArrayOf() shouldThrowExactlyUnit { serializer.writeTo(Color(0x123456), source) }.message shouldBe "secured write" - mocker.verify { - threw { encrypt.encrypt(isAny()) } - } + verify { encrypt.encrypt(any()) } } "error when reading secure data" { val source = Buffer() - mocker.every { encrypt.encrypt(isAny()) } returns byteArrayOf() - mocker.every { encrypt.decrypt(isAny()) } runs { error("oops") } + every { encrypt.encrypt(any()) } returns byteArrayOf() + every { encrypt.decrypt(any()) } calls { error("oops") } shouldThrowExactlyUnit { serializer.readFrom(source) }.message shouldBe "secured read" - mocker.verify { - threw { encrypt.decrypt(isAny()) } - } + verify { encrypt.decrypt(any()) } } } @@ -120,6 +116,4 @@ internal class EncryptedPreferencesSerializerTest : FreeSpec() { return Color(string.toInt(16)) } } - - override fun extensions() = listOf(mocker()) } diff --git a/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/mocks/SessionDataStore.kt b/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/mocks/SessionDataStore.kt deleted file mode 100644 index c55ae0304..000000000 --- a/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/mocks/SessionDataStore.kt +++ /dev/null @@ -1,6 +0,0 @@ -package dev.alvr.katana.data.preferences.session.mocks - -import androidx.datastore.core.DataStore -import dev.alvr.katana.data.preferences.session.models.Session - -internal sealed interface SessionDataStore : DataStore diff --git a/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/mocks/mocks.kt b/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/mocks/mocks.kt new file mode 100644 index 000000000..f19b0d43f --- /dev/null +++ b/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/mocks/mocks.kt @@ -0,0 +1,14 @@ +package dev.alvr.katana.data.preferences.session.mocks + +import dev.alvr.katana.data.preferences.session.models.Session +import dev.alvr.katana.domain.session.models.AnilistToken +import io.kotest.property.Arb +import io.kotest.property.arbitrary.boolean +import io.kotest.property.arbitrary.next + +internal val anilistTokenMock = AnilistToken("TOKEN") + +internal val sessionMock = Session( + anilistToken = anilistTokenMock, + isSessionActive = Arb.boolean().next(), +) diff --git a/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/repositories/SessionRepositoryTest.kt b/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/repositories/SessionRepositoryTest.kt index 0cf0ee080..e285d3e3e 100644 --- a/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/repositories/SessionRepositoryTest.kt +++ b/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/repositories/SessionRepositoryTest.kt @@ -5,34 +5,33 @@ import arrow.core.left import arrow.core.none import arrow.core.right import arrow.core.some -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeNone import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.common.tests.shouldBeSome -import dev.alvr.katana.data.preferences.session.sources.MockSessionLocalSource +import dev.alvr.katana.data.preferences.session.mocks.anilistTokenMock import dev.alvr.katana.data.preferences.session.sources.SessionLocalSource import dev.alvr.katana.domain.session.failures.SessionFailure -import dev.alvr.katana.domain.session.models.AnilistToken import dev.alvr.katana.domain.session.repositories.SessionRepository +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(SessionLocalSource::class) internal class SessionRepositoryTest : FreeSpec() { - private val mocker = Mocker() - private val source: SessionLocalSource = MockSessionLocalSource(mocker) - private val repo: SessionRepository = SessionRepositoryImpl(source) + private val source: SessionLocalSource = mock() - private val anilistToken = AnilistToken("TOKEN") + private val repo: SessionRepository = SessionRepositoryImpl(source) init { "observing" - { "observing if the session is active" { - mocker.every { source.sessionActive } returns flowOf( + every { source.sessionActive } returns flowOf( true.right(), true.right(), false.right(), @@ -45,80 +44,78 @@ internal class SessionRepositoryTest : FreeSpec() { awaitComplete() } - mocker.verify { source.sessionActive } + verify { source.sessionActive } } } "getting" - { "getting a non-existing token" { - mocker.everySuspending { source.getAnilistToken() } returns none() + everySuspend { source.getAnilistToken() } returns none() repo.getAnilistToken().shouldBeNone() - mocker.verifyWithSuspend { source.getAnilistToken() } + verifySuspend { source.getAnilistToken() } } "getting an existing token" { - mocker.everySuspending { source.getAnilistToken() } returns anilistToken.some() - repo.getAnilistToken().shouldBeSome(anilistToken) - mocker.verifyWithSuspend { source.getAnilistToken() } + everySuspend { source.getAnilistToken() } returns anilistTokenMock.some() + repo.getAnilistToken().shouldBeSome(anilistTokenMock) + verifySuspend { source.getAnilistToken() } } } "saving" - { "saving a session without error" { - mocker.everySuspending { source.saveSession(isAny()) } returns Unit.right() - repo.saveSession(anilistToken).shouldBeRight(Unit) - mocker.verifyWithSuspend { source.saveSession(anilistToken) } + everySuspend { source.saveSession(anilistTokenMock) } returns Unit.right() + repo.saveSession(anilistTokenMock).shouldBeRight(Unit) + verifySuspend { source.saveSession(anilistTokenMock) } } "saving a session with an error" { - mocker.everySuspending { source.saveSession(isAny()) } returns SessionFailure.SavingSession.left() - repo.saveSession(anilistToken).shouldBeLeft(SessionFailure.SavingSession) - mocker.verifyWithSuspend { source.saveSession(anilistToken) } + everySuspend { source.saveSession(anilistTokenMock) } returns SessionFailure.SavingSession.left() + repo.saveSession(anilistTokenMock).shouldBeLeft(SessionFailure.SavingSession) + verifySuspend { source.saveSession(anilistTokenMock) } } } "deleting" - { "deleting a session without error" { - mocker.everySuspending { source.deleteAnilistToken() } returns Unit.right() + everySuspend { source.deleteAnilistToken() } returns Unit.right() repo.deleteAnilistToken().shouldBeRight(Unit) - mocker.verifyWithSuspend { source.deleteAnilistToken() } + verifySuspend { source.deleteAnilistToken() } } "deleting a session with an error" { - mocker.everySuspending { source.deleteAnilistToken() } returns SessionFailure.DeletingToken.left() + everySuspend { source.deleteAnilistToken() } returns SessionFailure.DeletingToken.left() repo.deleteAnilistToken().shouldBeLeft(SessionFailure.DeletingToken) - mocker.verifyWithSuspend { source.deleteAnilistToken() } + verifySuspend { source.deleteAnilistToken() } } } "clearing" - { "clearing a session without error" { - mocker.everySuspending { source.clearActiveSession() } returns Unit.right() + everySuspend { source.clearActiveSession() } returns Unit.right() repo.clearActiveSession().shouldBeRight(Unit) - mocker.verifyWithSuspend { source.clearActiveSession() } + verifySuspend { source.clearActiveSession() } } "clearing a session with an error" { - mocker.everySuspending { source.clearActiveSession() } returns SessionFailure.ClearingSession.left() + everySuspend { source.clearActiveSession() } returns SessionFailure.ClearingSession.left() repo.clearActiveSession().shouldBeLeft(SessionFailure.ClearingSession) - mocker.verifyWithSuspend { source.clearActiveSession() } + verifySuspend { source.clearActiveSession() } } } "logging out" - { "logging out without error" { - mocker.everySuspending { source.logout() } returns Unit.right() + everySuspend { source.logout() } returns Unit.right() repo.logout().shouldBeRight(Unit) - mocker.verifyWithSuspend { source.logout() } + verifySuspend { source.logout() } } "logging out with an error" { - mocker.everySuspending { source.logout() } returns SessionFailure.LoggingOut.left() + everySuspend { source.logout() } returns SessionFailure.LoggingOut.left() repo.logout().shouldBeLeft(SessionFailure.LoggingOut) - mocker.verifyWithSuspend { source.logout() } + verifySuspend { source.logout() } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/sources/SessionLocalSourceTest.kt b/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/sources/SessionLocalSourceTest.kt index 7324d828f..37df0a06a 100644 --- a/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/sources/SessionLocalSourceTest.kt +++ b/data/preferences/session/src/commonTest/kotlin/dev/alvr/katana/data/preferences/session/sources/SessionLocalSourceTest.kt @@ -1,147 +1,143 @@ package dev.alvr.katana.data.preferences.session.sources +import androidx.datastore.core.DataStore import androidx.datastore.core.IOException import app.cash.turbine.test -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeNone import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.common.tests.shouldBeSome -import dev.alvr.katana.data.preferences.session.mocks.MockSessionDataStore -import dev.alvr.katana.data.preferences.session.mocks.SessionDataStore +import dev.alvr.katana.data.preferences.session.mocks.anilistTokenMock +import dev.alvr.katana.data.preferences.session.mocks.sessionMock import dev.alvr.katana.data.preferences.session.models.Session -import dev.alvr.katana.data.preferences.session.models.fakeSession import dev.alvr.katana.domain.session.failures.SessionFailure -import dev.alvr.katana.domain.session.models.AnilistToken +import dev.mokkery.answering.returns +import dev.mokkery.answering.throws +import dev.mokkery.every +import dev.mokkery.everySuspend +import dev.mokkery.matcher.any +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf -import org.kodein.mock.Mocker -import org.kodein.mock.UsesFakes -import org.kodein.mock.UsesMocks -@UsesFakes(Session::class) -@UsesMocks(SessionDataStore::class) -@Suppress("TooGenericExceptionThrown") internal class SessionLocalSourceTest : FreeSpec() { - private val mocker = Mocker() - private val store: SessionDataStore = MockSessionDataStore(mocker) - private val source: SessionLocalSource = SessionLocalSourceImpl(store) + private val store = mock>() - private val anilistToken = AnilistToken("TOKEN") + private val source: SessionLocalSource = SessionLocalSourceImpl(store) init { "successful" - { "getting a token from datastore for the first time" { - mocker.every { store.data } returns flowOf(Session(anilistToken = null)) + every { store.data } returns flowOf(Session(anilistToken = null)) source.getAnilistToken().shouldBeNone() - mocker.verify { store.data } + verify { store.data } } "saving a session" { - mocker.everySuspending { store.updateData(isAny()) } returns fakeSession() - source.saveSession(anilistToken).shouldBeRight(Unit) - mocker.verifyWithSuspend { store.updateData(isAny()) } + everySuspend { store.updateData(any()) } returns sessionMock + source.saveSession(anilistTokenMock).shouldBeRight(Unit) + verifySuspend { store.updateData(any()) } } "getting the saved token" { - mocker.every { store.data } returns flowOf( + every { store.data } returns flowOf( Session( - anilistToken = anilistToken, + anilistToken = anilistTokenMock, isSessionActive = true, ), ) - source.getAnilistToken().shouldBeSome(anilistToken) - mocker.verify { store.data } + source.getAnilistToken().shouldBeSome(anilistTokenMock) + verify { store.data } } "deleting the saved token" { - mocker.everySuspending { store.updateData(isAny()) } returns fakeSession() + everySuspend { store.updateData(any()) } returns sessionMock source.deleteAnilistToken().shouldBeRight(Unit) - mocker.verifyWithSuspend { store.updateData(isAny()) } + verifySuspend { store.updateData(any()) } } "clearing the session" { - mocker.everySuspending { store.updateData(isAny()) } returns fakeSession() + everySuspend { store.updateData(any()) } returns sessionMock source.clearActiveSession().shouldBeRight(Unit) - mocker.verifyWithSuspend { store.updateData(isAny()) } + verifySuspend { store.updateData(any()) } } "logging out" { - mocker.everySuspending { store.updateData(isAny()) } returns fakeSession() + everySuspend { store.updateData(any()) } returns sessionMock source.logout().shouldBeRight(Unit) - mocker.verifyWithSuspend { store.updateData(isAny()) } + verifySuspend { store.updateData(any()) } } listOf( Session(anilistToken = null, isSessionActive = false), Session(anilistToken = null, isSessionActive = true), - Session(anilistToken = anilistToken, isSessionActive = false), - Session(anilistToken = anilistToken, isSessionActive = true), + Session(anilistToken = anilistTokenMock, isSessionActive = false), + Session(anilistToken = anilistTokenMock, isSessionActive = true), ).forEach { session -> "checking session active for ${session.anilistToken} and ${session.isSessionActive}" { - mocker.every { store.data } returns flowOf(session) + every { store.data } returns flowOf(session) source.sessionActive.test(5.seconds) { awaitItem().shouldBeRight((session.anilistToken == null && session.isSessionActive).not()) cancelAndIgnoreRemainingEvents() } - mocker.verify { store.data } + verify { store.data } } } } "failure" - { "the clearing the session fails AND it's a common Exception" { - mocker.everySuspending { store.updateData(isAny()) } runs { throw Exception() } + everySuspend { store.updateData(any()) } throws Exception() source.clearActiveSession().shouldBeLeft(SessionFailure.ClearingSession) - mocker.verifyWithSuspend { called { store.updateData(isAny()) } } + verifySuspend { store.updateData(any()) } } "the clearing the session fails AND it's a writing Exception" { - mocker.everySuspending { store.updateData(isAny()) } runs { throw IOException("Oops.") } + everySuspend { store.updateData(any()) } throws IOException("Oops.") source.clearActiveSession().shouldBeLeft(SessionFailure.ClearingSession) - mocker.verifyWithSuspend { called { store.updateData(isAny()) } } + verifySuspend { store.updateData(any()) } } "it's the deleting token AND it's a common Exception" { - mocker.everySuspending { store.updateData(isAny()) } runs { throw Exception() } + everySuspend { store.updateData(any()) } throws Exception() source.deleteAnilistToken().shouldBeLeft(SessionFailure.DeletingToken) - mocker.verifyWithSuspend { called { store.updateData(isAny()) } } + verifySuspend { store.updateData(any()) } } "it's the deleting token AND it's a writing Exception" { - mocker.everySuspending { store.updateData(isAny()) } runs { throw IOException("Oops.") } + everySuspend { store.updateData(any()) } throws IOException("Oops.") source.deleteAnilistToken().shouldBeLeft(SessionFailure.DeletingToken) - mocker.verifyWithSuspend { called { store.updateData(isAny()) } } + verifySuspend { store.updateData(any()) } } "it's the saving token AND it's a common Exception" { - mocker.everySuspending { store.updateData(isAny()) } runs { throw Exception() } - source.saveSession(anilistToken).shouldBeLeft(SessionFailure.SavingSession) - mocker.verifyWithSuspend { called { store.updateData(isAny()) } } + everySuspend { store.updateData(any()) } throws Exception() + source.saveSession(anilistTokenMock).shouldBeLeft(SessionFailure.SavingSession) + verifySuspend { store.updateData(any()) } } "it's the saving token AND it's a writing Exception" { - mocker.everySuspending { store.updateData(isAny()) } runs { throw IOException("Oops.") } - source.saveSession(anilistToken).shouldBeLeft(SessionFailure.SavingSession) - mocker.verifyWithSuspend { called { store.updateData(isAny()) } } + everySuspend { store.updateData(any()) } throws IOException("Oops.") + source.saveSession(anilistTokenMock).shouldBeLeft(SessionFailure.SavingSession) + verifySuspend { store.updateData(any()) } } "it's logging out AND it's a common Exception" { - mocker.everySuspending { store.updateData(isAny()) } runs { throw Exception() } + everySuspend { store.updateData(any()) } throws Exception() source.logout().shouldBeLeft(SessionFailure.LoggingOut) - mocker.verifyWithSuspend { called { store.updateData(isAny()) } } + verifySuspend { store.updateData(any()) } } "it's logging out AND it's a writing Exception" { - mocker.everySuspending { store.updateData(isAny()) } runs { throw IOException("Oops.") } + everySuspend { store.updateData(any()) } throws IOException("Oops.") source.logout().shouldBeLeft(SessionFailure.LoggingOut) - mocker.verifyWithSuspend { called { store.updateData(isAny()) } } + verifySuspend { store.updateData(any()) } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/mocks.kt b/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/mocks.kt new file mode 100644 index 000000000..6b350333f --- /dev/null +++ b/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/mocks.kt @@ -0,0 +1,78 @@ +package dev.alvr.katana.data.remote.lists + +import com.apollographql.apollo3.api.Error +import com.apollographql.apollo3.api.Optional +import dev.alvr.katana.data.remote.base.type.FuzzyDateInput +import dev.alvr.katana.data.remote.base.type.MediaType +import dev.alvr.katana.domain.lists.models.lists.MediaList +import io.kotest.property.Arb +import io.kotest.property.arbitrary.arbitrary +import io.kotest.property.arbitrary.boolean +import io.kotest.property.arbitrary.enum +import io.kotest.property.arbitrary.int +import io.kotest.property.arbitrary.next +import io.kotest.property.arbitrary.orNull +import io.kotest.property.arbitrary.positiveDouble +import io.kotest.property.arbitrary.positiveInt +import io.kotest.property.arbitrary.string +import korlibs.time.Date +import korlibs.time.DateTimeTz + +internal val mediaListCollectionQueryMock = MediaListCollectionQuery( + type = Arb.enum().next(), +) + +internal val mediaListEntriesMutationMock = MediaListEntriesMutation( + id = Arb.int().next(), + score = Optional.presentIfNotNull(Arb.positiveDouble().orNull().next()), + progress = Optional.presentIfNotNull(Arb.positiveInt().orNull().next()), + progressVolumes = Optional.presentIfNotNull(Arb.positiveInt().orNull().next()), + repeat = Optional.presentIfNotNull(Arb.positiveInt().orNull().next()), + private = Optional.presentIfNotNull(Arb.boolean().orNull().next()), + notes = Optional.presentIfNotNull(Arb.string().orNull().next()), + hiddenFromStatusLists = Optional.presentIfNotNull(Arb.boolean().orNull().next()), + startedAt = Optional.presentIfNotNull(Arb.fuzzyDate().orNull().next()), + completedAt = Optional.presentIfNotNull(Arb.fuzzyDate().orNull().next()), +) + +internal val mediaListMock = MediaList( + id = Arb.int().next(), + score = Arb.positiveDouble().next(), + progress = Arb.positiveInt().next(), + progressVolumes = Arb.positiveInt().orNull().next(), + repeat = Arb.positiveInt().next(), + private = Arb.boolean().next(), + notes = Arb.string().next(), + hiddenFromStatusLists = Arb.boolean().next(), + startedAt = Arb.date().orNull().next(), + completedAt = Arb.date().orNull().next(), + updatedAt = Arb.dateTimeTz().orNull().next(), +) + +internal val apolloErrorMock = Error( + message = Arb.string().next(), + locations = emptyList(), + path = emptyList(), + extensions = emptyMap(), + nonStandardFields = emptyMap(), +) + +private fun Arb.Companion.date() = arbitrary { + Date( + year = Arb.int(1970, 2030).next(), + month = Arb.int(1, 12).next(), + day = Arb.int(1, 28).next(), + ) +} + +private fun Arb.Companion.dateTimeTz() = arbitrary { + DateTimeTz.nowLocal() +} + +private fun Arb.Companion.fuzzyDate() = arbitrary { + FuzzyDateInput( + year = Optional.presentIfNotNull(Arb.int().orNull().next()), + month = Optional.presentIfNotNull(Arb.int().orNull().next()), + day = Optional.presentIfNotNull(Arb.int().orNull().next()), + ) +} diff --git a/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/repositories/ListsRepositoryTest.kt b/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/repositories/ListsRepositoryTest.kt index ffb023913..e1be030f8 100644 --- a/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/repositories/ListsRepositoryTest.kt +++ b/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/repositories/ListsRepositoryTest.kt @@ -3,72 +3,64 @@ package dev.alvr.katana.data.remote.lists.repositories import app.cash.turbine.test import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight +import dev.alvr.katana.data.remote.lists.mediaListMock import dev.alvr.katana.data.remote.lists.sources.CommonListsRemoteSource -import dev.alvr.katana.data.remote.lists.sources.MockCommonListsRemoteSource import dev.alvr.katana.data.remote.lists.sources.anime.AnimeListsRemoteSource -import dev.alvr.katana.data.remote.lists.sources.anime.MockAnimeListsRemoteSource import dev.alvr.katana.data.remote.lists.sources.manga.MangaListsRemoteSource -import dev.alvr.katana.data.remote.lists.sources.manga.MockMangaListsRemoteSource import dev.alvr.katana.domain.base.failures.Failure import dev.alvr.katana.domain.lists.failures.ListsFailure import dev.alvr.katana.domain.lists.models.MediaCollection import dev.alvr.katana.domain.lists.models.entries.MediaEntry -import dev.alvr.katana.domain.lists.models.lists.MediaList -import dev.alvr.katana.domain.lists.models.lists.fakeMediaList import dev.alvr.katana.domain.lists.repositories.ListsRepository +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.everySuspend +import dev.mokkery.matcher.any +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf -import org.kodein.mock.Mocker -import org.kodein.mock.UsesFakes -import org.kodein.mock.UsesMocks -@UsesFakes(MediaList::class) -@UsesMocks( - CommonListsRemoteSource::class, - AnimeListsRemoteSource::class, - MangaListsRemoteSource::class, -) internal class ListsRepositoryTest : FreeSpec() { - private val mocker = Mocker() - private val commonSource = MockCommonListsRemoteSource(mocker) - private val animeSource = MockAnimeListsRemoteSource(mocker) - private val mangaSource = MockMangaListsRemoteSource(mocker) + private val commonSource = mock() + private val animeSource = mock() + private val mangaSource = mock() private val repo: ListsRepository = ListsRepositoryImpl(commonSource, animeSource, mangaSource) init { "collecting anime collection flow" { val collection = MediaCollection(emptyList()) - mocker.every { animeSource.animeCollection } returns flowOf(collection.right()) + every { animeSource.animeCollection } returns flowOf(collection.right()) repo.animeCollection.test(5.seconds) { awaitItem().shouldBeRight(collection) awaitComplete() } - mocker.verify { animeSource.animeCollection } + verify { animeSource.animeCollection } } "collecting manga collection flow" { val collection = MediaCollection(emptyList()) - mocker.every { mangaSource.mangaCollection } returns flowOf(collection.right()) + every { mangaSource.mangaCollection } returns flowOf(collection.right()) repo.mangaCollection.test(5.seconds) { awaitItem().shouldBeRight(collection) awaitComplete() } - mocker.verify { mangaSource.mangaCollection } + verify { mangaSource.mangaCollection } } "successfully updating list" { - mocker.everySuspending { commonSource.updateList(isAny()) } returns Unit.right() - repo.updateList(fakeMediaList()).shouldBeRight(Unit) - mocker.verifyWithSuspend { commonSource.updateList(isAny()) } + everySuspend { commonSource.updateList(any()) } returns Unit.right() + repo.updateList(mediaListMock).shouldBeRight(Unit) + verifySuspend { commonSource.updateList(any()) } } listOf( @@ -76,12 +68,22 @@ internal class ListsRepositoryTest : FreeSpec() { Failure.Unknown to Failure.Unknown.left(), ).forEach { (expected, failure) -> "failure updating the list ($expected)" { - mocker.everySuspending { repo.updateList(isAny()) } returns failure - repo.updateList(fakeMediaList()).shouldBeLeft(expected) - mocker.verifyWithSuspend { repo.updateList(fakeMediaList()) } + everySuspend { commonSource.updateList(any()) } returns failure + repo.updateList(mediaListMock).shouldBeLeft(expected) + verifySuspend { commonSource.updateList(mediaListMock) } } } - } - override fun extensions() = listOf(mocker()) +// "failure updating the list" { +// everySuspend { commonSource.updateList(any()) } sequentially { +// returns(ListsFailure.UpdatingList.left()) +// returns(Failure.Unknown.left()) +// } +// +// repo.updateList(mediaListMock).shouldBeLeft(ListsFailure.UpdatingList) +// repo.updateList(mediaListMock).shouldBeLeft(Failure.Unknown) +// +// verifySuspend { repo.updateList(mediaListMock) } +// } + } } diff --git a/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/ApolloListsRemoteSourceTest.kt b/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/ApolloListsRemoteSourceTest.kt index 95adb9257..040fc5b6a 100644 --- a/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/ApolloListsRemoteSourceTest.kt +++ b/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/ApolloListsRemoteSourceTest.kt @@ -5,12 +5,10 @@ import arrow.core.right import com.apollographql.apollo3.ApolloClient import com.apollographql.apollo3.annotations.ApolloExperimental import com.apollographql.apollo3.interceptor.ApolloInterceptor -import com.apollographql.apollo3.interceptor.MockApolloInterceptor import com.apollographql.apollo3.testing.MapTestNetworkTransport import com.apollographql.apollo3.testing.registerTestNetworkError import com.apollographql.apollo3.testing.registerTestResponse import dev.alvr.katana.common.core.zero -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.data.remote.base.optional @@ -35,8 +33,11 @@ import dev.alvr.katana.data.remote.lists.sources.manga.MangaListsRemoteSourceImp import dev.alvr.katana.domain.lists.failures.ListsFailure import dev.alvr.katana.domain.lists.models.entries.CommonMediaEntry import dev.alvr.katana.domain.lists.models.entries.MediaEntry -import dev.alvr.katana.domain.user.managers.MockUserIdManager import dev.alvr.katana.domain.user.managers.UserIdManager +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec import io.kotest.matchers.booleans.shouldBeFalse import io.kotest.matchers.booleans.shouldBeTrue @@ -54,18 +55,11 @@ import korlibs.time.DateTime import korlibs.time.DateTimeTz import korlibs.time.TimezoneOffset import kotlin.time.Duration.Companion.seconds -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks( - UserIdManager::class, - ApolloInterceptor::class, -) @ApolloExperimental internal class ApolloListsRemoteSourceTest : FreeSpec() { - private val mocker = Mocker() - private val userIdManager = MockUserIdManager(mocker) - private val reloadInterceptor = MockApolloInterceptor(mocker) + private val userIdManager = mock() + private val reloadInterceptor = mock() private val client = ApolloClient.Builder().networkTransport(MapTestNetworkTransport()).build() private val userId = 37_384.right() @@ -77,7 +71,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { init { beforeEach { - mocker.everySuspending { userIdManager.getId() } returns userId + everySuspend { userIdManager.getId() } returns userId } "anime" - { @@ -97,7 +91,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { awaitItem().shouldBeRight().lists.shouldBeEmpty() awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "the entries are empty" { @@ -147,7 +141,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { } awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "the entry has null values" { @@ -220,7 +214,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { } awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "the entry has values" { @@ -314,7 +308,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { } awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "the returned data is null" { @@ -328,7 +322,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "an error occurs" { @@ -344,7 +338,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } } @@ -366,7 +360,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "the entries are empty" { @@ -416,7 +410,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { } awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "the entry has null values" { @@ -490,7 +484,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { } awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "the entry has values" { @@ -576,7 +570,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { } awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "the returned data is null" { @@ -590,7 +584,7 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "an error occurs" { @@ -606,10 +600,8 @@ internal class ApolloListsRemoteSourceTest : FreeSpec() { awaitComplete() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/CommonListsRemoteSourceTest.kt b/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/CommonListsRemoteSourceTest.kt index 18ed0b433..7d8205dc9 100644 --- a/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/CommonListsRemoteSourceTest.kt +++ b/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/CommonListsRemoteSourceTest.kt @@ -5,50 +5,37 @@ import arrow.core.right import com.apollographql.apollo3.ApolloClient import com.apollographql.apollo3.annotations.ApolloExperimental import com.apollographql.apollo3.api.ApolloResponse -import com.apollographql.apollo3.api.Error -import com.apollographql.apollo3.api.fakeError import com.apollographql.apollo3.interceptor.ApolloInterceptor -import com.apollographql.apollo3.interceptor.MockApolloInterceptor import com.apollographql.apollo3.mockserver.MockResponse import com.apollographql.apollo3.mockserver.MockServer import com.apollographql.apollo3.testing.QueueTestNetworkTransport import com.apollographql.apollo3.testing.enqueueTestResponse import com.benasher44.uuid.uuid4 -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.data.remote.base.type.MediaType import dev.alvr.katana.data.remote.base.type.buildMediaListCollection import dev.alvr.katana.data.remote.lists.MediaListCollectionQuery -import dev.alvr.katana.data.remote.lists.MediaListEntriesMutation +import dev.alvr.katana.data.remote.lists.apolloErrorMock import dev.alvr.katana.data.remote.lists.enqueueResponse -import dev.alvr.katana.data.remote.lists.fakeMediaListCollectionQuery -import dev.alvr.katana.data.remote.lists.fakeMediaListEntriesMutation +import dev.alvr.katana.data.remote.lists.mediaListCollectionQueryMock +import dev.alvr.katana.data.remote.lists.mediaListEntriesMutationMock +import dev.alvr.katana.data.remote.lists.mediaListMock import dev.alvr.katana.domain.lists.failures.ListsFailure import dev.alvr.katana.domain.lists.models.MediaCollection import dev.alvr.katana.domain.lists.models.entries.MediaEntry -import dev.alvr.katana.domain.lists.models.lists.MediaList -import dev.alvr.katana.domain.lists.models.lists.fakeMediaList -import dev.alvr.katana.domain.user.managers.MockUserIdManager import dev.alvr.katana.domain.user.managers.UserIdManager +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds -import org.kodein.mock.Mocker -import org.kodein.mock.UsesFakes -import org.kodein.mock.UsesMocks - -@UsesFakes( - Error::class, - MediaList::class, - MediaListCollectionQuery::class, - MediaListEntriesMutation::class, -) -@UsesMocks(UserIdManager::class, ApolloInterceptor::class) + @OptIn(ApolloExperimental::class) internal class CommonListsRemoteSourceTest : FreeSpec() { - private val mocker = Mocker() - private val userIdManager = MockUserIdManager(mocker) - private val reloadInterceptor = MockApolloInterceptor(mocker) + private val userIdManager = mock() + private val reloadInterceptor = mock() private val client = ApolloClient.Builder().networkTransport(QueueTestNetworkTransport()).build() @@ -58,9 +45,9 @@ internal class CommonListsRemoteSourceTest : FreeSpec() { "querying" - { queryList().forEach { (data, type) -> "the server responded with data or not ($data, $type)" { - mocker.everySuspending { userIdManager.getId() } returns 37_384.right() + everySuspend { userIdManager.getId() } returns 37_384.right() val response = ApolloResponse.Builder( - operation = fakeMediaListCollectionQuery(), + operation = mediaListCollectionQueryMock, requestUuid = uuid4(), data = data, ).build() @@ -70,31 +57,31 @@ internal class CommonListsRemoteSourceTest : FreeSpec() { awaitItem().shouldBeRight(MediaCollection(emptyList())) cancelAndIgnoreRemainingEvents() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } "a HTTP error occurs ($data, $type)" { - mocker.everySuspending { userIdManager.getId() } returns 37_384.right() + everySuspend { userIdManager.getId() } returns 37_384.right() val response = ApolloResponse.Builder( - operation = fakeMediaListCollectionQuery(), + operation = mediaListCollectionQueryMock, requestUuid = uuid4(), data = data, - ).errors(listOf(fakeError())).build() + ).errors(listOf(apolloErrorMock)).build() client.enqueueTestResponse(response) source.getMediaCollection(type).test(5.seconds) { awaitItem().shouldBeRight(MediaCollection(emptyList())) cancelAndIgnoreRemainingEvents() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } } } "updating" - { "the server returns some data" { - client.enqueueTestResponse(fakeMediaListEntriesMutation()) - source.updateList(fakeMediaList()).shouldBeRight() + client.enqueueTestResponse(mediaListEntriesMutationMock) + source.updateList(mediaListMock).shouldBeRight() } } @@ -111,21 +98,19 @@ internal class CommonListsRemoteSourceTest : FreeSpec() { badClient().forEach { (type, action) -> "a HTTP error occurs" { - mocker.everySuspending { userIdManager.getId() } returns 37_384.right() + everySuspend { userIdManager.getId() } returns 37_384.right() mockServer.enqueueResponse(action) source.getMediaCollection(type).test(5.seconds) { awaitItem().shouldBeLeft(ListsFailure.GetMediaCollection) cancelAndIgnoreRemainingEvents() } - mocker.verifyWithSuspend { userIdManager.getId() } + verifySuspend { userIdManager.getId() } } } } } - override fun extensions() = listOf(mocker()) - private fun queryList(): List> { val empty = MediaListCollectionQuery.Data { this["collection"] = buildMediaListCollection { diff --git a/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/ListsRemoteSourceTest.kt b/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/ListsRemoteSourceTest.kt index 6f5fa59b1..c0ba9dd23 100644 --- a/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/ListsRemoteSourceTest.kt +++ b/data/remote/lists/src/commonTest/kotlin/dev/alvr/katana/data/remote/lists/sources/ListsRemoteSourceTest.kt @@ -2,7 +2,6 @@ package dev.alvr.katana.data.remote.lists.sources import app.cash.turbine.test import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.data.remote.base.type.MediaType import dev.alvr.katana.data.remote.lists.sources.anime.AnimeListsRemoteSource @@ -11,26 +10,26 @@ import dev.alvr.katana.data.remote.lists.sources.manga.MangaListsRemoteSource import dev.alvr.katana.data.remote.lists.sources.manga.MangaListsRemoteSourceImpl import dev.alvr.katana.domain.lists.models.MediaCollection import dev.alvr.katana.domain.lists.models.entries.MediaEntry +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(CommonListsRemoteSource::class) internal class ListsRemoteSourceTest : FreeSpec() { - private val mocker = Mocker() + private val source = mock() - private val source = MockCommonListsRemoteSource(mocker) private val animeSource: AnimeListsRemoteSource = AnimeListsRemoteSourceImpl(source) private val mangaSource: MangaListsRemoteSource = MangaListsRemoteSourceImpl(source) init { "the data is null" { - mocker.every { source.getMediaCollection(MediaType.ANIME) } returns flowOf( + every { source.getMediaCollection(MediaType.ANIME) } returns flowOf( MediaCollection(emptyList()).right(), ) - mocker.every { source.getMediaCollection(MediaType.MANGA) } returns flowOf( + every { source.getMediaCollection(MediaType.MANGA) } returns flowOf( MediaCollection(emptyList()).right(), ) @@ -44,12 +43,10 @@ internal class ListsRemoteSourceTest : FreeSpec() { cancelAndIgnoreRemainingEvents() } - mocker.verify { + verify { source.getMediaCollection(MediaType.ANIME) source.getMediaCollection(MediaType.MANGA) } } } - - override fun extensions() = listOf(mocker()) } diff --git a/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/managers/UserIdManagerTest.kt b/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/managers/UserIdManagerTest.kt index e8715fc27..e07ec8b94 100644 --- a/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/managers/UserIdManagerTest.kt +++ b/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/managers/UserIdManagerTest.kt @@ -2,41 +2,37 @@ package dev.alvr.katana.data.remote.user.managers import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.usecases.invoke import dev.alvr.katana.domain.user.failures.UserFailure import dev.alvr.katana.domain.user.managers.UserIdManager import dev.alvr.katana.domain.user.models.UserId -import dev.alvr.katana.domain.user.repositories.MockUserRepository import dev.alvr.katana.domain.user.repositories.UserRepository import dev.alvr.katana.domain.user.usecases.GetUserIdUseCase +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(UserRepository::class) internal class UserIdManagerTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockUserRepository(mocker) + private val repo = mock() private val useCase = GetUserIdUseCase(repo) private val manager: UserIdManager = UserIdManagerImpl(useCase) init { "server return viewer is valid" { - mocker.everySuspending { repo.getUserId() } returns UserId(37_384).right() + everySuspend { repo.getUserId() } returns UserId(37_384).right() manager.getId().shouldBeRight(37_384) - mocker.verifyWithSuspend { useCase() } + verifySuspend { useCase() } } "server fails to return something" { - mocker.everySuspending { repo.getUserId() } returns UserFailure.GettingUserId.left() + everySuspend { repo.getUserId() } returns UserFailure.GettingUserId.left() manager.getId().shouldBeLeft(UserFailure.GettingUserId) - mocker.verifyWithSuspend { useCase() } + verifySuspend { useCase() } } } - - override fun extensions() = listOf(mocker()) } diff --git a/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/mocks.kt b/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/mocks.kt new file mode 100644 index 000000000..d60759427 --- /dev/null +++ b/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/mocks.kt @@ -0,0 +1,8 @@ +package dev.alvr.katana.data.remote.user + +import dev.alvr.katana.domain.user.models.UserId +import io.kotest.property.Arb +import io.kotest.property.arbitrary.next +import io.kotest.property.arbitrary.positiveInt + +internal val userIdMock = UserId(Arb.positiveInt().next()) diff --git a/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/repositories/UserRepositoryTest.kt b/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/repositories/UserRepositoryTest.kt index d96b30765..2963f7760 100644 --- a/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/repositories/UserRepositoryTest.kt +++ b/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/repositories/UserRepositoryTest.kt @@ -3,38 +3,27 @@ package dev.alvr.katana.data.remote.user.repositories import app.cash.turbine.test import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight -import dev.alvr.katana.data.remote.user.sources.id.MockUserIdRemoteSource import dev.alvr.katana.data.remote.user.sources.id.UserIdRemoteSource -import dev.alvr.katana.data.remote.user.sources.info.MockUserInfoRemoteSource import dev.alvr.katana.data.remote.user.sources.info.UserInfoRemoteSource +import dev.alvr.katana.data.remote.user.userIdMock import dev.alvr.katana.domain.base.failures.Failure import dev.alvr.katana.domain.user.failures.UserFailure -import dev.alvr.katana.domain.user.models.UserId -import dev.alvr.katana.domain.user.models.UserInfo -import dev.alvr.katana.domain.user.models.fakeUserId import dev.alvr.katana.domain.user.repositories.UserRepository +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verify +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.emptyFlow -import org.kodein.mock.Mocker -import org.kodein.mock.UsesFakes -import org.kodein.mock.UsesMocks -@UsesFakes( - UserId::class, - UserInfo::class, -) -@UsesMocks( - UserIdRemoteSource::class, - UserInfoRemoteSource::class, -) internal class UserRepositoryTest : FreeSpec() { - private val mocker = Mocker() - private val userIdSource = MockUserIdRemoteSource(mocker) - private val userInfoSource = MockUserInfoRemoteSource(mocker) + private val userIdSource = mock() + private val userInfoSource = mock() private val repo: UserRepository = UserRepositoryImpl(userIdSource, userInfoSource) @@ -42,23 +31,23 @@ internal class UserRepositoryTest : FreeSpec() { "userId" - { "getting the user id" - { "the server returns no data" { - mocker.everySuspending { userIdSource.getUserId() } returns fakeUserId().right() - repo.getUserId().shouldBeRight(fakeUserId()) - mocker.verifyWithSuspend { userIdSource.getUserId() } + everySuspend { userIdSource.getUserId() } returns userIdMock.right() + repo.getUserId().shouldBeRight(userIdMock) + verifySuspend { userIdSource.getUserId() } } "the server returns an empty userId" { - mocker.everySuspending { userIdSource.getUserId() } returns UserFailure.GettingUserId.left() + everySuspend { userIdSource.getUserId() } returns UserFailure.GettingUserId.left() repo.getUserId().shouldBeLeft(UserFailure.GettingUserId) - mocker.verifyWithSuspend { userIdSource.getUserId() } + verifySuspend { userIdSource.getUserId() } } } "saving the user id" - { "is successful" { - mocker.everySuspending { userIdSource.saveUserId() } returns Unit.right() + everySuspend { userIdSource.saveUserId() } returns Unit.right() repo.saveUserId().shouldBeRight() - mocker.verifyWithSuspend { userIdSource.saveUserId() } + verifySuspend { userIdSource.saveUserId() } } listOf( @@ -67,9 +56,9 @@ internal class UserRepositoryTest : FreeSpec() { Failure.Unknown to Failure.Unknown.left(), ).forEach { (expected, failure) -> "failure getting the user id ($expected)" { - mocker.everySuspending { userIdSource.saveUserId() } returns failure + everySuspend { userIdSource.saveUserId() } returns failure repo.saveUserId().shouldBeLeft(expected) - mocker.verifyWithSuspend { userIdSource.saveUserId() } + verifySuspend { userIdSource.saveUserId() } } } } @@ -78,13 +67,11 @@ internal class UserRepositoryTest : FreeSpec() { "userInfo" - { "observing userInfo" - { "the server returns no data" { - mocker.every { userInfoSource.userInfo } returns emptyFlow() + every { userInfoSource.userInfo } returns emptyFlow() repo.userInfo.test(5.seconds) { awaitComplete() } - mocker.verify { userInfoSource.userInfo } + verify { userInfoSource.userInfo } } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/sources/info/UserInfoRemoteSourceTest.kt b/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/sources/info/UserInfoRemoteSourceTest.kt index 602645cc4..14c6b4610 100644 --- a/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/sources/info/UserInfoRemoteSourceTest.kt +++ b/data/remote/user/src/commonTest/kotlin/dev/alvr/katana/data/remote/user/sources/info/UserInfoRemoteSourceTest.kt @@ -3,7 +3,6 @@ package dev.alvr.katana.data.remote.user.sources.info import app.cash.turbine.test import com.apollographql.apollo3.ApolloClient import com.apollographql.apollo3.annotations.ApolloExperimental -import com.apollographql.apollo3.api.Error import com.apollographql.apollo3.testing.MapTestNetworkTransport import com.apollographql.apollo3.testing.registerTestNetworkError import com.apollographql.apollo3.testing.registerTestResponse @@ -17,9 +16,7 @@ import dev.alvr.katana.domain.user.failures.UserFailure import dev.alvr.katana.domain.user.models.UserInfo import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds -import org.kodein.mock.UsesFakes -@UsesFakes(Error::class) @OptIn(ApolloExperimental::class) internal class UserInfoRemoteSourceTest : FreeSpec() { private val client = ApolloClient.Builder().networkTransport(MapTestNetworkTransport()).build() diff --git a/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/mocks.kt b/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/mocks.kt new file mode 100644 index 000000000..5a8826e7b --- /dev/null +++ b/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/mocks.kt @@ -0,0 +1,27 @@ +package dev.alvr.katana.domain.lists + +import dev.alvr.katana.domain.lists.models.lists.MediaList +import io.kotest.property.Arb +import io.kotest.property.arbitrary.boolean +import io.kotest.property.arbitrary.double +import io.kotest.property.arbitrary.int +import io.kotest.property.arbitrary.next +import io.kotest.property.arbitrary.string +import korlibs.time.Date +import korlibs.time.DateTime +import korlibs.time.DateTimeTz +import korlibs.time.TimezoneOffset + +internal val mediaListMock = MediaList( + id = Arb.int().next(), + score = Arb.double().next(), + progress = Arb.int().next(), + progressVolumes = Arb.int().next(), + repeat = Arb.int().next(), + private = Arb.boolean().next(), + notes = Arb.string().next(), + hiddenFromStatusLists = Arb.boolean().next(), + startedAt = Date(2022, 1, 1), + completedAt = Date(2022, 12, 31), + updatedAt = DateTimeTz.local(DateTime(2022, 12, 31, 23, 59, 59), TimezoneOffset.UTC), +) diff --git a/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/ObserveAnimeListUseCaseTest.kt b/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/ObserveAnimeListUseCaseTest.kt index 4017e2eac..b693bf0ba 100644 --- a/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/ObserveAnimeListUseCaseTest.kt +++ b/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/ObserveAnimeListUseCaseTest.kt @@ -3,7 +3,6 @@ package dev.alvr.katana.domain.lists.usecases import app.cash.turbine.test import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.usecases.invoke @@ -11,23 +10,22 @@ import dev.alvr.katana.domain.lists.failures.ListsFailure import dev.alvr.katana.domain.lists.models.MediaCollection import dev.alvr.katana.domain.lists.models.entries.MediaEntry import dev.alvr.katana.domain.lists.repositories.ListsRepository -import dev.alvr.katana.domain.lists.repositories.MockListsRepository +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(ListsRepository::class) internal class ObserveAnimeListUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockListsRepository(mocker) + private val repo = mock() private val useCase = ObserveAnimeListUseCase(repo) init { "successfully observe the anime lists" { - mocker.every { repo.animeCollection } returns flowOf( + every { repo.animeCollection } returns flowOf( MediaCollection(emptyList()).right(), ) @@ -38,11 +36,11 @@ internal class ObserveAnimeListUseCaseTest : FreeSpec() { cancelAndConsumeRemainingEvents() } - mocker.verify { repo.animeCollection } + verify { repo.animeCollection } } "failure observe the anime lists" { - mocker.every { repo.animeCollection } returns flowOf( + every { repo.animeCollection } returns flowOf( ListsFailure.GetMediaCollection.left(), ) @@ -53,9 +51,7 @@ internal class ObserveAnimeListUseCaseTest : FreeSpec() { cancelAndConsumeRemainingEvents() } - mocker.verify { repo.animeCollection } + verify { repo.animeCollection } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/ObserveMangaListUseCaseTest.kt b/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/ObserveMangaListUseCaseTest.kt index 7a57e863f..98713e0b6 100644 --- a/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/ObserveMangaListUseCaseTest.kt +++ b/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/ObserveMangaListUseCaseTest.kt @@ -3,7 +3,6 @@ package dev.alvr.katana.domain.lists.usecases import app.cash.turbine.test import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.usecases.invoke @@ -11,23 +10,22 @@ import dev.alvr.katana.domain.lists.failures.ListsFailure import dev.alvr.katana.domain.lists.models.MediaCollection import dev.alvr.katana.domain.lists.models.entries.MediaEntry import dev.alvr.katana.domain.lists.repositories.ListsRepository -import dev.alvr.katana.domain.lists.repositories.MockListsRepository +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(ListsRepository::class) internal class ObserveMangaListUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockListsRepository(mocker) + private val repo = mock() private val useCase = ObserveMangaListUseCase(repo) init { "successfully observe the manga lists" { - mocker.every { repo.mangaCollection } returns flowOf( + every { repo.mangaCollection } returns flowOf( MediaCollection(emptyList()).right(), ) @@ -38,11 +36,11 @@ internal class ObserveMangaListUseCaseTest : FreeSpec() { cancelAndConsumeRemainingEvents() } - mocker.verify { repo.mangaCollection } + verify { repo.mangaCollection } } "failure observe the manga lists" { - mocker.every { repo.mangaCollection } returns flowOf( + every { repo.mangaCollection } returns flowOf( ListsFailure.GetMediaCollection.left(), ) @@ -53,9 +51,7 @@ internal class ObserveMangaListUseCaseTest : FreeSpec() { cancelAndConsumeRemainingEvents() } - mocker.verify { repo.mangaCollection } + verify { repo.mangaCollection } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/UpdateListUseCaseTest.kt b/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/UpdateListUseCaseTest.kt index e3a8fe7eb..ba6726150 100644 --- a/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/UpdateListUseCaseTest.kt +++ b/domain/lists/src/commonTest/kotlin/dev/alvr/katana/domain/lists/usecases/UpdateListUseCaseTest.kt @@ -2,33 +2,29 @@ package dev.alvr.katana.domain.lists.usecases import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.failures.Failure import dev.alvr.katana.domain.lists.failures.ListsFailure -import dev.alvr.katana.domain.lists.models.lists.MediaList -import dev.alvr.katana.domain.lists.models.lists.fakeMediaList +import dev.alvr.katana.domain.lists.mediaListMock import dev.alvr.katana.domain.lists.repositories.ListsRepository -import dev.alvr.katana.domain.lists.repositories.MockListsRepository +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.matcher.any +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec -import org.kodein.mock.Mocker -import org.kodein.mock.UsesFakes -import org.kodein.mock.UsesMocks -@UsesFakes(MediaList::class) -@UsesMocks(ListsRepository::class) internal class UpdateListUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockListsRepository(mocker) + private val repo = mock() private val useCase = UpdateListUseCase(repo) init { "successfully updating the list" { - mocker.everySuspending { repo.updateList(isAny()) } returns Unit.right() - useCase(fakeMediaList()).shouldBeRight(Unit) - mocker.verifyWithSuspend { repo.updateList(fakeMediaList()) } + everySuspend { repo.updateList(any()) } returns Unit.right() + useCase(mediaListMock).shouldBeRight(Unit) + verifySuspend { repo.updateList(mediaListMock) } } listOf( @@ -36,12 +32,10 @@ internal class UpdateListUseCaseTest : FreeSpec() { Failure.Unknown to Failure.Unknown.left(), ).forEach { (expected, failure) -> "failure updating the list ($expected)" { - mocker.everySuspending { repo.updateList(isAny()) } returns failure - useCase(fakeMediaList()).shouldBeLeft(expected) - mocker.verifyWithSuspend { repo.updateList(fakeMediaList()) } + everySuspend { repo.updateList(any()) } returns failure + useCase(mediaListMock).shouldBeLeft(expected) + verifySuspend { repo.updateList(mediaListMock) } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/mocks.kt b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/mocks.kt index 331d5777d..95ae9bc7e 100644 --- a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/mocks.kt +++ b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/mocks.kt @@ -2,4 +2,4 @@ package dev.alvr.katana.domain.session import dev.alvr.katana.domain.session.models.AnilistToken -internal val anilistToken = AnilistToken("TOKEN") +internal val anilistTokenMock = AnilistToken("TOKEN") diff --git a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/ClearActiveSessionUseCaseTest.kt b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/ClearActiveSessionUseCaseTest.kt index b1288ca31..7a6b48d79 100644 --- a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/ClearActiveSessionUseCaseTest.kt +++ b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/ClearActiveSessionUseCaseTest.kt @@ -2,30 +2,28 @@ package dev.alvr.katana.domain.session.usecases import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.failures.Failure import dev.alvr.katana.domain.base.usecases.invoke import dev.alvr.katana.domain.session.failures.SessionFailure -import dev.alvr.katana.domain.session.repositories.MockSessionRepository import dev.alvr.katana.domain.session.repositories.SessionRepository +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(SessionRepository::class) internal class ClearActiveSessionUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockSessionRepository(mocker) + private val repo = mock() private val useCase = ClearActiveSessionUseCase(repo) init { "successfully clearing the session" { - mocker.everySuspending { repo.clearActiveSession() } returns Unit.right() + everySuspend { repo.clearActiveSession() } returns Unit.right() useCase().shouldBeRight(Unit) - mocker.verifyWithSuspend { repo.clearActiveSession() } + verifySuspend { repo.clearActiveSession() } } listOf( @@ -33,12 +31,10 @@ internal class ClearActiveSessionUseCaseTest : FreeSpec() { Failure.Unknown to Failure.Unknown.left(), ).forEach { (expected, failure) -> "failure clearing the session ($expected)" { - mocker.everySuspending { repo.clearActiveSession() } returns failure + everySuspend { repo.clearActiveSession() } returns failure useCase().shouldBeLeft(expected) - mocker.verifyWithSuspend { repo.clearActiveSession() } + verifySuspend { repo.clearActiveSession() } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/DeleteAnilistTokenUseCaseTest.kt b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/DeleteAnilistTokenUseCaseTest.kt index 38d905140..0fd235256 100644 --- a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/DeleteAnilistTokenUseCaseTest.kt +++ b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/DeleteAnilistTokenUseCaseTest.kt @@ -2,30 +2,28 @@ package dev.alvr.katana.domain.session.usecases import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.failures.Failure import dev.alvr.katana.domain.base.usecases.invoke import dev.alvr.katana.domain.session.failures.SessionFailure -import dev.alvr.katana.domain.session.repositories.MockSessionRepository import dev.alvr.katana.domain.session.repositories.SessionRepository +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(SessionRepository::class) internal class DeleteAnilistTokenUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockSessionRepository(mocker) + private val repo = mock() private val useCase = DeleteAnilistTokenUseCase(repo) init { "successfully deleting the token" { - mocker.everySuspending { repo.deleteAnilistToken() } returns Unit.right() + everySuspend { repo.deleteAnilistToken() } returns Unit.right() useCase().shouldBeRight(Unit) - mocker.verifyWithSuspend { repo.deleteAnilistToken() } + verifySuspend { repo.deleteAnilistToken() } } listOf( @@ -33,12 +31,10 @@ internal class DeleteAnilistTokenUseCaseTest : FreeSpec() { Failure.Unknown to Failure.Unknown.left(), ).forEach { (expected, failure) -> "failure deleting the token ($expected)" { - mocker.everySuspending { repo.deleteAnilistToken() } returns failure + everySuspend { repo.deleteAnilistToken() } returns failure useCase().shouldBeLeft(expected) - mocker.verifyWithSuspend { repo.deleteAnilistToken() } + verifySuspend { repo.deleteAnilistToken() } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/GetAnilistTokenUseCaseTest.kt b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/GetAnilistTokenUseCaseTest.kt index 93b2831b1..1182dfeb6 100644 --- a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/GetAnilistTokenUseCaseTest.kt +++ b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/GetAnilistTokenUseCaseTest.kt @@ -2,37 +2,33 @@ package dev.alvr.katana.domain.session.usecases import arrow.core.none import arrow.core.some -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeNone import dev.alvr.katana.common.tests.shouldBeSome import dev.alvr.katana.domain.base.usecases.invoke -import dev.alvr.katana.domain.session.anilistToken -import dev.alvr.katana.domain.session.repositories.MockSessionRepository +import dev.alvr.katana.domain.session.anilistTokenMock import dev.alvr.katana.domain.session.repositories.SessionRepository +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(SessionRepository::class) internal class GetAnilistTokenUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockSessionRepository(mocker) + private val repo = mock() private val useCase = GetAnilistTokenUseCase(repo) init { "successfully getting the token" { - mocker.everySuspending { repo.getAnilistToken() } returns anilistToken.some() - useCase().shouldBeSome(anilistToken) - mocker.verifyWithSuspend { repo.getAnilistToken() } + everySuspend { repo.getAnilistToken() } returns anilistTokenMock.some() + useCase().shouldBeSome(anilistTokenMock) + verifySuspend { repo.getAnilistToken() } } "failure getting the token" { - mocker.everySuspending { repo.getAnilistToken() } returns none() + everySuspend { repo.getAnilistToken() } returns none() useCase().shouldBeNone() - mocker.verifyWithSuspend { repo.getAnilistToken() } + verifySuspend { repo.getAnilistToken() } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/LogOutUseCaseTest.kt b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/LogOutUseCaseTest.kt index ab4ed48a2..5a72fa794 100644 --- a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/LogOutUseCaseTest.kt +++ b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/LogOutUseCaseTest.kt @@ -2,30 +2,28 @@ package dev.alvr.katana.domain.session.usecases import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.failures.Failure import dev.alvr.katana.domain.base.usecases.invoke import dev.alvr.katana.domain.session.failures.SessionFailure -import dev.alvr.katana.domain.session.repositories.MockSessionRepository import dev.alvr.katana.domain.session.repositories.SessionRepository +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(SessionRepository::class) internal class LogOutUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockSessionRepository(mocker) + private val repo = mock() private val useCase = LogOutUseCase(repo) init { "successfully saving the session" { - mocker.everySuspending { repo.logout() } returns Unit.right() + everySuspend { repo.logout() } returns Unit.right() useCase().shouldBeRight(Unit) - mocker.verifyWithSuspend { repo.logout() } + verifySuspend { repo.logout() } } listOf( @@ -33,12 +31,10 @@ internal class LogOutUseCaseTest : FreeSpec() { Failure.Unknown to Failure.Unknown.left(), ).forEach { (expected, failure) -> "failure saving the session ($expected)" { - mocker.everySuspending { repo.logout() } returns failure + everySuspend { repo.logout() } returns failure useCase().shouldBeLeft(expected) - mocker.verifyWithSuspend { repo.logout() } + verifySuspend { repo.logout() } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/ObserveActiveSessionUseCaseTest.kt b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/ObserveActiveSessionUseCaseTest.kt index e300e7a70..80adefb45 100644 --- a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/ObserveActiveSessionUseCaseTest.kt +++ b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/ObserveActiveSessionUseCaseTest.kt @@ -3,29 +3,27 @@ package dev.alvr.katana.domain.session.usecases import app.cash.turbine.test import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.usecases.invoke import dev.alvr.katana.domain.session.failures.SessionFailure -import dev.alvr.katana.domain.session.repositories.MockSessionRepository import dev.alvr.katana.domain.session.repositories.SessionRepository +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(SessionRepository::class) internal class ObserveActiveSessionUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockSessionRepository(mocker) + private val repo = mock() private val useCase = ObserveActiveSessionUseCase(repo) init { "successfully observing the session" { - mocker.every { repo.sessionActive } returns flowOf( + every { repo.sessionActive } returns flowOf( false.right(), true.right(), false.right(), @@ -45,11 +43,11 @@ internal class ObserveActiveSessionUseCaseTest : FreeSpec() { cancelAndConsumeRemainingEvents() } - mocker.verify { repo.sessionActive } + verify { repo.sessionActive } } "failure observing the session" { - mocker.every { repo.sessionActive } returns flowOf(SessionFailure.CheckingActiveSession.left()) + every { repo.sessionActive } returns flowOf(SessionFailure.CheckingActiveSession.left()) useCase() @@ -58,9 +56,7 @@ internal class ObserveActiveSessionUseCaseTest : FreeSpec() { cancelAndConsumeRemainingEvents() } - mocker.verify { repo.sessionActive } + verify { repo.sessionActive } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/SaveAnilistTokenUseCaseTest.kt b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/SaveAnilistTokenUseCaseTest.kt index 496ffe828..15ba810a2 100644 --- a/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/SaveAnilistTokenUseCaseTest.kt +++ b/domain/session/src/commonTest/kotlin/dev/alvr/katana/domain/session/usecases/SaveAnilistTokenUseCaseTest.kt @@ -2,30 +2,28 @@ package dev.alvr.katana.domain.session.usecases import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.failures.Failure -import dev.alvr.katana.domain.session.anilistToken +import dev.alvr.katana.domain.session.anilistTokenMock import dev.alvr.katana.domain.session.failures.SessionFailure -import dev.alvr.katana.domain.session.repositories.MockSessionRepository import dev.alvr.katana.domain.session.repositories.SessionRepository +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(SessionRepository::class) internal class SaveAnilistTokenUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockSessionRepository(mocker) + private val repo = mock() private val useCase = SaveSessionUseCase(repo) init { "successfully saving the session" { - mocker.everySuspending { repo.saveSession(isAny()) } returns Unit.right() - useCase(anilistToken).shouldBeRight(Unit) - mocker.verifyWithSuspend { repo.saveSession(anilistToken) } + everySuspend { repo.saveSession(anilistTokenMock) } returns Unit.right() + useCase(anilistTokenMock).shouldBeRight(Unit) + verifySuspend { repo.saveSession(anilistTokenMock) } } listOf( @@ -33,12 +31,10 @@ internal class SaveAnilistTokenUseCaseTest : FreeSpec() { Failure.Unknown to Failure.Unknown.left(), ).forEach { (expected, failure) -> "failure saving the session ($expected)" { - mocker.everySuspending { repo.saveSession(isAny()) } returns failure - useCase(anilistToken).shouldBeLeft(expected) - mocker.verifyWithSuspend { repo.saveSession(anilistToken) } + everySuspend { repo.saveSession(anilistTokenMock) } returns failure + useCase(anilistTokenMock).shouldBeLeft(expected) + verifySuspend { repo.saveSession(anilistTokenMock) } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/mocks.kt b/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/mocks.kt new file mode 100644 index 000000000..a38b5bf2c --- /dev/null +++ b/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/mocks.kt @@ -0,0 +1,16 @@ +package dev.alvr.katana.domain.user + +import dev.alvr.katana.domain.user.models.UserId +import dev.alvr.katana.domain.user.models.UserInfo +import io.kotest.property.Arb +import io.kotest.property.arbitrary.int +import io.kotest.property.arbitrary.next +import io.kotest.property.arbitrary.string + +internal val userIdMock = UserId(Arb.int().next()) + +internal val userInfoMock = UserInfo( + username = Arb.string().next(), + avatar = Arb.string().next(), + banner = Arb.string().next(), +) diff --git a/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/GetUserIdUseCaseTest.kt b/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/GetUserIdUseCaseTest.kt index 5230ee167..2848301fb 100644 --- a/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/GetUserIdUseCaseTest.kt +++ b/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/GetUserIdUseCaseTest.kt @@ -2,34 +2,29 @@ package dev.alvr.katana.domain.user.usecases import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.failures.Failure import dev.alvr.katana.domain.base.usecases.invoke import dev.alvr.katana.domain.user.failures.UserFailure -import dev.alvr.katana.domain.user.models.UserId -import dev.alvr.katana.domain.user.models.fakeUserId -import dev.alvr.katana.domain.user.repositories.MockUserRepository import dev.alvr.katana.domain.user.repositories.UserRepository +import dev.alvr.katana.domain.user.userIdMock +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec -import org.kodein.mock.Mocker -import org.kodein.mock.UsesFakes -import org.kodein.mock.UsesMocks -@UsesFakes(UserId::class) -@UsesMocks(UserRepository::class) internal class GetUserIdUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockUserRepository(mocker) + private val repo = mock() private val useCase = GetUserIdUseCase(repo) init { "successfully getting user id" { - mocker.everySuspending { repo.getUserId() } returns fakeUserId().right() - useCase().shouldBeRight(fakeUserId()) - mocker.verifyWithSuspend { repo.getUserId() } + everySuspend { repo.getUserId() } returns userIdMock.right() + useCase().shouldBeRight(userIdMock) + verifySuspend { repo.getUserId() } } listOf( @@ -37,12 +32,10 @@ internal class GetUserIdUseCaseTest : FreeSpec() { Failure.Unknown to Failure.Unknown.left(), ).forEach { (expected, failure) -> "failure getting user id ($expected)" { - mocker.everySuspending { repo.getUserId() } returns failure + everySuspend { repo.getUserId() } returns failure useCase().shouldBeLeft(expected) - mocker.verifyWithSuspend { repo.getUserId() } + verifySuspend { repo.getUserId() } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/ObserveUserInfoUseCaseTest.kt b/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/ObserveUserInfoUseCaseTest.kt index 9d74ea754..33b3ecbf4 100644 --- a/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/ObserveUserInfoUseCaseTest.kt +++ b/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/ObserveUserInfoUseCaseTest.kt @@ -3,46 +3,41 @@ package dev.alvr.katana.domain.user.usecases import app.cash.turbine.test import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.usecases.invoke import dev.alvr.katana.domain.user.failures.UserFailure -import dev.alvr.katana.domain.user.models.UserInfo -import dev.alvr.katana.domain.user.models.fakeUserInfo -import dev.alvr.katana.domain.user.repositories.MockUserRepository import dev.alvr.katana.domain.user.repositories.UserRepository +import dev.alvr.katana.domain.user.userInfoMock +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify import io.kotest.core.spec.style.FreeSpec import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.flow.flowOf -import org.kodein.mock.Mocker -import org.kodein.mock.UsesFakes -import org.kodein.mock.UsesMocks -@UsesFakes(UserInfo::class) -@UsesMocks(UserRepository::class) internal class ObserveUserInfoUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockUserRepository(mocker) + private val repo = mock() private val useCase = ObserveUserInfoUseCase(repo) init { "successfully observing user info" { - mocker.every { repo.userInfo } returns flowOf(fakeUserInfo().right()) + every { repo.userInfo } returns flowOf(userInfoMock.right()) useCase() useCase.flow.test(5.seconds) { - awaitItem().shouldBeRight(fakeUserInfo()) + awaitItem().shouldBeRight(userInfoMock) cancelAndConsumeRemainingEvents() } - mocker.verify { repo.userInfo } + verify { repo.userInfo } } "failure observe user info" { - mocker.every { repo.userInfo } returns flowOf(UserFailure.GettingUserInfo.left()) + every { repo.userInfo } returns flowOf(UserFailure.GettingUserInfo.left()) useCase() @@ -51,9 +46,7 @@ internal class ObserveUserInfoUseCaseTest : FreeSpec() { cancelAndConsumeRemainingEvents() } - mocker.verify { repo.userInfo } + verify { repo.userInfo } } } - - override fun extensions() = listOf(mocker()) } diff --git a/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/SaveUserIdUseCaseTest.kt b/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/SaveUserIdUseCaseTest.kt index 53085e6e5..a1cd21b23 100644 --- a/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/SaveUserIdUseCaseTest.kt +++ b/domain/user/src/commonTest/kotlin/dev/alvr/katana/domain/user/usecases/SaveUserIdUseCaseTest.kt @@ -2,30 +2,28 @@ package dev.alvr.katana.domain.user.usecases import arrow.core.left import arrow.core.right -import dev.alvr.katana.common.tests.invoke import dev.alvr.katana.common.tests.shouldBeLeft import dev.alvr.katana.common.tests.shouldBeRight import dev.alvr.katana.domain.base.failures.Failure import dev.alvr.katana.domain.base.usecases.invoke import dev.alvr.katana.domain.user.failures.UserFailure -import dev.alvr.katana.domain.user.repositories.MockUserRepository import dev.alvr.katana.domain.user.repositories.UserRepository +import dev.mokkery.answering.returns +import dev.mokkery.everySuspend +import dev.mokkery.mock +import dev.mokkery.verifySuspend import io.kotest.core.spec.style.FreeSpec -import org.kodein.mock.Mocker -import org.kodein.mock.UsesMocks -@UsesMocks(UserRepository::class) internal class SaveUserIdUseCaseTest : FreeSpec() { - private val mocker = Mocker() - private val repo = MockUserRepository(mocker) + private val repo = mock() private val useCase = SaveUserIdUseCase(repo) init { "successfully saving user id" { - mocker.everySuspending { repo.saveUserId() } returns Unit.right() + everySuspend { repo.saveUserId() } returns Unit.right() useCase().shouldBeRight(Unit) - mocker.verifyWithSuspend { repo.saveUserId() } + verifySuspend { repo.saveUserId() } } listOf( @@ -34,12 +32,10 @@ internal class SaveUserIdUseCaseTest : FreeSpec() { Failure.Unknown to Failure.Unknown.left(), ).forEach { (expected, failure) -> "failure saving user id ($expected)" { - mocker.everySuspending { repo.saveUserId() } returns failure + everySuspend { repo.saveUserId() } returns failure useCase().shouldBeLeft(expected) - mocker.verifyWithSuspend { repo.saveUserId() } + verifySuspend { repo.saveUserId() } } } } - - override fun extensions() = listOf(mocker()) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6bfa3a731..ba2810d8e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -31,7 +31,7 @@ lifecycle = "2.7.0" lyricist = "1.6.2-1.8.20" materialkolor = "1.4.0" mockk = "1.13.10" -mockmp = "1.17.0" +mokkery = "1.9.22-1.4.0" okio = "3.8.0" orbit = "6.1.0" parcelable = "1.3.0" @@ -58,7 +58,7 @@ kotest = { id = "io.kotest.multiplatform", version.ref = "kotest" } kotlin = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } -mockmp = { id = "org.kodein.mock.mockmp", version.ref = "mockmp" } +mokkery = { id = "dev.mokkery", version.ref = "mokkery" } parcelize = { id = "com.arkivanov.parcelize.darwin", version.ref = "parcelize" } sentry = { id = "io.sentry.android.gradle", version.ref = "sentry-plugin" } serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } @@ -106,7 +106,7 @@ gradle-kotest = { module = "io.kotest:kotest-framework-multiplatform-plugin-grad gradle-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } gradle-kover = { module = "org.jetbrains.kotlinx:kover-gradle-plugin", version.ref = "kover" } gradle-ksp = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin", version.ref = "ksp" } -gradle-mockmp = { module = "org.kodein.mock:mockmp-gradle-plugin", version.ref = "mockmp" } +gradle-mokkery = { module = "dev.mokkery:mokkery-gradle", version.ref = "mokkery" } gradle-sentry = { module = "io.sentry:sentry-android-gradle-plugin", version.ref = "sentry-plugin" } # Kamel @@ -181,9 +181,6 @@ kotest-property = { module = "io.kotest:kotest-property", version.ref = "kotest" ## MockK mockk = { module = "io.mockk:mockk", version.ref = "mockk" } -## MocKMP -mockmp = { module = "org.kodein.mock:mockmp-runtime", version.ref = "mockmp" } - ## Turbine turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" }