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