diff --git a/.idea/androidTestResultsUserPreferences.xml b/.idea/androidTestResultsUserPreferences.xml index bf3909f..f9e941b 100644 --- a/.idea/androidTestResultsUserPreferences.xml +++ b/.idea/androidTestResultsUserPreferences.xml @@ -43,12 +43,26 @@ + + + + + + + + + + + + + + diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 89d88b2..fd0a259 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -6,7 +6,6 @@ plugins { alias(libs.plugins.compose.compiler) alias(libs.plugins.ksp) alias(libs.plugins.detekt) - alias(libs.plugins.hilt) alias(libs.plugins.google.secrets.gradle.plugin) alias(libs.plugins.automattic.measure.builds) } @@ -23,7 +22,7 @@ android { versionCode = extraString("version_code").toInt() versionName = extraString("version_name") - testInstrumentationRunner = "com.santimattius.template.CustomTestRunner" + testInstrumentationRunner = "com.santimattius.template.InstrumentationTestRunner" vectorDrawables { useSupportLibrary = true } @@ -71,6 +70,11 @@ android { excludes.add("/META-INF/{AL2.0,LGPL2.1}") } } + applicationVariants.forEach { variant -> + variant.sourceSets.forEach { + it.javaDirectories += files("build/generated/ksp/${variant.name}/kotlin") + } + } } composeCompiler { @@ -105,6 +109,10 @@ measureBuilds { } } +ksp { + arg("KOIN_CONFIG_CHECK","true") +} + dependencies { implementation(project(":core")) implementation(libs.kotlin.stdlib) @@ -112,6 +120,8 @@ dependencies { implementation(libs.bundles.ui) implementation(libs.bundles.lifecycle) + implementation(libs.activity.compose) + testImplementation(libs.lifecycle.viewmodel.testing) implementation(libs.room.ktx) @@ -119,6 +129,7 @@ dependencies { //Compose implementation(platform(libs.compose.bom)) implementation(libs.bundles.compose) + androidTestImplementation(project(":app")) debugImplementation(libs.bundles.compose.debug) testImplementation(platform(libs.compose.bom)) @@ -131,19 +142,25 @@ dependencies { implementation(libs.glide.core) implementation(libs.coil.core) - //Hilt - implementation(libs.hilt.android) - implementation(libs.hilt.navigation.compose) - ksp(libs.hilt.compiler) - ksp(libs.androidx.hilt.compiler) + //Koin + implementation(platform(libs.koin.bom)) + implementation(libs.koin.android) + implementation(libs.koin.androidx.compose) + implementation(libs.koin.androidx.startup) + + compileOnly(libs.koin.annotations.core) + ksp(libs.koin.annotations.compiler) + + testImplementation(libs.koin.annotations.core) + kspTest(libs.koin.annotations.compiler) - // For Robolectric tests. - testImplementation(libs.hilt.test) - kspTest(libs.hilt.android.compiler) + testImplementation(libs.koin.test.core) + testImplementation(libs.koin.test.junit4) - // For instrumented tests. - androidTestImplementation(libs.hilt.test) - kspAndroidTest(libs.hilt.android.compiler) + androidTestImplementation(libs.koin.test.junit4) + androidTestImplementation(libs.koin.android.test) + androidTestImplementation(libs.koin.annotations.core) + kspAndroidTest(libs.koin.annotations.compiler) //Unit Testing testImplementation(project(path = ":shared-test")) @@ -154,6 +171,7 @@ dependencies { //Android Testing debugImplementation(libs.androidx.fragment.testing.manifest) + implementation(libs.androidx.fragment.testing) androidTestImplementation(libs.junit) androidTestImplementation(libs.androidx.core.ktx) diff --git a/app/src/androidTest/java/com/santimattius/template/CustomTestRunner.kt b/app/src/androidTest/java/com/santimattius/template/InstrumentationTestRunner.kt similarity index 54% rename from app/src/androidTest/java/com/santimattius/template/CustomTestRunner.kt rename to app/src/androidTest/java/com/santimattius/template/InstrumentationTestRunner.kt index 89d0626..5a78db1 100644 --- a/app/src/androidTest/java/com/santimattius/template/CustomTestRunner.kt +++ b/app/src/androidTest/java/com/santimattius/template/InstrumentationTestRunner.kt @@ -3,15 +3,13 @@ package com.santimattius.template import android.app.Application import android.content.Context import androidx.test.runner.AndroidJUnitRunner -import dagger.hilt.android.testing.HiltTestApplication - -class CustomTestRunner : AndroidJUnitRunner() { +class InstrumentationTestRunner : AndroidJUnitRunner() { override fun newApplication( - cl: ClassLoader?, + classLoader: ClassLoader?, className: String?, context: Context? ): Application { - return super.newApplication(cl, HiltTestApplication::class.java.name, context) + return super.newApplication(classLoader, TestApplication::class.java.name, context) } } \ No newline at end of file diff --git a/app/src/androidTest/java/com/santimattius/template/TestApplication.kt b/app/src/androidTest/java/com/santimattius/template/TestApplication.kt new file mode 100644 index 0000000..f60aebc --- /dev/null +++ b/app/src/androidTest/java/com/santimattius/template/TestApplication.kt @@ -0,0 +1,29 @@ +package com.santimattius.template + +import android.app.Application +import org.koin.androix.startup.KoinStartup +import org.koin.core.annotation.KoinExperimentalAPI +import org.koin.dsl.KoinConfiguration +import org.koin.dsl.module +import org.koin.ksp.generated.com_santimattius_template_di_AppModule +import org.koin.ksp.generated.defaultModule + +@OptIn(KoinExperimentalAPI::class) +class TestApplication : Application(), KoinStartup { + override fun onKoinStartup(): KoinConfiguration { + return KoinConfiguration { + //kspAndroidTest no generate FakeDataModule + val fakeDataModule = com.santimattius.template.di.FakeDataModule() + modules( + com_santimattius_template_di_AppModule, + defaultModule, + module { + single { fakeDataModule.provideMovieRepository(get(), get()) } + single { fakeDataModule.provideFakeLocalDataSource() } + single { fakeDataModule.provideRemoteDataSource() } + } + ) + } + } + +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/santimattius/template/di/FakeDataModule.kt b/app/src/androidTest/java/com/santimattius/template/di/FakeDataModule.kt index 042c876..8825d7d 100644 --- a/app/src/androidTest/java/com/santimattius/template/di/FakeDataModule.kt +++ b/app/src/androidTest/java/com/santimattius/template/di/FakeDataModule.kt @@ -6,36 +6,30 @@ import com.santimattius.core.data.datasources.MovieLocalDataSource import com.santimattius.core.data.datasources.MovieNetworkDataSource import com.santimattius.core.data.repositories.TMDbRepository import com.santimattius.core.domain.repositories.MovieRepository -import dagger.Module -import dagger.Provides -import dagger.hilt.components.SingletonComponent -import dagger.hilt.testing.TestInstallIn -import javax.inject.Named +import org.koin.core.annotation.Factory +import org.koin.core.annotation.Module +import org.koin.core.annotation.Named @Module -@TestInstallIn( - components = [SingletonComponent::class], - replaces = [DataModule::class] -) class FakeDataModule { - @Provides + @Factory fun provideMovieRepository( - @Named("fake_remote_data_source") movieNetworkDataSource: MovieNetworkDataSource, - @Named("fake_local_data_source") movieLocalDataSource: MovieLocalDataSource, + @Named("_fake_remote_data_source") movieNetworkDataSource: MovieNetworkDataSource, + @Named("_fake_local_data_source") movieLocalDataSource: MovieLocalDataSource, ): MovieRepository = TMDbRepository( movieNetworkDataSource = movieNetworkDataSource, movieLocalDataSource = movieLocalDataSource ) - @Named("fake_local_data_source") - @Provides + @Named("_fake_local_data_source") + @Factory fun provideFakeLocalDataSource(): MovieLocalDataSource { return FakeMovieLocalDataSource() } - @Named("fake_remote_data_source") - @Provides + @Named("_fake_remote_data_source") + @Factory fun provideRemoteDataSource(): MovieNetworkDataSource { return FakeMovieNetworkDataSource() } diff --git a/app/src/androidTest/java/com/santimattius/template/rules/KoinAndroidTestRule.kt b/app/src/androidTest/java/com/santimattius/template/rules/KoinAndroidTestRule.kt new file mode 100644 index 0000000..98848a3 --- /dev/null +++ b/app/src/androidTest/java/com/santimattius/template/rules/KoinAndroidTestRule.kt @@ -0,0 +1,33 @@ +package com.santimattius.template.rules + +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.rules.TestWatcher +import org.junit.runner.Description +import org.koin.android.ext.koin.androidContext +import org.koin.core.context.GlobalContext.getKoinApplicationOrNull +import org.koin.core.context.GlobalContext.unloadKoinModules +import org.koin.core.context.loadKoinModules +import org.koin.core.context.startKoin +import org.koin.core.module.Module + +class KoinAndroidTestRule( + private val modules: List +) : TestWatcher() { + + override fun starting(description: Description?) { + val application = getKoinApplicationOrNull() + if (application == null) { + startKoin { + androidContext(InstrumentationRegistry.getInstrumentation().targetContext.applicationContext) + modules(modules) + } + } else { + loadKoinModules(modules = modules) + } + + } + + override fun finished(description: Description?) { + unloadKoinModules(modules) + } +} \ No newline at end of file diff --git a/app/src/androidTest/java/com/santimattius/template/ui/HomeComposeActivityTest.kt b/app/src/androidTest/java/com/santimattius/template/ui/HomeComposeActivityTest.kt index 9e6d24e..6c0fcf1 100644 --- a/app/src/androidTest/java/com/santimattius/template/ui/HomeComposeActivityTest.kt +++ b/app/src/androidTest/java/com/santimattius/template/ui/HomeComposeActivityTest.kt @@ -4,24 +4,32 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithTag import androidx.test.espresso.IdlingPolicies -import com.santimattius.test.rules.MainCoroutinesTestRule -import com.santimattius.template.di.DataModule +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.MediumTest +import com.santimattius.template.rules.KoinAndroidTestRule import com.santimattius.template.ui.compose.HomeComposeActivity -import dagger.hilt.android.testing.HiltAndroidRule -import dagger.hilt.android.testing.HiltAndroidTest -import dagger.hilt.android.testing.UninstallModules +import com.santimattius.test.rules.MainCoroutinesTestRule import org.junit.Before import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith +import org.koin.ksp.generated.com_santimattius_template_di_AppModule +import org.koin.ksp.generated.com_santimattius_template_di_FakeDataModule +import org.koin.ksp.generated.defaultModule import java.util.concurrent.TimeUnit - -@UninstallModules(DataModule::class) -@HiltAndroidTest +@MediumTest +@RunWith(AndroidJUnit4::class) class HomeComposeActivityTest { @get:Rule(order = 0) - var hiltRule = HiltAndroidRule(this) + var koinTestRule = KoinAndroidTestRule( + listOf( + com_santimattius_template_di_FakeDataModule, + com_santimattius_template_di_AppModule, + defaultModule + ) + ) @get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule() @@ -34,7 +42,6 @@ class HomeComposeActivityTest { @Before fun init() { - hiltRule.inject() composeTestRule.mainClock.autoAdvance = false IdlingPolicies.setIdlingResourceTimeout(10, TimeUnit.SECONDS) } diff --git a/app/src/androidTest/java/com/santimattius/template/ui/HomeViewActivityTest.kt b/app/src/androidTest/java/com/santimattius/template/ui/HomeViewActivityTest.kt index 9b1793d..a6f6827 100644 --- a/app/src/androidTest/java/com/santimattius/template/ui/HomeViewActivityTest.kt +++ b/app/src/androidTest/java/com/santimattius/template/ui/HomeViewActivityTest.kt @@ -6,29 +6,35 @@ import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.hasDescendant import androidx.test.espresso.matcher.ViewMatchers.withContentDescription import androidx.test.espresso.matcher.ViewMatchers.withId +import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest -import com.santimattius.test.data.MovieMother -import com.santimattius.test.rules.MainCoroutinesTestRule import com.santimattius.template.R -import com.santimattius.template.di.DataModule import com.santimattius.template.espresso.RecyclerViewInteraction -import com.santimattius.template.ui.xml.home.HomeViewActivity +import com.santimattius.template.rules.KoinAndroidTestRule import com.santimattius.template.ui.models.MovieUiModel import com.santimattius.template.ui.models.mapping.asUiModels -import dagger.hilt.android.testing.HiltAndroidRule -import dagger.hilt.android.testing.HiltAndroidTest -import dagger.hilt.android.testing.UninstallModules -import org.junit.Before +import com.santimattius.template.ui.xml.home.HomeViewActivity +import com.santimattius.test.data.MovieMother +import com.santimattius.test.rules.MainCoroutinesTestRule import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith +import org.koin.ksp.generated.com_santimattius_template_di_AppModule +import org.koin.ksp.generated.com_santimattius_template_di_FakeDataModule +import org.koin.ksp.generated.defaultModule @MediumTest -@UninstallModules(DataModule::class) -@HiltAndroidTest +@RunWith(AndroidJUnit4::class) class HomeViewActivityTest { @get:Rule(order = 0) - var hiltRule = HiltAndroidRule(this) + var koinTestRule = KoinAndroidTestRule( + listOf( + com_santimattius_template_di_FakeDataModule, + com_santimattius_template_di_AppModule, + defaultModule + ) + ) @get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule() @@ -36,11 +42,6 @@ class HomeViewActivityTest { @get:Rule(order = 1) val coroutinesTestRule = MainCoroutinesTestRule() - @Before - fun setUp() { - hiltRule.inject() - } - @Test fun showsTitleOfImageIfThereAreImages() { val pictures = MovieMother.createDomainMovies() diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..8ab2a68 Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/com/santimattius/template/MainApplication.kt b/app/src/main/java/com/santimattius/template/MainApplication.kt index 975fc1f..552e0c5 100644 --- a/app/src/main/java/com/santimattius/template/MainApplication.kt +++ b/app/src/main/java/com/santimattius/template/MainApplication.kt @@ -1,7 +1,26 @@ package com.santimattius.template import android.app.Application -import dagger.hilt.android.HiltAndroidApp +import org.koin.android.ext.koin.androidContext +import org.koin.android.logger.AndroidLogger +import org.koin.androix.startup.KoinStartup +import org.koin.core.annotation.KoinExperimentalAPI +import org.koin.dsl.KoinConfiguration +import org.koin.ksp.generated.com_santimattius_template_di_AppModule +import org.koin.ksp.generated.com_santimattius_template_di_DataModule +import org.koin.ksp.generated.defaultModule -@HiltAndroidApp -class MainApplication : Application() \ No newline at end of file +@OptIn(KoinExperimentalAPI::class) +class MainApplication : Application(), KoinStartup { + override fun onKoinStartup(): KoinConfiguration { + return KoinConfiguration { + androidContext(this@MainApplication) + logger(AndroidLogger()) + modules( + com_santimattius_template_di_DataModule, + com_santimattius_template_di_AppModule, + defaultModule + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/santimattius/template/di/AppModule.kt b/app/src/main/java/com/santimattius/template/di/AppModule.kt index f500344..e48fa76 100644 --- a/app/src/main/java/com/santimattius/template/di/AppModule.kt +++ b/app/src/main/java/com/santimattius/template/di/AppModule.kt @@ -5,28 +5,23 @@ import com.santimattius.core.data.client.database.TheMovieDataBase import com.santimattius.core.data.client.network.RetrofitServiceCreator import com.santimattius.core.data.client.network.TheMovieDBService import com.santimattius.template.BuildConfig -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext -import dagger.hilt.components.SingletonComponent +import org.koin.core.annotation.Factory +import org.koin.core.annotation.Module +import org.koin.core.annotation.Singleton -import javax.inject.Singleton @Module -@InstallIn(SingletonComponent::class) class AppModule { - @Provides - fun provideAppDatabase(@ApplicationContext context: Context): TheMovieDataBase = + @Factory + fun provideAppDatabase(context: Context): TheMovieDataBase = TheMovieDataBase.get(context) - @Provides + @Factory fun provideMovieDBService(serviceCreator: RetrofitServiceCreator): TheMovieDBService = serviceCreator.createService(TheMovieDBService::class.java) - @Provides @Singleton fun provideRetrofit(): RetrofitServiceCreator { return RetrofitServiceCreator( diff --git a/app/src/main/java/com/santimattius/template/di/DataModule.kt b/app/src/main/java/com/santimattius/template/di/DataModule.kt index b698dfc..7661c2e 100644 --- a/app/src/main/java/com/santimattius/template/di/DataModule.kt +++ b/app/src/main/java/com/santimattius/template/di/DataModule.kt @@ -8,16 +8,13 @@ import com.santimattius.core.data.datasources.implementation.RetrofitMovieNetwor import com.santimattius.core.data.datasources.implementation.RoomMovieLocalDataSource import com.santimattius.core.data.repositories.TMDbRepository import com.santimattius.core.domain.repositories.MovieRepository -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent +import org.koin.core.annotation.Module +import org.koin.core.annotation.Singleton @Module -@InstallIn(SingletonComponent::class) class DataModule { - @Provides + @Singleton fun provideMovieRepository( movieNetworkDataSource: MovieNetworkDataSource, movieLocalDataSource: MovieLocalDataSource, @@ -26,12 +23,12 @@ class DataModule { movieLocalDataSource = movieLocalDataSource ) - @Provides + @Singleton fun provideLocalDataSource(theMovieDataBase: TheMovieDataBase): MovieLocalDataSource { return RoomMovieLocalDataSource(theMovieDataBase = theMovieDataBase) } - @Provides + @Singleton fun provideRemoteDataSource(service: TheMovieDBService): MovieNetworkDataSource { return RetrofitMovieNetworkDataSource(service = service) } diff --git a/app/src/main/java/com/santimattius/template/ui/compose/HomeComposeActivity.kt b/app/src/main/java/com/santimattius/template/ui/compose/HomeComposeActivity.kt index 5f62545..a66cd77 100644 --- a/app/src/main/java/com/santimattius/template/ui/compose/HomeComposeActivity.kt +++ b/app/src/main/java/com/santimattius/template/ui/compose/HomeComposeActivity.kt @@ -13,7 +13,6 @@ import androidx.compose.material.icons.filled.Android import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold -import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -25,7 +24,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource -import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.santimattius.template.R import com.santimattius.template.ui.compose.models.HomeUiState @@ -40,9 +38,9 @@ import com.santimattius.template.ui.compose.ui.components.snackbar.CustomSnackBa import com.santimattius.template.ui.compose.ui.components.snackbar.SnackBarVisualsWithError import com.santimattius.template.ui.compose.ui.theme.AndroidTestingTheme import com.santimattius.template.ui.xml.home.HomeViewActivity -import dagger.hilt.android.AndroidEntryPoint +import org.koin.androidx.compose.koinViewModel + -@AndroidEntryPoint class HomeComposeActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -61,7 +59,7 @@ class HomeComposeActivity : ComponentActivity() { @Composable fun HomeRoute( - viewModel: HomeViewModel = hiltViewModel() + viewModel: HomeComposeViewModel = koinViewModel() ) { val snackBarHostState = remember { SnackbarHostState() } Scaffold( diff --git a/app/src/main/java/com/santimattius/template/ui/compose/HomeViewModel.kt b/app/src/main/java/com/santimattius/template/ui/compose/HomeComposeViewModel.kt similarity index 95% rename from app/src/main/java/com/santimattius/template/ui/compose/HomeViewModel.kt rename to app/src/main/java/com/santimattius/template/ui/compose/HomeComposeViewModel.kt index 4f6f66c..5658baa 100644 --- a/app/src/main/java/com/santimattius/template/ui/compose/HomeViewModel.kt +++ b/app/src/main/java/com/santimattius/template/ui/compose/HomeComposeViewModel.kt @@ -7,7 +7,6 @@ import com.santimattius.template.ui.compose.models.HomeUiState import com.santimattius.template.ui.compose.models.Messages import com.santimattius.template.ui.models.MovieUiModel import com.santimattius.template.ui.models.mapping.asUiModels -import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -17,10 +16,10 @@ import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import javax.inject.Inject +import org.koin.android.annotation.KoinViewModel -@HiltViewModel -class HomeViewModel @Inject constructor( +@KoinViewModel +class HomeComposeViewModel( private val movieRepository: MovieRepository, ) : ViewModel() { diff --git a/app/src/main/java/com/santimattius/template/ui/xml/home/HomeFragment.kt b/app/src/main/java/com/santimattius/template/ui/xml/home/HomeFragment.kt index 3d2c71d..f7628a8 100644 --- a/app/src/main/java/com/santimattius/template/ui/xml/home/HomeFragment.kt +++ b/app/src/main/java/com/santimattius/template/ui/xml/home/HomeFragment.kt @@ -8,7 +8,6 @@ import android.widget.Toast import androidx.annotation.VisibleForTesting import androidx.core.view.isVisible import androidx.fragment.app.Fragment -import androidx.fragment.app.viewModels import androidx.recyclerview.widget.GridLayoutManager import com.santimattius.template.R import com.santimattius.template.core.presentation.DialogAction @@ -16,12 +15,11 @@ import com.santimattius.template.databinding.PopularMoviesFragmentBinding import com.santimattius.template.ui.xml.components.showDialog import com.santimattius.template.ui.xml.home.components.PopularMoviesAdapter import com.santimattius.template.ui.xml.models.HomeState -import dagger.hilt.android.AndroidEntryPoint +import org.koin.androidx.viewmodel.ext.android.viewModel -@AndroidEntryPoint class HomeFragment : Fragment() { - private val viewModel: HomeViewModel by viewModels() + private val viewModel: HomeViewModel by viewModel() private val homeAdapter: PopularMoviesAdapter by lazy { PopularMoviesAdapter { diff --git a/app/src/main/java/com/santimattius/template/ui/xml/home/HomeViewActivity.kt b/app/src/main/java/com/santimattius/template/ui/xml/home/HomeViewActivity.kt index c6ac6ae..212e9df 100644 --- a/app/src/main/java/com/santimattius/template/ui/xml/home/HomeViewActivity.kt +++ b/app/src/main/java/com/santimattius/template/ui/xml/home/HomeViewActivity.kt @@ -4,9 +4,7 @@ import android.os.Bundle import android.view.MenuItem import androidx.appcompat.app.AppCompatActivity import com.santimattius.template.R -import dagger.hilt.android.AndroidEntryPoint -@AndroidEntryPoint class HomeViewActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/santimattius/template/ui/xml/home/HomeViewModel.kt b/app/src/main/java/com/santimattius/template/ui/xml/home/HomeViewModel.kt index aed8d10..42e1ce0 100644 --- a/app/src/main/java/com/santimattius/template/ui/xml/home/HomeViewModel.kt +++ b/app/src/main/java/com/santimattius/template/ui/xml/home/HomeViewModel.kt @@ -5,16 +5,16 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.santimattius.core.domain.repositories.MovieRepository -import com.santimattius.template.ui.xml.models.HomeState import com.santimattius.template.ui.models.mapping.asUiModels -import dagger.hilt.android.lifecycle.HiltViewModel +import com.santimattius.template.ui.xml.models.HomeState import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import javax.inject.Inject +import org.koin.android.annotation.KoinViewModel + -@HiltViewModel -class HomeViewModel @Inject constructor( +@KoinViewModel +class HomeViewModel( private val movieRepository: MovieRepository, ) : ViewModel() { diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index eca70cf..036d09b 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index eca70cf..036d09b 100644 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - - + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index a571e60..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..73c6418 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..f71f155 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 61da551..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..73c6418 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c41dd28..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..7ae1218 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..4938bd3 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index db5080a..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..7ae1218 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 6dba46d..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..1cfe5d4 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..f27134a Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index da31a87..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1cfe5d4 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 15ac681..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..fdf39a8 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..e98f51d Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index b216f2d..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..fdf39a8 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index f25a419..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..bf611fc Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000..2db485b Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index e96783c..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..bf611fc Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000..c5d5899 --- /dev/null +++ b/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #FFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ac40a1f..a99909c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ - Testing App + Testing Android Populars Movies Ha ocurrido un error al cargar las peliculas Reintentar diff --git a/app/src/test/java/com/santimattius/template/ui/compose/HomeComposeActivityTest.kt b/app/src/test/java/com/santimattius/template/ui/compose/HomeComposeActivityTest.kt index c7d7e88..410f38b 100644 --- a/app/src/test/java/com/santimattius/template/ui/compose/HomeComposeActivityTest.kt +++ b/app/src/test/java/com/santimattius/template/ui/compose/HomeComposeActivityTest.kt @@ -1,5 +1,6 @@ package com.santimattius.template.ui.compose +import android.app.Application import android.os.Build import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.compose.ui.test.ExperimentalTestApi @@ -7,32 +8,34 @@ import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.runAndroidComposeUiTest import com.santimattius.test.rules.MainCoroutinesTestRule -import com.santimattius.template.di.DataModule -import dagger.hilt.android.testing.HiltAndroidRule -import dagger.hilt.android.testing.HiltAndroidTest -import dagger.hilt.android.testing.HiltTestApplication -import dagger.hilt.android.testing.UninstallModules -import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.koin.ksp.generated.com_santimattius_template_di_AppModule +import org.koin.ksp.generated.com_santimattius_template_ui_di_FakeDataModule +import org.koin.ksp.generated.defaultModule +import org.koin.test.KoinTestRule import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config -@UninstallModules(DataModule::class) -@HiltAndroidTest @RunWith(RobolectricTestRunner::class) @Config( manifest = Config.NONE, sdk = [Build.VERSION_CODES.R], instrumentedPackages = ["androidx.loader.content"], - application = HiltTestApplication::class + application = Application::class ) class HomeComposeActivityTest { @get:Rule(order = 0) - var hiltRule = HiltAndroidRule(this) + var koinTestRule = KoinTestRule.create { + modules( + com_santimattius_template_ui_di_FakeDataModule, + com_santimattius_template_di_AppModule, + defaultModule + ) + } @get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule() @@ -40,10 +43,6 @@ class HomeComposeActivityTest { @get:Rule val coroutinesTestRule = MainCoroutinesTestRule() - @Before - fun init() { - hiltRule.inject() - } @OptIn(ExperimentalTestApi::class) @Test diff --git a/app/src/test/java/com/santimattius/template/ui/compose/HomeViewModelFlowsTest.kt b/app/src/test/java/com/santimattius/template/ui/compose/HomeViewModelFlowsTest.kt index b3a4120..8799aa9 100644 --- a/app/src/test/java/com/santimattius/template/ui/compose/HomeViewModelFlowsTest.kt +++ b/app/src/test/java/com/santimattius/template/ui/compose/HomeViewModelFlowsTest.kt @@ -25,7 +25,7 @@ class HomeViewModelFlowsTest { val movies = MovieMother.createMovies().dtoToDomain() val repository = MockMovieRepository(onPopularMovies = { movies }) val expectedState = HomeUiState(movies = movies.asUiModels()) - viewModelScenario { HomeViewModel(repository) }.use { scenario -> + viewModelScenario { HomeComposeViewModel(repository) }.use { scenario -> val viewModel = scenario.viewModel runTest(mainCoroutinesTestRule.testDispatcher) { viewModel.state.test { @@ -42,7 +42,7 @@ class HomeViewModelFlowsTest { @Test fun `Given result is empty When popular movies Then return empty list`() { val repository = MockMovieRepository(onPopularMovies = { emptyList() }) - viewModelScenario { HomeViewModel(repository) }.use { + viewModelScenario { HomeComposeViewModel(repository) }.use { val viewModel = it.viewModel runTest(mainCoroutinesTestRule.testDispatcher) { viewModel.state.test { @@ -61,7 +61,7 @@ class HomeViewModelFlowsTest { @Test fun `Given result is error When popular movies Then return error`() { val repository = MockMovieRepository(onPopularMovies = { throw Exception() }) - viewModelScenario { HomeViewModel(repository) }.use { scenario -> + viewModelScenario { HomeComposeViewModel(repository) }.use { scenario -> val viewModel = scenario.viewModel runTest(mainCoroutinesTestRule.testDispatcher) { viewModel.state.test { diff --git a/app/src/test/java/com/santimattius/template/ui/di/FakeDataModule.kt b/app/src/test/java/com/santimattius/template/ui/di/FakeDataModule.kt index 35dc9f0..f2a5aaf 100644 --- a/app/src/test/java/com/santimattius/template/ui/di/FakeDataModule.kt +++ b/app/src/test/java/com/santimattius/template/ui/di/FakeDataModule.kt @@ -1,26 +1,19 @@ package com.santimattius.template.ui.di -import com.santimattius.test.data.FakeMovieLocalDataSource -import com.santimattius.test.data.FakeMovieNetworkDataSource import com.santimattius.core.data.datasources.MovieLocalDataSource import com.santimattius.core.data.datasources.MovieNetworkDataSource import com.santimattius.core.data.repositories.TMDbRepository -import com.santimattius.template.di.DataModule import com.santimattius.core.domain.repositories.MovieRepository -import dagger.Module -import dagger.Provides -import dagger.hilt.components.SingletonComponent -import dagger.hilt.testing.TestInstallIn -import javax.inject.Named +import com.santimattius.test.data.FakeMovieLocalDataSource +import com.santimattius.test.data.FakeMovieNetworkDataSource +import org.koin.core.annotation.Factory +import org.koin.core.annotation.Module +import org.koin.core.annotation.Named @Module -@TestInstallIn( - components = [SingletonComponent::class], - replaces = [DataModule::class] -) class FakeDataModule { - @Provides + @Factory fun provideMovieRepository( @Named("fake_remote_data_source") movieNetworkDataSource: MovieNetworkDataSource, @Named("fake_local_data_source") movieLocalDataSource: MovieLocalDataSource, @@ -30,13 +23,13 @@ class FakeDataModule { ) @Named("fake_local_data_source") - @Provides + @Factory fun provideFakeLocalDataSource(): MovieLocalDataSource { return FakeMovieLocalDataSource() } @Named("fake_remote_data_source") - @Provides + @Factory fun provideRemoteDataSource(): MovieNetworkDataSource { return FakeMovieNetworkDataSource() } diff --git a/app/src/test/java/com/santimattius/template/ui/xml/HomeFragmentTest.kt b/app/src/test/java/com/santimattius/template/ui/xml/HomeFragmentTest.kt index 4d58ec4..f744314 100644 --- a/app/src/test/java/com/santimattius/template/ui/xml/HomeFragmentTest.kt +++ b/app/src/test/java/com/santimattius/template/ui/xml/HomeFragmentTest.kt @@ -1,39 +1,42 @@ package com.santimattius.template.ui.xml +import android.app.Application import android.os.Build import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.santimattius.test.extensions.launchFragmentInHiltContainer -import com.santimattius.test.rules.MainCoroutinesTestRule -import com.santimattius.template.di.DataModule +import androidx.fragment.app.testing.launchFragmentInContainer +import androidx.lifecycle.Lifecycle import com.santimattius.template.ui.xml.home.HomeFragment import com.santimattius.template.ui.xml.home.components.viewholders.MovieViewHolder -import dagger.hilt.android.testing.HiltAndroidRule -import dagger.hilt.android.testing.HiltAndroidTest -import dagger.hilt.android.testing.HiltTestApplication -import dagger.hilt.android.testing.UninstallModules +import com.santimattius.test.rules.MainCoroutinesTestRule import org.hamcrest.CoreMatchers.equalTo -import org.hamcrest.MatcherAssert -import org.junit.Before -import org.junit.Ignore +import org.hamcrest.MatcherAssert.assertThat import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.koin.ksp.generated.com_santimattius_template_di_AppModule +import org.koin.ksp.generated.com_santimattius_template_ui_di_FakeDataModule +import org.koin.ksp.generated.defaultModule +import org.koin.test.KoinTestRule +import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config -@UninstallModules(DataModule::class) -@HiltAndroidTest -@RunWith(AndroidJUnit4::class) +@RunWith(RobolectricTestRunner::class) @Config( manifest = Config.NONE, sdk = [Build.VERSION_CODES.R], instrumentedPackages = ["androidx.loader.content"], - application = HiltTestApplication::class + application = Application::class ) class HomeFragmentTest { @get:Rule - var hiltRule = HiltAndroidRule(this) + var koinTestRule = KoinTestRule.create { + modules( + com_santimattius_template_ui_di_FakeDataModule, + com_santimattius_template_di_AppModule, + defaultModule + ) + } @get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule() @@ -41,33 +44,25 @@ class HomeFragmentTest { @get:Rule val coroutinesTestRule = MainCoroutinesTestRule() - @Before - fun setUp() { - hiltRule.inject() - } @Test - @Ignore("Test not working, check documentation test fragment and hilt") fun `verify first movie is spider-man`() { -// val scenario = -// launchFragmentInContainer(themeResId = R.style.Theme_EntertainmentApp) -// -// scenario.onFragment { fragment -> } + val scenario = launchFragmentInContainer( + initialState = Lifecycle.State.INITIALIZED + ) -//https://developer.android.com/training/dependency-injection/hilt-testing?hl=es-419#launchfragment - launchFragmentInHiltContainer { - val recyclerView = (this as HomeFragment).viewBinding.gridOfMovies + scenario.moveToState(Lifecycle.State.RESUMED) + scenario.onFragment { fragment -> + val recyclerView = fragment.viewBinding.gridOfMovies val viewHolder = recyclerView .findViewHolderForAdapterPosition(0) val imageView = (viewHolder as MovieViewHolder).viewBinding.imageMovie - - MatcherAssert.assertThat( - imageView.contentDescription, - equalTo("Spider-Man: No Way Home") - ) + val title = imageView.contentDescription.toString() + assertThat(title, equalTo("Spider-Man: No Way Home")) } + } } \ No newline at end of file diff --git a/app/src/test/java/com/santimattius/template/ui/xml/HomeViewActivityTest.kt b/app/src/test/java/com/santimattius/template/ui/xml/HomeViewActivityTest.kt index 46ca9e4..c35898f 100644 --- a/app/src/test/java/com/santimattius/template/ui/xml/HomeViewActivityTest.kt +++ b/app/src/test/java/com/santimattius/template/ui/xml/HomeViewActivityTest.kt @@ -1,41 +1,44 @@ package com.santimattius.template.ui.xml +import android.app.Application import android.os.Build import androidx.arch.core.executor.testing.InstantTaskExecutorRule import androidx.fragment.app.FragmentContainerView import androidx.test.core.app.ActivityScenario import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.santimattius.test.rules.MainCoroutinesTestRule import com.santimattius.template.R -import com.santimattius.template.di.DataModule import com.santimattius.template.ui.xml.home.HomeFragment import com.santimattius.template.ui.xml.home.HomeViewActivity import com.santimattius.template.ui.xml.home.components.viewholders.MovieViewHolder -import dagger.hilt.android.testing.HiltAndroidRule -import dagger.hilt.android.testing.HiltAndroidTest -import dagger.hilt.android.testing.HiltTestApplication -import dagger.hilt.android.testing.UninstallModules +import com.santimattius.test.rules.MainCoroutinesTestRule import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.MatcherAssert.assertThat -import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.koin.ksp.generated.com_santimattius_template_di_AppModule +import org.koin.ksp.generated.com_santimattius_template_ui_di_FakeDataModule +import org.koin.ksp.generated.defaultModule +import org.koin.test.KoinTestRule import org.robolectric.annotation.Config -@UninstallModules(DataModule::class) -@HiltAndroidTest @RunWith(AndroidJUnit4::class) @Config( manifest = Config.NONE, sdk = [Build.VERSION_CODES.R], instrumentedPackages = ["androidx.loader.content"], - application = HiltTestApplication::class + application = Application::class ) class HomeViewActivityTest { @get:Rule - var hiltRule = HiltAndroidRule(this) + var koinTestRule = KoinTestRule.create { + modules( + com_santimattius_template_ui_di_FakeDataModule, + com_santimattius_template_di_AppModule, + defaultModule + ) + } @get:Rule val instantTaskExecutorRule = InstantTaskExecutorRule() @@ -43,10 +46,6 @@ class HomeViewActivityTest { @get:Rule val coroutinesTestRule = MainCoroutinesTestRule() - @Before - fun setUp() { - hiltRule.inject() - } @Test fun `verify first movie is spider-man`() { diff --git a/build.gradle.kts b/build.gradle.kts index 44b9aba..7c820fd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,6 @@ plugins { alias(libs.plugins.kotlin) apply false alias(libs.plugins.compose.compiler) apply false alias(libs.plugins.ksp) apply false - alias(libs.plugins.hilt) apply false alias(libs.plugins.detekt) apply false alias(libs.plugins.google.secrets.gradle.plugin) apply false alias(libs.plugins.automattic.measure.builds) apply false diff --git a/core/build.gradle.kts b/core/build.gradle.kts index a665ef3..469e6f4 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -49,6 +49,12 @@ android { } } } + + libraryVariants.forEach { variant -> + variant.sourceSets.forEach { + it.javaDirectories += files("build/generated/ksp/${variant.name}/kotlin") + } + } } dependencies { @@ -67,11 +73,10 @@ dependencies { implementation(libs.room.runtime) ksp(libs.room.compiler) - //DI - implementation(libs.hilt.android) - implementation(libs.hilt.navigation.compose) - ksp(libs.hilt.compiler) - ksp(libs.androidx.hilt.compiler) + //Koin + implementation(platform(libs.koin.bom)) + implementation(libs.koin.android) + implementation(libs.koin.androidx.compose) testImplementation(project(path = ":shared-test")) testImplementation(libs.bundles.unitTesting) @@ -81,8 +86,8 @@ dependencies { testImplementation(libs.hamcrest) testImplementation(libs.mockito.kotlin) - testImplementation(libs.hilt.test) - kspTest(libs.hilt.android.compiler) + testImplementation(libs.koin.test.core) + testImplementation(libs.koin.test.junit4) androidTestImplementation(libs.test.ext) androidTestImplementation(libs.test.espresso) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7b04c6f..2fdab18 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,11 +1,10 @@ [versions] # Plugins -androidGradlePlugin = "8.7.3" +androidGradlePlugin = "8.8.0" hamcrest = "2.2" -kotlin = "2.1.0" -hilt = "2.54" +kotlin = "2.1.10" detektGradlePlugin = "1.23.7" -ksp = "2.1.0-1.0.29" +ksp = "2.1.10-1.0.29" googleSecretsPlugin = "2.0.1" automatticMeasureBuilds = "3.1.1" @@ -17,7 +16,7 @@ fragmentKtx = "1.8.5" constraintLayout = "2.2.0" recyclerView = "1.4.0" materialVersion = "1.12.0" -lifecycle = "2.9.0-alpha08" +lifecycle = "2.9.0-alpha09" retrofit = "2.11.0" okHttp = "4.12.0" @@ -28,12 +27,12 @@ glide = "4.12.0" coil = "2.7.0" room = "2.6.1" -hiltCompiler = "1.2.0" -hiltNavigationCompose = "1.2.0" - -androidxComposeBom = "2025.01.00" +androidxComposeBom = "2025.01.01" activityCompose = "1.10.0" +koinBom = "4.1.0-Beta5" +koinAnnotations = "2.0.0-RC1" + #Testing junit = "4.13.2" junitExt = "1.2.1" @@ -96,13 +95,16 @@ coroutine-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", ver room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" } room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" } room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" } -#Hilt -hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" } -hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" } -hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", version.ref = "hilt" } -hilt-test = { module = "com.google.dagger:hilt-android-testing", version.ref = "hilt" } -hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" } -androidx-hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "hiltCompiler" } + +koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koinBom" } +koin-android = { group = "io.insert-koin", name = "koin-android" } +koin-androidx-compose = { group = "io.insert-koin", name = "koin-androidx-compose" } +koin-androidx-startup = { group = "io.insert-koin", name = "koin-androidx-startup" } +koin-annotations-core = { group = "io.insert-koin", name = "koin-annotations" , version.ref= "koinAnnotations" } +koin-annotations-compiler = { group = "io.insert-koin", name = "koin-ksp-compiler", version.ref= "koinAnnotations" } +koin-test-core = { group = "io.insert-koin", name = "koin-test"} +koin-test-junit4 = { group = "io.insert-koin", name = "koin-test-junit4"} +koin-android-test = { group = "io.insert-koin", name = "koin-android-test"} # Test junit = { module = "junit:junit", version.ref = "junit" } @@ -113,7 +115,9 @@ mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version.ref = " robolectric-core = { module = "org.robolectric:robolectric", version.ref = "robolectric" } robolectric-httpclient = { module = "org.robolectric:shadows-httpclient", version.ref = "robolectric" } androidx-core-ktx = { module = "androidx.test:core-ktx", version.ref = "coreKtxVersion" } -androidx-fragment-testing-manifest = { module = "androidx.fragment:fragment-testing-manifest", version.ref = "fragmentKtx" } +androidx-fragment-testing-manifest = { module = "androidx.fragment:fragment-testing-manifest", version.ref = "fragmentTesting" } +androidx-fragment-testing = { module = "androidx.fragment:fragment-testing", version.ref = "fragmentTesting" } + # AndroidTest test-ext = { module = "androidx.test.ext:junit", version.ref = "junitExt" } test-ext-ktx = { module = "androidx.test.ext:junit-ktx", version.ref = "junitExt" } @@ -149,7 +153,6 @@ kotlin = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } room = { id = "androidx.room", version.ref = "room"} ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } -hilt = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detektGradlePlugin" } google-secrets-gradle-plugin = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "googleSecretsPlugin" } automattic-measure-builds = { id = "com.automattic.android.measure-builds", version.ref = "automatticMeasureBuilds" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 78da8c6..349ffa5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip diff --git a/plugins/build/kotlin/pluginsjar-classes.txt b/plugins/build/kotlin/pluginsjar-classes.txt deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/build/libs/plugins.jar b/plugins/build/libs/plugins.jar index 244388a..e8b9e08 100644 Binary files a/plugins/build/libs/plugins.jar and b/plugins/build/libs/plugins.jar differ diff --git a/shared-test/build.gradle.kts b/shared-test/build.gradle.kts index ba738a5..68f031e 100644 --- a/shared-test/build.gradle.kts +++ b/shared-test/build.gradle.kts @@ -4,7 +4,6 @@ plugins { alias(libs.plugins.android.library) alias(libs.plugins.kotlin) alias(libs.plugins.ksp) - alias(libs.plugins.hilt) } android { @@ -33,6 +32,11 @@ android { kotlinOptions { jvmTarget = JavaVersion.VERSION_17.toString() } + libraryVariants.forEach { variant -> + variant.sourceSets.forEach { + it.javaDirectories += files("build/generated/ksp/${variant.name}/kotlin") + } + } } dependencies { @@ -44,8 +48,9 @@ dependencies { implementation(libs.bundles.serializable) implementation(libs.androidx.fragment.testing.manifest) - implementation(libs.hilt.android) - implementation(libs.hilt.test) - ksp(libs.hilt.compiler) + + implementation(platform(libs.koin.bom)) + implementation(libs.koin.test.core) + implementation(libs.bundles.unitTesting) } \ No newline at end of file diff --git a/shared-test/src/main/AndroidManifest.xml b/shared-test/src/main/AndroidManifest.xml index 7bf7287..4fb0375 100644 --- a/shared-test/src/main/AndroidManifest.xml +++ b/shared-test/src/main/AndroidManifest.xml @@ -1,9 +1,2 @@ - - - - - - \ No newline at end of file + diff --git a/shared-test/src/main/java/com/santimattius/test/HiltTestActivity.kt b/shared-test/src/main/java/com/santimattius/test/HiltTestActivity.kt deleted file mode 100644 index 7599d8f..0000000 --- a/shared-test/src/main/java/com/santimattius/test/HiltTestActivity.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.santimattius.test - -import androidx.fragment.app.FragmentActivity -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class HiltTestActivity : FragmentActivity() \ No newline at end of file diff --git a/shared-test/src/main/java/com/santimattius/test/extensions/HiltExtensions.kt b/shared-test/src/main/java/com/santimattius/test/extensions/HiltExtensions.kt deleted file mode 100644 index bf6496a..0000000 --- a/shared-test/src/main/java/com/santimattius/test/extensions/HiltExtensions.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.santimattius.test.extensions - -import android.content.ComponentName -import android.content.Intent -import android.os.Bundle -import androidx.annotation.StyleRes -import androidx.fragment.app.Fragment -import androidx.test.core.app.ActivityScenario -import androidx.test.core.app.ApplicationProvider -import com.santimattius.shared_test.R -import com.santimattius.test.HiltTestActivity - -//https://developer.android.com/training/dependency-injection/hilt-testing?hl=es-419#launchfragment -inline fun launchFragmentInHiltContainer( - fragmentArgs: Bundle? = null, - @StyleRes themeResId: Int = R.style.FragmentScenarioEmptyFragmentActivityTheme, - crossinline action: Fragment.() -> Unit = {} -) { - val startActivityIntent = Intent.makeMainActivity( - ComponentName( - ApplicationProvider.getApplicationContext(), - HiltTestActivity::class.java - ) - ).putExtra( - "androidx.fragment.app.testing.FragmentScenario.EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY", - themeResId - ) - - val scenario = ActivityScenario.launch(startActivityIntent) - scenario.onActivity { activity -> - val fragment: Fragment = activity.supportFragmentManager.fragmentFactory.instantiate( - requireNotNull(T::class.java.classLoader), - T::class.java.name - ) - fragment.arguments = fragmentArgs - activity.supportFragmentManager - .beginTransaction() - .add(android.R.id.content, fragment, "") - .commitNow() - - fragment.action() - } -} \ No newline at end of file