From 7e9bfa8d5e3674f7ab601fddd57f594e6c88c8df Mon Sep 17 00:00:00 2001 From: Petrus Nguyen Thai Hoc Date: Sat, 6 Nov 2021 01:23:46 +0700 Subject: [PATCH 1/6] wip --- .idea/gradle.xml | 4 +- .../java/com/hoc/flowmvi/core/CoreModule.kt | 2 +- .../com/hoc/flowmvi/core/NavigatorImpl.kt | 4 +- buildSrc/src/main/kotlin/deps.kt | 2 + core-ui/.gitignore | 1 + core-ui/build.gradle.kts | 55 +++++++++++++ {core => core-ui}/consumer-rules.pro | 0 {core => core-ui}/proguard-rules.pro | 0 .../core_ui/ExampleInstrumentedTest.kt | 1 + core-ui/src/main/AndroidManifest.xml | 5 ++ .../com/hoc/flowmvi/core_ui}/CollectIn.kt | 2 +- .../com/hoc/flowmvi/core_ui}/FlowBinding.kt | 2 +- .../core_ui}/SwipeLeftToDeleteCallback.kt | 2 +- .../flowmvi/core_ui}/navigator/Navigator.kt | 2 +- .../drawable/ic_baseline_delete_white_24.xml | 0 .../hoc/flowmvi/core_ui/ExampleUnitTest.kt | 1 + core/build.gradle.kts | 49 +----------- .../flowmvi/core/ExampleInstrumentedTest.kt | 1 - core/src/main/AndroidManifest.xml | 13 --- core/src/main/res/font/noto_sans.xml | 7 -- core/src/main/res/values/colors.xml | 6 -- core/src/main/res/values/font_certs.xml | 17 ---- core/src/main/res/values/preloaded_fonts.xml | 6 -- core/src/main/res/values/strings.xml | 3 - core/src/main/res/values/styles.xml | 11 --- data/build.gradle.kts | 3 +- .../flowmvi/data/UserRepositoryImplTest.kt | 37 +++------ feature-add/build.gradle.kts | 2 +- .../com/hoc/flowmvi/ui/add/AddActivity.kt | 3 +- .../java/com/hoc/flowmvi/ui/add/AddModule.kt | 2 +- feature-main/build.gradle.kts | 2 +- .../com/hoc/flowmvi/ui/main/MainActivity.kt | 2 +- feature-search/build.gradle.kts | 2 +- .../hoc/flowmvi/ui/search/SearchActivity.kt | 6 +- .../com/hoc/flowmvi/ui/search/SearchModule.kt | 2 +- mvi/mvi-base/build.gradle.kts | 2 +- .../flowmvi/mvi_base/AbstractMviActivity.kt | 2 +- mvi/mvi-testing/build.gradle.kts | 1 + .../mvi_testing/BaseMviViewModelTest.kt | 80 ++++++++++++------- settings.gradle.kts | 2 + test-utils/.gitignore | 1 + test-utils/build.gradle.kts | 10 +++ .../test_utils/TestCoroutineDispatcherRule.kt | 24 ++++++ .../hoc/flowmvi/test_utils/TestDispatchers.kt | 13 +++ 44 files changed, 201 insertions(+), 191 deletions(-) create mode 100644 core-ui/.gitignore create mode 100644 core-ui/build.gradle.kts rename {core => core-ui}/consumer-rules.pro (100%) rename {core => core-ui}/proguard-rules.pro (100%) create mode 100644 core-ui/src/androidTest/java/com/hoc/flowmvi/core_ui/ExampleInstrumentedTest.kt create mode 100644 core-ui/src/main/AndroidManifest.xml rename {core/src/main/java/com/hoc/flowmvi/core => core-ui/src/main/java/com/hoc/flowmvi/core_ui}/CollectIn.kt (97%) rename {core/src/main/java/com/hoc/flowmvi/core => core-ui/src/main/java/com/hoc/flowmvi/core_ui}/FlowBinding.kt (99%) rename {core/src/main/java/com/hoc/flowmvi/core => core-ui/src/main/java/com/hoc/flowmvi/core_ui}/SwipeLeftToDeleteCallback.kt (98%) rename {core/src/main/java/com/hoc/flowmvi/core => core-ui/src/main/java/com/hoc/flowmvi/core_ui}/navigator/Navigator.kt (88%) rename {core => core-ui}/src/main/res/drawable/ic_baseline_delete_white_24.xml (100%) create mode 100644 core-ui/src/test/java/com/hoc/flowmvi/core_ui/ExampleUnitTest.kt delete mode 100644 core/src/androidTest/java/com/hoc/flowmvi/core/ExampleInstrumentedTest.kt delete mode 100644 core/src/main/AndroidManifest.xml delete mode 100644 core/src/main/res/font/noto_sans.xml delete mode 100644 core/src/main/res/values/colors.xml delete mode 100644 core/src/main/res/values/font_certs.xml delete mode 100644 core/src/main/res/values/preloaded_fonts.xml delete mode 100644 core/src/main/res/values/strings.xml delete mode 100644 core/src/main/res/values/styles.xml create mode 100644 test-utils/.gitignore create mode 100644 test-utils/build.gradle.kts create mode 100644 test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestCoroutineDispatcherRule.kt create mode 100644 test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestDispatchers.kt diff --git a/.idea/gradle.xml b/.idea/gradle.xml index ce97a058..b9c4f02c 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -14,6 +14,7 @@ - \ No newline at end of file + diff --git a/app/src/main/java/com/hoc/flowmvi/core/CoreModule.kt b/app/src/main/java/com/hoc/flowmvi/core/CoreModule.kt index 088c9ac8..bacf7866 100644 --- a/app/src/main/java/com/hoc/flowmvi/core/CoreModule.kt +++ b/app/src/main/java/com/hoc/flowmvi/core/CoreModule.kt @@ -1,7 +1,7 @@ package com.hoc.flowmvi.core import com.hoc.flowmvi.core.dispatchers.CoroutineDispatchers -import com.hoc.flowmvi.core.navigator.Navigator +import com.hoc.flowmvi.core_ui.navigator.Navigator import org.koin.dsl.module val coreModule = module { diff --git a/app/src/main/java/com/hoc/flowmvi/core/NavigatorImpl.kt b/app/src/main/java/com/hoc/flowmvi/core/NavigatorImpl.kt index 130f6c2d..0bfd900e 100644 --- a/app/src/main/java/com/hoc/flowmvi/core/NavigatorImpl.kt +++ b/app/src/main/java/com/hoc/flowmvi/core/NavigatorImpl.kt @@ -1,8 +1,8 @@ package com.hoc.flowmvi.core import android.content.Context -import com.hoc.flowmvi.core.navigator.IntentProviders -import com.hoc.flowmvi.core.navigator.Navigator +import com.hoc.flowmvi.core_ui.navigator.IntentProviders +import com.hoc.flowmvi.core_ui.navigator.Navigator class NavigatorImpl( private val add: IntentProviders.Add, diff --git a/buildSrc/src/main/kotlin/deps.kt b/buildSrc/src/main/kotlin/deps.kt index 1cbfc9cf..5381ef7c 100644 --- a/buildSrc/src/main/kotlin/deps.kt +++ b/buildSrc/src/main/kotlin/deps.kt @@ -97,12 +97,14 @@ inline val PDsS.kotlinKapt: PDS get() = id("kotlin-kapt") inline val DependencyHandler.domain get() = project(":domain") inline val DependencyHandler.core get() = project(":core") +inline val DependencyHandler.coreUi get() = project(":core-ui") inline val DependencyHandler.data get() = project(":data") inline val DependencyHandler.featureMain get() = project(":feature-main") inline val DependencyHandler.featureAdd get() = project(":feature-add") inline val DependencyHandler.featureSearch get() = project(":feature-search") inline val DependencyHandler.mviBase get() = project(":mvi-base") inline val DependencyHandler.mviTesting get() = project(":mvi-testing") +inline val DependencyHandler.testUtils get() = project(":test-utils") fun DependencyHandler.addUnitTest(testImplementation: Boolean = true) { val configName = if (testImplementation) "testImplementation" else "implementation" diff --git a/core-ui/.gitignore b/core-ui/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/core-ui/.gitignore @@ -0,0 +1 @@ +/build diff --git a/core-ui/build.gradle.kts b/core-ui/build.gradle.kts new file mode 100644 index 00000000..019ff854 --- /dev/null +++ b/core-ui/build.gradle.kts @@ -0,0 +1,55 @@ +plugins { + androidLib + kotlinAndroid +} + +android { + compileSdk = appConfig.compileSdkVersion + buildToolsVersion = appConfig.buildToolsVersion + + defaultConfig { + minSdk = appConfig.minSdkVersion + targetSdk = appConfig.targetSdkVersion + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles("consumer-rules.pro") + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + kotlinOptions { jvmTarget = JavaVersion.VERSION_1_8.toString() } + + testOptions { + unitTests.isIncludeAndroidResources = true + unitTests.isReturnDefaultValues = true + } +} + +dependencies { + implementation(deps.coroutines.core) + implementation(deps.coroutines.android) + + implementation(deps.androidx.coreKtx) + implementation(deps.androidx.swipeRefreshLayout) + implementation(deps.androidx.recyclerView) + implementation(deps.androidx.material) + + implementation(deps.lifecycle.commonJava8) + implementation(deps.lifecycle.runtimeKtx) + + implementation(deps.timber) + + addUnitTest() +} diff --git a/core/consumer-rules.pro b/core-ui/consumer-rules.pro similarity index 100% rename from core/consumer-rules.pro rename to core-ui/consumer-rules.pro diff --git a/core/proguard-rules.pro b/core-ui/proguard-rules.pro similarity index 100% rename from core/proguard-rules.pro rename to core-ui/proguard-rules.pro diff --git a/core-ui/src/androidTest/java/com/hoc/flowmvi/core_ui/ExampleInstrumentedTest.kt b/core-ui/src/androidTest/java/com/hoc/flowmvi/core_ui/ExampleInstrumentedTest.kt new file mode 100644 index 00000000..bd932593 --- /dev/null +++ b/core-ui/src/androidTest/java/com/hoc/flowmvi/core_ui/ExampleInstrumentedTest.kt @@ -0,0 +1 @@ +package com.hoc.flowmvi.core_ui diff --git a/core-ui/src/main/AndroidManifest.xml b/core-ui/src/main/AndroidManifest.xml new file mode 100644 index 00000000..22f7d521 --- /dev/null +++ b/core-ui/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + diff --git a/core/src/main/java/com/hoc/flowmvi/core/CollectIn.kt b/core-ui/src/main/java/com/hoc/flowmvi/core_ui/CollectIn.kt similarity index 97% rename from core/src/main/java/com/hoc/flowmvi/core/CollectIn.kt rename to core-ui/src/main/java/com/hoc/flowmvi/core_ui/CollectIn.kt index c80ff5fe..669e251d 100644 --- a/core/src/main/java/com/hoc/flowmvi/core/CollectIn.kt +++ b/core-ui/src/main/java/com/hoc/flowmvi/core_ui/CollectIn.kt @@ -1,4 +1,4 @@ -package com.hoc.flowmvi.core +package com.hoc.flowmvi.core_ui import androidx.fragment.app.Fragment import androidx.lifecycle.Lifecycle diff --git a/core/src/main/java/com/hoc/flowmvi/core/FlowBinding.kt b/core-ui/src/main/java/com/hoc/flowmvi/core_ui/FlowBinding.kt similarity index 99% rename from core/src/main/java/com/hoc/flowmvi/core/FlowBinding.kt rename to core-ui/src/main/java/com/hoc/flowmvi/core_ui/FlowBinding.kt index 29528fb0..73d57c17 100644 --- a/core/src/main/java/com/hoc/flowmvi/core/FlowBinding.kt +++ b/core-ui/src/main/java/com/hoc/flowmvi/core_ui/FlowBinding.kt @@ -1,4 +1,4 @@ -package com.hoc.flowmvi.core +package com.hoc.flowmvi.core_ui import android.content.Context import android.os.Looper diff --git a/core/src/main/java/com/hoc/flowmvi/core/SwipeLeftToDeleteCallback.kt b/core-ui/src/main/java/com/hoc/flowmvi/core_ui/SwipeLeftToDeleteCallback.kt similarity index 98% rename from core/src/main/java/com/hoc/flowmvi/core/SwipeLeftToDeleteCallback.kt rename to core-ui/src/main/java/com/hoc/flowmvi/core_ui/SwipeLeftToDeleteCallback.kt index 9c68ce9f..71ae822e 100644 --- a/core/src/main/java/com/hoc/flowmvi/core/SwipeLeftToDeleteCallback.kt +++ b/core-ui/src/main/java/com/hoc/flowmvi/core_ui/SwipeLeftToDeleteCallback.kt @@ -1,4 +1,4 @@ -package com.hoc.flowmvi.core +package com.hoc.flowmvi.core_ui import android.content.Context import android.graphics.Canvas diff --git a/core/src/main/java/com/hoc/flowmvi/core/navigator/Navigator.kt b/core-ui/src/main/java/com/hoc/flowmvi/core_ui/navigator/Navigator.kt similarity index 88% rename from core/src/main/java/com/hoc/flowmvi/core/navigator/Navigator.kt rename to core-ui/src/main/java/com/hoc/flowmvi/core_ui/navigator/Navigator.kt index 4749440c..d0a6b1db 100644 --- a/core/src/main/java/com/hoc/flowmvi/core/navigator/Navigator.kt +++ b/core-ui/src/main/java/com/hoc/flowmvi/core_ui/navigator/Navigator.kt @@ -1,4 +1,4 @@ -package com.hoc.flowmvi.core.navigator +package com.hoc.flowmvi.core_ui.navigator import android.content.Context import android.content.Intent diff --git a/core/src/main/res/drawable/ic_baseline_delete_white_24.xml b/core-ui/src/main/res/drawable/ic_baseline_delete_white_24.xml similarity index 100% rename from core/src/main/res/drawable/ic_baseline_delete_white_24.xml rename to core-ui/src/main/res/drawable/ic_baseline_delete_white_24.xml diff --git a/core-ui/src/test/java/com/hoc/flowmvi/core_ui/ExampleUnitTest.kt b/core-ui/src/test/java/com/hoc/flowmvi/core_ui/ExampleUnitTest.kt new file mode 100644 index 00000000..bd932593 --- /dev/null +++ b/core-ui/src/test/java/com/hoc/flowmvi/core_ui/ExampleUnitTest.kt @@ -0,0 +1 @@ +package com.hoc.flowmvi.core_ui diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 351e1704..cf13ffe4 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,55 +1,8 @@ plugins { - androidLib - kotlinAndroid -} - -android { - compileSdk = appConfig.compileSdkVersion - buildToolsVersion = appConfig.buildToolsVersion - - defaultConfig { - minSdk = appConfig.minSdkVersion - targetSdk = appConfig.targetSdkVersion - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = true - proguardFiles( - getDefaultProguardFile("proguard-android-optimize.txt"), - "proguard-rules.pro" - ) - } - } - - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { jvmTarget = JavaVersion.VERSION_1_8.toString() } - - testOptions { - unitTests.isIncludeAndroidResources = true - unitTests.isReturnDefaultValues = true - } + kotlin } dependencies { implementation(deps.coroutines.core) - implementation(deps.coroutines.android) - - implementation(deps.androidx.coreKtx) - implementation(deps.androidx.swipeRefreshLayout) - implementation(deps.androidx.recyclerView) - implementation(deps.androidx.material) - - implementation(deps.lifecycle.commonJava8) - implementation(deps.lifecycle.runtimeKtx) - - implementation(deps.timber) - addUnitTest() } diff --git a/core/src/androidTest/java/com/hoc/flowmvi/core/ExampleInstrumentedTest.kt b/core/src/androidTest/java/com/hoc/flowmvi/core/ExampleInstrumentedTest.kt deleted file mode 100644 index dc6f3377..00000000 --- a/core/src/androidTest/java/com/hoc/flowmvi/core/ExampleInstrumentedTest.kt +++ /dev/null @@ -1 +0,0 @@ -package com.hoc.flowmvi.core diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml deleted file mode 100644 index baf271f3..00000000 --- a/core/src/main/AndroidManifest.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - diff --git a/core/src/main/res/font/noto_sans.xml b/core/src/main/res/font/noto_sans.xml deleted file mode 100644 index 6cbfda08..00000000 --- a/core/src/main/res/font/noto_sans.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - diff --git a/core/src/main/res/values/colors.xml b/core/src/main/res/values/colors.xml deleted file mode 100644 index 030098fe..00000000 --- a/core/src/main/res/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - #6200EE - #3700B3 - #03DAC5 - diff --git a/core/src/main/res/values/font_certs.xml b/core/src/main/res/values/font_certs.xml deleted file mode 100644 index d2226ac0..00000000 --- a/core/src/main/res/values/font_certs.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - @array/com_google_android_gms_fonts_certs_dev - @array/com_google_android_gms_fonts_certs_prod - - - - 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 - - - diff --git a/core/src/main/res/values/preloaded_fonts.xml b/core/src/main/res/values/preloaded_fonts.xml deleted file mode 100644 index cb9caba3..00000000 --- a/core/src/main/res/values/preloaded_fonts.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - @font/noto_sans - - diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml deleted file mode 100644 index 32bfe8a8..00000000 --- a/core/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - MVI Coroutines Flow - diff --git a/core/src/main/res/values/styles.xml b/core/src/main/res/values/styles.xml deleted file mode 100644 index 1c56072b..00000000 --- a/core/src/main/res/values/styles.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 412a1f59..7bcd2199 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -18,7 +18,7 @@ android { buildTypes { release { - isMinifyEnabled = true + isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" @@ -55,4 +55,5 @@ dependencies { implementation(deps.timber) addUnitTest() + testImplementation(testUtils) } diff --git a/data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplTest.kt b/data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplTest.kt index eb0d8e05..d10a9b59 100644 --- a/data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplTest.kt +++ b/data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplTest.kt @@ -4,12 +4,13 @@ import arrow.core.Either import arrow.core.getOrHandle import arrow.core.identity import com.hoc.flowmvi.core.Mapper -import com.hoc.flowmvi.core.dispatchers.CoroutineDispatchers import com.hoc.flowmvi.data.remote.UserApiService import com.hoc.flowmvi.data.remote.UserBody import com.hoc.flowmvi.data.remote.UserResponse import com.hoc.flowmvi.domain.entity.User import com.hoc.flowmvi.domain.repository.UserError +import com.hoc.flowmvi.test_utils.TestCoroutineDispatcherRule +import com.hoc.flowmvi.test_utils.TestDispatchers import io.mockk.clearAllMocks import io.mockk.coEvery import io.mockk.coVerify @@ -19,17 +20,6 @@ import io.mockk.every import io.mockk.mockk import io.mockk.verify import io.mockk.verifySequence -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.CoroutineStart -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.launch -import kotlinx.coroutines.test.TestCoroutineDispatcher -import kotlinx.coroutines.test.resetMain -import kotlinx.coroutines.test.runBlockingTest -import kotlinx.coroutines.test.setMain import java.io.IOException import kotlin.test.AfterTest import kotlin.test.BeforeTest @@ -40,6 +30,13 @@ import kotlin.test.assertNotNull import kotlin.test.assertNull import kotlin.test.assertTrue import kotlin.time.ExperimentalTime +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runBlockingTest +import org.junit.Rule private val USER_BODY = UserBody( email = "email1@gmail.com", @@ -95,16 +92,13 @@ private val USERS = listOf( ), ) -@ExperimentalCoroutinesApi -class TestDispatchersImpl(testDispatcher: TestCoroutineDispatcher) : CoroutineDispatchers { - override val main: CoroutineDispatcher = testDispatcher - override val io: CoroutineDispatcher = testDispatcher -} @ExperimentalCoroutinesApi @ExperimentalTime class UserRepositoryImplTest { - private val testDispatcher = TestCoroutineDispatcher() + @get:Rule + val coroutineRule = TestCoroutineDispatcherRule() + private val testDispatcher get() = coroutineRule.testCoroutineDispatcher private lateinit var repo: UserRepositoryImpl private lateinit var userApiService: UserApiService @@ -114,8 +108,6 @@ class UserRepositoryImplTest { @BeforeTest fun setup() { - Dispatchers.setMain(testDispatcher) - userApiService = mockk() responseToDomain = mockk() domainToBody = mockk() @@ -123,7 +115,7 @@ class UserRepositoryImplTest { repo = UserRepositoryImpl( userApiService = userApiService, - dispatchers = TestDispatchersImpl(testDispatcher), + dispatchers = TestDispatchers(coroutineRule.testCoroutineDispatcher), responseToDomain = responseToDomain, domainToBody = domainToBody, errorMapper = errorMapper @@ -132,9 +124,6 @@ class UserRepositoryImplTest { @AfterTest fun tearDown() { - testDispatcher.cleanupTestCoroutines() - Dispatchers.resetMain() - confirmVerified( userApiService, responseToDomain, diff --git a/feature-add/build.gradle.kts b/feature-add/build.gradle.kts index b55d001e..8aa3fbae 100644 --- a/feature-add/build.gradle.kts +++ b/feature-add/build.gradle.kts @@ -17,7 +17,7 @@ android { buildTypes { release { - isMinifyEnabled = true + isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" diff --git a/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt b/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt index e59f17b8..8bbb239d 100644 --- a/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt +++ b/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt @@ -8,7 +8,7 @@ import androidx.transition.AutoTransition import androidx.transition.TransitionManager import com.hoc.flowmvi.core.clicks import com.hoc.flowmvi.core.firstChange -import com.hoc.flowmvi.core.navigator.IntentProviders +import com.hoc.flowmvi.core_ui.navigator.IntentProviders import com.hoc.flowmvi.core.textChanges import com.hoc.flowmvi.core.toast import com.hoc.flowmvi.mvi_base.AbstractMviActivity @@ -17,7 +17,6 @@ import com.hoc081098.flowext.mapTo import com.hoc081098.viewbindingdelegate.viewBinding import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import org.koin.androidx.viewmodel.ext.android.viewModel import timber.log.Timber diff --git a/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddModule.kt b/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddModule.kt index 227df3f6..ca1f178d 100644 --- a/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddModule.kt +++ b/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddModule.kt @@ -1,6 +1,6 @@ package com.hoc.flowmvi.ui.add -import com.hoc.flowmvi.core.navigator.IntentProviders +import com.hoc.flowmvi.core_ui.navigator.IntentProviders import kotlinx.coroutines.ExperimentalCoroutinesApi import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.dsl.module diff --git a/feature-main/build.gradle.kts b/feature-main/build.gradle.kts index 2532aed4..e46f9c3d 100644 --- a/feature-main/build.gradle.kts +++ b/feature-main/build.gradle.kts @@ -17,7 +17,7 @@ android { buildTypes { release { - isMinifyEnabled = true + isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" diff --git a/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt b/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt index a48bd93f..cce3d960 100644 --- a/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt +++ b/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt @@ -9,7 +9,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.hoc.flowmvi.core.SwipeLeftToDeleteCallback import com.hoc.flowmvi.core.clicks -import com.hoc.flowmvi.core.navigator.Navigator +import com.hoc.flowmvi.core_ui.navigator.Navigator import com.hoc.flowmvi.core.refreshes import com.hoc.flowmvi.core.toast import com.hoc.flowmvi.domain.repository.UserError diff --git a/feature-search/build.gradle.kts b/feature-search/build.gradle.kts index 0b0b5c7e..76064969 100644 --- a/feature-search/build.gradle.kts +++ b/feature-search/build.gradle.kts @@ -18,7 +18,7 @@ android { buildTypes { release { - isMinifyEnabled = true + isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" diff --git a/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchActivity.kt b/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchActivity.kt index e0908242..b067296a 100644 --- a/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchActivity.kt +++ b/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchActivity.kt @@ -12,7 +12,7 @@ import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager import com.hoc.flowmvi.core.SearchViewQueryTextEvent import com.hoc.flowmvi.core.clicks -import com.hoc.flowmvi.core.navigator.IntentProviders +import com.hoc.flowmvi.core_ui.navigator.IntentProviders import com.hoc.flowmvi.core.queryTextEvents import com.hoc.flowmvi.core.toast import com.hoc.flowmvi.domain.repository.UserError @@ -23,11 +23,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.consumeAsFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge -import kotlinx.coroutines.flow.onEach import org.koin.androidx.viewmodel.ext.android.viewModel import timber.log.Timber import kotlin.time.ExperimentalTime diff --git a/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchModule.kt b/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchModule.kt index 38b1c6d7..64895147 100644 --- a/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchModule.kt +++ b/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchModule.kt @@ -1,6 +1,6 @@ package com.hoc.flowmvi.ui.search -import com.hoc.flowmvi.core.navigator.IntentProviders +import com.hoc.flowmvi.core_ui.navigator.IntentProviders import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import org.koin.androidx.viewmodel.dsl.viewModel diff --git a/mvi/mvi-base/build.gradle.kts b/mvi/mvi-base/build.gradle.kts index 8773f946..220af562 100644 --- a/mvi/mvi-base/build.gradle.kts +++ b/mvi/mvi-base/build.gradle.kts @@ -37,7 +37,7 @@ dependencies { implementation(deps.lifecycle.runtimeKtx) implementation(deps.coroutines.core) - implementation(core) + implementation(coreUi) implementation(deps.timber) addUnitTest() diff --git a/mvi/mvi-base/src/main/java/com/hoc/flowmvi/mvi_base/AbstractMviActivity.kt b/mvi/mvi-base/src/main/java/com/hoc/flowmvi/mvi_base/AbstractMviActivity.kt index cbb29495..3ccbe35a 100644 --- a/mvi/mvi-base/src/main/java/com/hoc/flowmvi/mvi_base/AbstractMviActivity.kt +++ b/mvi/mvi-base/src/main/java/com/hoc/flowmvi/mvi_base/AbstractMviActivity.kt @@ -5,7 +5,7 @@ import androidx.annotation.CallSuper import androidx.annotation.LayoutRes import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.lifecycleScope -import com.hoc.flowmvi.core.collectIn +import com.hoc.flowmvi.core_ui.collectIn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach diff --git a/mvi/mvi-testing/build.gradle.kts b/mvi/mvi-testing/build.gradle.kts index 870df1a5..9cc63eda 100644 --- a/mvi/mvi-testing/build.gradle.kts +++ b/mvi/mvi-testing/build.gradle.kts @@ -36,6 +36,7 @@ dependencies { implementation(deps.coroutines.core) implementation(mviBase) + implementation(testUtils) implementation(deps.timber) addUnitTest(testImplementation = false) diff --git a/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt b/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt index a31f0b28..8a328f6d 100644 --- a/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt +++ b/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt @@ -1,29 +1,28 @@ package com.flowmvi.mvi_testing import androidx.annotation.CallSuper +import arrow.core.Either +import arrow.core.right import com.hoc.flowmvi.mvi_base.MviIntent import com.hoc.flowmvi.mvi_base.MviSingleEvent import com.hoc.flowmvi.mvi_base.MviViewModel import com.hoc.flowmvi.mvi_base.MviViewState +import com.hoc.flowmvi.test_utils.TestCoroutineDispatcherRule import io.mockk.clearAllMocks +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.assertEquals +import kotlin.time.Duration +import kotlin.time.ExperimentalTime import kotlinx.coroutines.CoroutineStart -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch -import kotlinx.coroutines.test.TestCoroutineDispatcher -import kotlinx.coroutines.test.resetMain import kotlinx.coroutines.test.runBlockingTest -import kotlinx.coroutines.test.setMain -import kotlin.test.AfterTest -import kotlin.test.BeforeTest -import kotlin.test.assertContentEquals -import kotlin.test.assertEquals -import kotlin.time.Duration -import kotlin.time.ExperimentalTime +import org.junit.Rule @ExperimentalTime @ExperimentalCoroutinesApi @@ -33,19 +32,27 @@ abstract class BaseMviViewModelTest< E : MviSingleEvent, VM : MviViewModel, > { - private val testDispatcher = TestCoroutineDispatcher() + @get:Rule + val coroutineRule = TestCoroutineDispatcherRule() + + protected val testDispatcher get() = coroutineRule.testCoroutineDispatcher @CallSuper @BeforeTest open fun setup() { - Dispatchers.setMain(testDispatcher) + } + + @CallSuper + @AfterTest + open fun tearDown() { + clearAllMocks() } protected fun test( vmProducer: () -> VM, intents: Flow, - expectedStates: List, - expectedEvents: List, + expectedStates: List Unit, S>>, + expectedEvents: List Unit, E>>, delayAfterDispatchingIntents: Duration = Duration.ZERO, logging: Boolean = true, intentsBeforeCollecting: Flow? = null, @@ -69,29 +76,40 @@ abstract class BaseMviViewModelTest< } assertEquals(expectedStates.size, states.size, "States size") - assertContentEquals( - expectedStates, - states, - "States content" - ) + expectedStates.withIndex().zip(states).forEach { (indexedValue, state) -> + val (index, exp) = indexedValue + exp.fold( + ifRight = { + assertEquals( + expected = it, + actual = state, + message = "[State index=$index]" + ) + }, + ifLeft = { it(state) } + ) + } assertEquals(expectedEvents.size, events.size, "Events size") - assertContentEquals( - expectedEvents, - events, - "Evens content", - ) + expectedEvents.withIndex().zip(events).forEach { (indexedValue, event) -> + val (index, exp) = indexedValue + exp.fold( + ifRight = { + assertEquals( + expected = it, + actual = event, + message = "[Event index=$index]" + ) + }, + ifLeft = { it(event) } + ) + } otherAssertions?.invoke() stateJob.cancel() eventJob.cancel() } - @CallSuper - @AfterTest - open fun tearDown() { - Dispatchers.resetMain() - testDispatcher.cleanupTestCoroutines() - clearAllMocks() - } } + +fun Iterable.mapRight(): List Unit, T>> = map { it.right() } diff --git a/settings.gradle.kts b/settings.gradle.kts index b7dfdfed..cf8a3884 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,6 +7,8 @@ include(":feature-search") include(":domain") include(":data") include(":core") +include(":core-ui") +include(":test-utils") includeProject(":mvi-base", "mvi/mvi-base") includeProject(":mvi-testing", "mvi/mvi-testing") diff --git a/test-utils/.gitignore b/test-utils/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/test-utils/.gitignore @@ -0,0 +1 @@ +/build diff --git a/test-utils/build.gradle.kts b/test-utils/build.gradle.kts new file mode 100644 index 00000000..bef2a2c2 --- /dev/null +++ b/test-utils/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + kotlin +} + +dependencies { + implementation(deps.coroutines.core) + implementation(core) + + addUnitTest(testImplementation = false) +} diff --git a/test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestCoroutineDispatcherRule.kt b/test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestCoroutineDispatcherRule.kt new file mode 100644 index 00000000..6e6c5eec --- /dev/null +++ b/test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestCoroutineDispatcherRule.kt @@ -0,0 +1,24 @@ +package com.hoc.flowmvi.test_utils + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestCoroutineDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import org.junit.rules.TestWatcher +import org.junit.runner.Description + +@ExperimentalCoroutinesApi +class TestCoroutineDispatcherRule(val testCoroutineDispatcher: TestCoroutineDispatcher = TestCoroutineDispatcher()) : + TestWatcher() { + override fun starting(description: Description) { + Dispatchers.setMain(testCoroutineDispatcher) + println("$this::starting $description") + } + + override fun finished(description: Description) { + Dispatchers.resetMain() + testCoroutineDispatcher.cleanupTestCoroutines() + println("$this::finished $description") + } +} diff --git a/test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestDispatchers.kt b/test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestDispatchers.kt new file mode 100644 index 00000000..5faa6744 --- /dev/null +++ b/test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestDispatchers.kt @@ -0,0 +1,13 @@ +package com.hoc.flowmvi.test_utils + +import com.hoc.flowmvi.core.dispatchers.CoroutineDispatchers +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestCoroutineDispatcher + +@ExperimentalCoroutinesApi +class TestDispatchers(testCoroutineDispatcher: TestCoroutineDispatcher) : + CoroutineDispatchers { + override val main: CoroutineDispatcher = testCoroutineDispatcher + override val io: CoroutineDispatcher = testCoroutineDispatcher +} From 754dbb899d3b55a406548f04168b738f4345de9c Mon Sep 17 00:00:00 2001 From: Petrus Nguyen Thai Hoc Date: Sat, 6 Nov 2021 01:32:27 +0700 Subject: [PATCH 2/6] format --- app/build.gradle.kts | 1 + .../hoc/flowmvi/data/UserRepositoryImplTest.kt | 15 +++++++-------- feature-add/build.gradle.kts | 1 + .../java/com/hoc/flowmvi/ui/add/AddActivity.kt | 9 +++++---- feature-main/build.gradle.kts | 1 + .../java/com/hoc/flowmvi/ui/main/MainActivity.kt | 8 ++++---- feature-search/build.gradle.kts | 1 + .../com/hoc/flowmvi/ui/search/SearchActivity.kt | 12 ++++++++---- .../flowmvi/mvi_testing/BaseMviViewModelTest.kt | 11 +++++------ 9 files changed, 33 insertions(+), 26 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f73e6abe..6d8e5bc6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -59,6 +59,7 @@ dependencies { implementation(domain) implementation(data) implementation(core) + implementation(coreUi) implementation(featureMain) implementation(featureAdd) implementation(featureSearch) diff --git a/data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplTest.kt b/data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplTest.kt index d10a9b59..18541457 100644 --- a/data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplTest.kt +++ b/data/src/test/java/com/hoc/flowmvi/data/UserRepositoryImplTest.kt @@ -20,6 +20,13 @@ import io.mockk.every import io.mockk.mockk import io.mockk.verify import io.mockk.verifySequence +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runBlockingTest +import org.junit.Rule import java.io.IOException import kotlin.test.AfterTest import kotlin.test.BeforeTest @@ -30,13 +37,6 @@ import kotlin.test.assertNotNull import kotlin.test.assertNull import kotlin.test.assertTrue import kotlin.time.ExperimentalTime -import kotlinx.coroutines.CoroutineStart -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.launch -import kotlinx.coroutines.test.runBlockingTest -import org.junit.Rule private val USER_BODY = UserBody( email = "email1@gmail.com", @@ -92,7 +92,6 @@ private val USERS = listOf( ), ) - @ExperimentalCoroutinesApi @ExperimentalTime class UserRepositoryImplTest { diff --git a/feature-add/build.gradle.kts b/feature-add/build.gradle.kts index 8aa3fbae..60e57890 100644 --- a/feature-add/build.gradle.kts +++ b/feature-add/build.gradle.kts @@ -41,6 +41,7 @@ android { dependencies { implementation(domain) implementation(core) + implementation(coreUi) implementation(mviBase) implementation(deps.androidx.appCompat) diff --git a/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt b/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt index 8bbb239d..90b18744 100644 --- a/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt +++ b/feature-add/src/main/java/com/hoc/flowmvi/ui/add/AddActivity.kt @@ -6,17 +6,18 @@ import android.view.MenuItem import androidx.core.view.isInvisible import androidx.transition.AutoTransition import androidx.transition.TransitionManager -import com.hoc.flowmvi.core.clicks -import com.hoc.flowmvi.core.firstChange +import com.hoc.flowmvi.core_ui.clicks +import com.hoc.flowmvi.core_ui.firstChange import com.hoc.flowmvi.core_ui.navigator.IntentProviders -import com.hoc.flowmvi.core.textChanges -import com.hoc.flowmvi.core.toast +import com.hoc.flowmvi.core_ui.textChanges +import com.hoc.flowmvi.core_ui.toast import com.hoc.flowmvi.mvi_base.AbstractMviActivity import com.hoc.flowmvi.ui.add.databinding.ActivityAddBinding import com.hoc081098.flowext.mapTo import com.hoc081098.viewbindingdelegate.viewBinding import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import org.koin.androidx.viewmodel.ext.android.viewModel import timber.log.Timber diff --git a/feature-main/build.gradle.kts b/feature-main/build.gradle.kts index e46f9c3d..50614bc0 100644 --- a/feature-main/build.gradle.kts +++ b/feature-main/build.gradle.kts @@ -48,6 +48,7 @@ android { dependencies { implementation(domain) implementation(core) + implementation(coreUi) implementation(mviBase) implementation(deps.androidx.appCompat) diff --git a/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt b/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt index a49a4dfd..18e99ffa 100644 --- a/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt +++ b/feature-main/src/main/java/com/hoc/flowmvi/ui/main/MainActivity.kt @@ -7,11 +7,11 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import com.hoc.flowmvi.core.SwipeLeftToDeleteCallback -import com.hoc.flowmvi.core.clicks +import com.hoc.flowmvi.core_ui.SwipeLeftToDeleteCallback +import com.hoc.flowmvi.core_ui.clicks import com.hoc.flowmvi.core_ui.navigator.Navigator -import com.hoc.flowmvi.core.refreshes -import com.hoc.flowmvi.core.toast +import com.hoc.flowmvi.core_ui.refreshes +import com.hoc.flowmvi.core_ui.toast import com.hoc.flowmvi.domain.repository.UserError import com.hoc.flowmvi.mvi_base.AbstractMviActivity import com.hoc.flowmvi.ui.main.databinding.ActivityMainBinding diff --git a/feature-search/build.gradle.kts b/feature-search/build.gradle.kts index 76064969..fdd552b4 100644 --- a/feature-search/build.gradle.kts +++ b/feature-search/build.gradle.kts @@ -42,6 +42,7 @@ android { dependencies { implementation(domain) implementation(core) + implementation(coreUi) implementation(mviBase) implementation(deps.androidx.appCompat) diff --git a/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchActivity.kt b/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchActivity.kt index b067296a..8524cd48 100644 --- a/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchActivity.kt +++ b/feature-search/src/main/java/com/hoc/flowmvi/ui/search/SearchActivity.kt @@ -10,11 +10,11 @@ import androidx.core.view.isInvisible import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.GridLayoutManager -import com.hoc.flowmvi.core.SearchViewQueryTextEvent -import com.hoc.flowmvi.core.clicks +import com.hoc.flowmvi.core_ui.SearchViewQueryTextEvent +import com.hoc.flowmvi.core_ui.clicks import com.hoc.flowmvi.core_ui.navigator.IntentProviders -import com.hoc.flowmvi.core.queryTextEvents -import com.hoc.flowmvi.core.toast +import com.hoc.flowmvi.core_ui.queryTextEvents +import com.hoc.flowmvi.core_ui.toast import com.hoc.flowmvi.domain.repository.UserError import com.hoc.flowmvi.mvi_base.AbstractMviActivity import com.hoc.flowmvi.ui.search.databinding.ActivitySearchBinding @@ -23,7 +23,11 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.consumeAsFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onEach import org.koin.androidx.viewmodel.ext.android.viewModel import timber.log.Timber import kotlin.time.ExperimentalTime diff --git a/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt b/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt index 8a328f6d..7a4a75ff 100644 --- a/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt +++ b/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt @@ -9,11 +9,6 @@ import com.hoc.flowmvi.mvi_base.MviViewModel import com.hoc.flowmvi.mvi_base.MviViewState import com.hoc.flowmvi.test_utils.TestCoroutineDispatcherRule import io.mockk.clearAllMocks -import kotlin.test.AfterTest -import kotlin.test.BeforeTest -import kotlin.test.assertEquals -import kotlin.time.Duration -import kotlin.time.ExperimentalTime import kotlinx.coroutines.CoroutineStart import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay @@ -23,6 +18,11 @@ import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch import kotlinx.coroutines.test.runBlockingTest import org.junit.Rule +import kotlin.test.AfterTest +import kotlin.test.BeforeTest +import kotlin.test.assertEquals +import kotlin.time.Duration +import kotlin.time.ExperimentalTime @ExperimentalTime @ExperimentalCoroutinesApi @@ -109,7 +109,6 @@ abstract class BaseMviViewModelTest< stateJob.cancel() eventJob.cancel() } - } fun Iterable.mapRight(): List Unit, T>> = map { it.right() } From b348ebb5da91bab8b7898fd70cc59e0c0fee3acd Mon Sep 17 00:00:00 2001 From: Petrus Nguyen Thai Hoc Date: Sat, 6 Nov 2021 01:36:17 +0700 Subject: [PATCH 3/6] fix --- domain/build.gradle.kts | 1 + domain/src/test/java/com/hoc/flowmvi/domain/UseCaseTest.kt | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index 60b79fc4..a3d82c44 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -8,4 +8,5 @@ dependencies { implementation(deps.arrow.core) addUnitTest() + testImplementation(testUtils) } diff --git a/domain/src/test/java/com/hoc/flowmvi/domain/UseCaseTest.kt b/domain/src/test/java/com/hoc/flowmvi/domain/UseCaseTest.kt index f396b5b4..d35c840e 100644 --- a/domain/src/test/java/com/hoc/flowmvi/domain/UseCaseTest.kt +++ b/domain/src/test/java/com/hoc/flowmvi/domain/UseCaseTest.kt @@ -10,6 +10,7 @@ import com.hoc.flowmvi.domain.usecase.GetUsersUseCase import com.hoc.flowmvi.domain.usecase.RefreshGetUsersUseCase import com.hoc.flowmvi.domain.usecase.RemoveUserUseCase import com.hoc.flowmvi.domain.usecase.SearchUsersUseCase +import com.hoc.flowmvi.test_utils.TestCoroutineDispatcherRule import io.mockk.clearAllMocks import io.mockk.coEvery import io.mockk.coVerify @@ -20,8 +21,8 @@ import io.mockk.verify import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.runBlockingTest +import org.junit.Rule import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.Test @@ -53,7 +54,9 @@ private val USERS = listOf( @ExperimentalCoroutinesApi class UseCaseTest { - private val testDispatcher = TestCoroutineDispatcher() + @get:Rule + val coroutineRule = TestCoroutineDispatcherRule() + private val testDispatcher get() = coroutineRule.testCoroutineDispatcher private lateinit var userRepository: UserRepository private lateinit var getUsersUseCase: GetUsersUseCase From c2a99720bb1d357b1cdba21d9d93af4b68a5e8ce Mon Sep 17 00:00:00 2001 From: Petrus Nguyen Thai Hoc Date: Sat, 6 Nov 2021 01:41:52 +0700 Subject: [PATCH 4/6] fix res --- core-ui/src/main/AndroidManifest.xml | 10 +++++++++- core-ui/src/main/res/font/noto_sans.xml | 7 +++++++ core-ui/src/main/res/values/colors.xml | 6 ++++++ core-ui/src/main/res/values/font_certs.xml | 17 +++++++++++++++++ core-ui/src/main/res/values/preloaded_fonts.xml | 6 ++++++ core-ui/src/main/res/values/strings.xml | 3 +++ core-ui/src/main/res/values/styles.xml | 11 +++++++++++ 7 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 core-ui/src/main/res/font/noto_sans.xml create mode 100644 core-ui/src/main/res/values/colors.xml create mode 100644 core-ui/src/main/res/values/font_certs.xml create mode 100644 core-ui/src/main/res/values/preloaded_fonts.xml create mode 100644 core-ui/src/main/res/values/strings.xml create mode 100644 core-ui/src/main/res/values/styles.xml diff --git a/core-ui/src/main/AndroidManifest.xml b/core-ui/src/main/AndroidManifest.xml index 22f7d521..069f7323 100644 --- a/core-ui/src/main/AndroidManifest.xml +++ b/core-ui/src/main/AndroidManifest.xml @@ -1,5 +1,13 @@ + package="com.hoc.flowmvi.core_ui"> + + + + + + diff --git a/core-ui/src/main/res/font/noto_sans.xml b/core-ui/src/main/res/font/noto_sans.xml new file mode 100644 index 00000000..6cbfda08 --- /dev/null +++ b/core-ui/src/main/res/font/noto_sans.xml @@ -0,0 +1,7 @@ + + + diff --git a/core-ui/src/main/res/values/colors.xml b/core-ui/src/main/res/values/colors.xml new file mode 100644 index 00000000..030098fe --- /dev/null +++ b/core-ui/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #6200EE + #3700B3 + #03DAC5 + diff --git a/core-ui/src/main/res/values/font_certs.xml b/core-ui/src/main/res/values/font_certs.xml new file mode 100644 index 00000000..d2226ac0 --- /dev/null +++ b/core-ui/src/main/res/values/font_certs.xml @@ -0,0 +1,17 @@ + + + + @array/com_google_android_gms_fonts_certs_dev + @array/com_google_android_gms_fonts_certs_prod + + + + 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 + + + diff --git a/core-ui/src/main/res/values/preloaded_fonts.xml b/core-ui/src/main/res/values/preloaded_fonts.xml new file mode 100644 index 00000000..cb9caba3 --- /dev/null +++ b/core-ui/src/main/res/values/preloaded_fonts.xml @@ -0,0 +1,6 @@ + + + + @font/noto_sans + + diff --git a/core-ui/src/main/res/values/strings.xml b/core-ui/src/main/res/values/strings.xml new file mode 100644 index 00000000..32bfe8a8 --- /dev/null +++ b/core-ui/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + MVI Coroutines Flow + diff --git a/core-ui/src/main/res/values/styles.xml b/core-ui/src/main/res/values/styles.xml new file mode 100644 index 00000000..1c56072b --- /dev/null +++ b/core-ui/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + From fbe1635589449e468a2fd6278b14db2ced9b49c7 Mon Sep 17 00:00:00 2001 From: Petrus Nguyen Thai Hoc Date: Sat, 6 Nov 2021 01:44:37 +0700 Subject: [PATCH 5/6] fix res --- .idea/misc.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/.idea/misc.xml b/.idea/misc.xml index 076b3e47..74a53cfc 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -9,6 +9,7 @@ + From ecbc6b9d853bded115f096926e6eeb833c898de3 Mon Sep 17 00:00:00 2001 From: Petrus Nguyen Thai Hoc Date: Sat, 6 Nov 2021 16:32:35 +0700 Subject: [PATCH 6/6] update log tests --- .github/workflows/build.yml | 3 ++ .github/workflows/review-suggest.yml | 4 +++ .github/workflows/unit-test.yml | 3 ++ buildSrc/src/main/kotlin/deps.kt | 6 ++++ mvi/mvi-testing/build.gradle.kts | 16 +++++++++ .../mvi_testing/BaseMviViewModelTest.kt | 36 +++++++++++++++---- .../test_utils/TestCoroutineDispatcherRule.kt | 2 -- 7 files changed, 61 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ad1e48d7..2517d228 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [ master ] +env: + CI: true + jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/review-suggest.yml b/.github/workflows/review-suggest.yml index d06d0ddd..444bdfee 100644 --- a/.github/workflows/review-suggest.yml +++ b/.github/workflows/review-suggest.yml @@ -2,6 +2,10 @@ name: reviewdog-suggester on: pull_request: types: [opened, synchronize, reopened] + +env: + CI: true + jobs: kotlin: name: runner / suggester / spotless diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 9ad2da3b..1615b60c 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [ master ] +env: + CI: true + jobs: build: runs-on: ubuntu-latest diff --git a/buildSrc/src/main/kotlin/deps.kt b/buildSrc/src/main/kotlin/deps.kt index 5381ef7c..3e969885 100644 --- a/buildSrc/src/main/kotlin/deps.kt +++ b/buildSrc/src/main/kotlin/deps.kt @@ -1,5 +1,6 @@ @file:Suppress("unused", "ClassName", "SpellCheckingInspection") +import org.gradle.api.Project import org.gradle.api.artifacts.dsl.DependencyHandler import org.gradle.kotlin.dsl.project import org.gradle.plugin.use.PluginDependenciesSpec @@ -114,3 +115,8 @@ fun DependencyHandler.addUnitTest(testImplementation: Boolean = true) { add(configName, deps.test.kotlinJUnit) add(configName, deps.coroutines.test) } + +val Project.isCiBuild: Boolean + get() = providers.environmentVariable("CI") + .forUseAtConfigurationTime() + .orNull == "true" diff --git a/mvi/mvi-testing/build.gradle.kts b/mvi/mvi-testing/build.gradle.kts index 61681633..1c467baf 100644 --- a/mvi/mvi-testing/build.gradle.kts +++ b/mvi/mvi-testing/build.gradle.kts @@ -16,12 +16,28 @@ android { } buildTypes { + debug { + (!isCiBuild).let { + buildConfigField( + type = it::class.java.simpleName, + name = "ENABLE_LOG_TEST", + value = it.toString(), + ) + } + } release { isMinifyEnabled = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) + false.let { + buildConfigField( + type = it::class.java.simpleName, + name = "ENABLE_LOG_TEST", + value = it.toString(), + ) + } } } compileOptions { diff --git a/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt b/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt index 7a4a75ff..4dbb5fa1 100644 --- a/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt +++ b/mvi/mvi-testing/src/main/java/com/flowmvi/mvi_testing/BaseMviViewModelTest.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.onCompletion import kotlinx.coroutines.flow.toList import kotlinx.coroutines.launch import kotlinx.coroutines.test.runBlockingTest @@ -54,12 +55,21 @@ abstract class BaseMviViewModelTest< expectedStates: List Unit, S>>, expectedEvents: List Unit, E>>, delayAfterDispatchingIntents: Duration = Duration.ZERO, - logging: Boolean = true, + logging: Boolean = BuildConfig.ENABLE_LOG_TEST, intentsBeforeCollecting: Flow? = null, otherAssertions: (suspend () -> Unit)? = null, ) = testDispatcher.runBlockingTest { + fun logIfEnabled(s: () -> String) = if (logging) println(s()) else Unit + val vm = vmProducer() - intentsBeforeCollecting?.collect { vm.processIntent(it) } + intentsBeforeCollecting + ?.onCompletion { logIfEnabled { "---------------" } } + ?.collect { + vm.processIntent(it) + logIfEnabled { "[BEFORE] Dispatch $it -> $vm" } + } + + logIfEnabled { "[START] $vm" } val states = mutableListOf() val events = mutableListOf() @@ -67,13 +77,15 @@ abstract class BaseMviViewModelTest< val stateJob = launch(start = CoroutineStart.UNDISPATCHED) { vm.viewState.toList(states) } val eventJob = launch(start = CoroutineStart.UNDISPATCHED) { vm.singleEvent.toList(events) } - intents.collect { vm.processIntent(it) } + intents.collect { + vm.processIntent(it) + logIfEnabled { "[DISPATCH] Dispatch $it -> $vm" } + } delay(delayAfterDispatchingIntents) + logIfEnabled { "---------------" } - if (logging) { - println(states) - println(events) - } + logIfEnabled { "[DONE] states=${states.joinToStringWithIndex()}" } + logIfEnabled { "[DONE] events=${events.joinToStringWithIndex()}" } assertEquals(expectedStates.size, states.size, "States size") expectedStates.withIndex().zip(states).forEach { (indexedValue, state) -> @@ -112,3 +124,13 @@ abstract class BaseMviViewModelTest< } fun Iterable.mapRight(): List Unit, T>> = map { it.right() } + +private fun List.joinToStringWithIndex(): String { + return withIndex().joinToString( + separator = ",\n", + prefix = "[\n", + postfix = "]", + ) { (i, v) -> + " [$i]: $v" + } +} diff --git a/test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestCoroutineDispatcherRule.kt b/test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestCoroutineDispatcherRule.kt index 6e6c5eec..1b25e277 100644 --- a/test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestCoroutineDispatcherRule.kt +++ b/test-utils/src/main/java/com/hoc/flowmvi/test_utils/TestCoroutineDispatcherRule.kt @@ -13,12 +13,10 @@ class TestCoroutineDispatcherRule(val testCoroutineDispatcher: TestCoroutineDisp TestWatcher() { override fun starting(description: Description) { Dispatchers.setMain(testCoroutineDispatcher) - println("$this::starting $description") } override fun finished(description: Description) { Dispatchers.resetMain() testCoroutineDispatcher.cleanupTestCoroutines() - println("$this::finished $description") } }