From 377b1dac7bf51cb9b6636bd511c637a6f263e4e0 Mon Sep 17 00:00:00 2001 From: Fernando Prieto Moyano Date: Sat, 29 Jan 2022 21:52:30 +0000 Subject: [PATCH 1/4] Updated some tests --- README.md | 6 +- .../presentation/vm/DashboardViewModelTest.kt | 86 ++++++------- .../presentation/vm/LaunchesViewModelTest.kt | 30 ++--- ...anyInfoUiModelDomainToUiModelMapperTest.kt | 1 - .../vm/mapper/DateTransformerImplTest.kt | 15 +-- .../LaunchesDomainToUiModelMapperTest.kt | 49 ++++---- build.gradle.kts | 2 +- .../fernando/android/plugin/AndroidPlugin.kt | 5 +- .../fernando/dependencies/TestDependencies.kt | 10 +- .../prieto/fernando/dependencies/Versions.kt | 3 +- .../data/SpaceXRemoteSourceImplTest.kt | 97 +++++++++++---- ...ResponseToRepositoryModelMapperImplTest.kt | 10 +- .../repository/SpaceXRepositoryImplTest.kt | 115 +++++++++++++++--- .../mapper/LaunchesDomainFilterImplTest.kt | 4 - .../domain/usecase/GetCompanyInfoImplTest.kt | 19 ++- .../domain/usecase/GetLaunchesImplTest.kt | 28 ++--- 16 files changed, 288 insertions(+), 192 deletions(-) diff --git a/README.md b/README.md index 66771d2..d485b02 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ The purpose of this project is to consolidate some of the learned insights throu * [Retrofit][5] Type-safe REST client for Android to consume RESTful web services. * [Timber][6] Logger with a small API which provides utility on top of Android's normal Log class. * [Espresso][7] Android UI Testing framework. -* [Mockito-Kotlin][8] test functions facilitation for Mockito (mocking framework for testing). +* [MockK][8] mocking framework for testing. * [MockWebServer][9] A scriptable web server for testing HTTP clients, used for Instrumentation tests in this project. * [Coil Compose][10] Image downloading and caching library supported by Jetpack Compose. * [Lottie Compose][11] Library that provides that parses Adobe After Effects animations exported as json with Bodymovin and renders them natively on mobile. @@ -45,7 +45,7 @@ The purpose of this project is to consolidate some of the learned insights throu [5]: https://github.com/square/retrofit [6]: https://github.com/JakeWharton/timber [7]: https://developer.android.com/training/testing/espresso/ -[8]: https://github.com/nhaarman/mockito-kotlin +[8]: https://mockk.io [9]: https://github.com/square/okhttp/tree/master/mockwebserver [10]: https://github.com/coil-kt/coil [11]: https://airbnb.io/lottie/#/android-compose @@ -96,7 +96,7 @@ These are the three options available (all of them maintained): There are some highlights: * Every layer in the architecture has been tested. -* Mockito has been used for mocking | stubbing. +* MockK has been used for mocking | stubbing. * `Given | When | Then` code presentation order, in order to give a more structured style. * Code Coverage (WORK IN PROGRESS). diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt index c9861f1..f5c7356 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt @@ -1,11 +1,10 @@ package prieto.fernando.spacex.presentation.vm import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import androidx.lifecycle.Observer -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.times -import com.nhaarman.mockito_kotlin.verify -import com.nhaarman.mockito_kotlin.whenever +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.impl.annotations.MockK import junit.framework.Assert.assertEquals import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -16,23 +15,19 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnitRunner import prieto.fernando.domain.model.CompanyInfoDomainModel import prieto.fernando.domain.usecase.GetCompanyInfo import prieto.fernando.spacex.presentation.screens.dashboard.CompanyInfoUiModel import prieto.fernando.spacex.presentation.vm.mapper.CompanyInfoDomainToUiModelMapper @ExperimentalCoroutinesApi -@RunWith(MockitoJUnitRunner::class) class DashboardViewModelTest { private lateinit var cut: DashboardViewModel - @Mock + @MockK lateinit var getCompanyInfo: GetCompanyInfo - @Mock + @MockK lateinit var companyInfoMapper: CompanyInfoDomainToUiModelMapper @Before @@ -44,41 +39,39 @@ class DashboardViewModelTest { @get:Rule var rule: TestRule = InstantTaskExecutorRule() - @Test fun `When companyInfo Then companyInfoUiModelRetrieved with expected result`() { - runBlockingTest { - // Given - val companyInfoDomainModel = CompanyInfoDomainModel( - "name", - "founder", - "foundedYear", - "employees", - 1, - 23 - ) - val expected = CompanyInfoUiModel( - "name", - "founder", - "founded", - "employees", - 1, - 23 - ) - val flow = flow { - emit(companyInfoDomainModel) - } - whenever(getCompanyInfo.execute()).thenReturn(flow) - whenever(companyInfoMapper.toUiModel(companyInfoDomainModel)).thenReturn(expected) + // Given + val companyInfoDomainModel = CompanyInfoDomainModel( + "name", + "founder", + "foundedYear", + "employees", + 1, + 23 + ) + val expected = CompanyInfoUiModel( + "name", + "founder", + "founded", + "employees", + 1, + 23 + ) - // When - cut.companyInfo() - val actualValue = cut.viewState.value.companyInfoUiModel - - // Then - verify(getCompanyInfo, times(2)).execute() - assertEquals(expected, actualValue) + coEvery { getCompanyInfo.execute() } returns flow { + emit(companyInfoDomainModel) } + every { companyInfoMapper.toUiModel(companyInfoDomainModel) } returns expected + + // When + cut.companyInfo() + val actual = cut.viewState.value.companyInfoUiModel + + // Then + coVerify(exactly = 2) { getCompanyInfo.execute() } + + assertEquals(expected, actual) } @Test @@ -86,18 +79,17 @@ class DashboardViewModelTest { runBlockingTest { // Given val expectedErrorState = true - val flow = flow { + coEvery { getCompanyInfo.execute() } returns flow { emit(throw Exception("Network Exception")) } - whenever(getCompanyInfo.execute()).thenReturn(flow) // When cut.companyInfo() - val actualValue = cut.viewState.value.isError + val actual = cut.viewState.value.isError // Then - verify(getCompanyInfo, times(2)).execute() - assertEquals(expectedErrorState, actualValue) + coVerify(exactly = 2) { getCompanyInfo } + assertEquals(expectedErrorState, actual) } } } diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt index 64e2a54..5baa9a4 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt @@ -1,9 +1,9 @@ package prieto.fernando.spacex.presentation.vm import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.nhaarman.mockito_kotlin.times -import com.nhaarman.mockito_kotlin.verify -import com.nhaarman.mockito_kotlin.whenever +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.impl.annotations.MockK import junit.framework.Assert.assertEquals import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -14,9 +14,6 @@ import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnitRunner import prieto.fernando.core_android_test.util.buildDate import prieto.fernando.domain.model.LaunchDomainModel import prieto.fernando.domain.model.LinksDomainModel @@ -29,24 +26,23 @@ import prieto.fernando.spacex.presentation.vm.mapper.ClickableLinkProvider import prieto.fernando.spacex.presentation.vm.mapper.LaunchesDomainToUiModelMapper @ExperimentalCoroutinesApi -@RunWith(MockitoJUnitRunner::class) class LaunchesViewModelTest { private lateinit var cut: LaunchesViewModel - @Mock + @MockK lateinit var getLaunches: GetLaunches - @Mock + @MockK lateinit var launchesMapper: LaunchesDomainToUiModelMapper - @Mock + @MockK lateinit var clickableLinkProvider: ClickableLinkProvider @Before fun setUp() { Dispatchers.setMain(Dispatchers.Unconfined) - cut = LaunchesViewModel(getLaunches, launchesMapper,clickableLinkProvider) + cut = LaunchesViewModel(getLaunches, launchesMapper, clickableLinkProvider) } @get:Rule @@ -101,18 +97,17 @@ class LaunchesViewModelTest { false ) ) - val flow = flow { + coEvery { getLaunches.execute(0, false) } returns flow { emit(launchDomainModels) } - whenever(getLaunches.execute(0, false)).thenReturn(flow) - whenever(launchesMapper.toUiModel(launchDomainModels)).thenReturn(expected) + coEvery { launchesMapper.toUiModel(launchDomainModels) } returns expected // When cut.launches() val actualValue = cut.viewState.value.launchUiModels // Then - verify(getLaunches, times(2)).execute(0, false) + coVerify(exactly = 2) { getLaunches.execute(0, false) } assertEquals(expected, actualValue) } } @@ -122,17 +117,16 @@ class LaunchesViewModelTest { runBlockingTest { // Given val expectedErrorState = true - val flow = flow { + coEvery { getLaunches.execute(0, false) } returns flow { emit(throw Exception("Network Exception")) } - whenever(getLaunches.execute(0, false)).thenReturn(flow) // When cut.launches() val actualValue = cut.viewState.value.isError // Then - verify(getLaunches, times(2)).execute(0, false) + coVerify(exactly = 2) { getLaunches.execute(0, false) } assertEquals(expectedErrorState, actualValue) } } diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/CompanyInfoUiModelDomainToUiModelMapperTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/CompanyInfoUiModelDomainToUiModelMapperTest.kt index b0077b4..8ce5fe9 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/CompanyInfoUiModelDomainToUiModelMapperTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/CompanyInfoUiModelDomainToUiModelMapperTest.kt @@ -5,7 +5,6 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import prieto.fernando.domain.model.CompanyInfoDomainModel -import prieto.fernando.spacex.presentation.vm.mapper.CompanyInfoDomainToUiModelMapperImpl import prieto.fernando.spacex.presentation.screens.dashboard.CompanyInfoUiModel import kotlin.test.assertEquals diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/DateTransformerImplTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/DateTransformerImplTest.kt index 4109180..acec565 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/DateTransformerImplTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/DateTransformerImplTest.kt @@ -1,21 +1,16 @@ package prieto.fernando.spacex.presentation.vm.mapper -import com.nhaarman.mockito_kotlin.given +import io.mockk.every +import io.mockk.impl.annotations.MockK import org.joda.time.DateTime import org.junit.Before import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnitRunner -import prieto.fernando.spacex.presentation.vm.mapper.DateTimeProvider -import prieto.fernando.spacex.presentation.vm.mapper.DateTransformerImpl import kotlin.test.assertEquals -@RunWith(MockitoJUnitRunner::class) class DateTransformerImplTest { private lateinit var cut: DateTransformerImpl - @Mock + @MockK lateinit var dateTimeProvider: DateTimeProvider @Before @@ -40,7 +35,7 @@ class DateTransformerImplTest { fun `Given date when getDifferenceOfDays then returns expected result`() { // Given val dateTime = DateTime(2022, 1, 2, 4, 3) - given { dateTimeProvider.today() }.willReturn(DateTime(2019, 1, 2, 4, 3)) + every { dateTimeProvider.today() }.returns(DateTime(2019, 1, 2, 4, 3)) val expected = "1096" // When @@ -54,7 +49,7 @@ class DateTransformerImplTest { fun `Given date when isPast then returns expected result`() { // Given val dateTime = DateTime(2018, 1, 2, 4, 3) - given { dateTimeProvider.today() }.willReturn(DateTime(2019, 1, 2, 4, 3)) + every { dateTimeProvider.today() }.returns(DateTime(2019, 1, 2, 4, 3)) val expected = true // When diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt index 124504e..89da6ba 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt @@ -1,35 +1,30 @@ package prieto.fernando.spacex.presentation.vm.mapper -import com.nhaarman.mockito_kotlin.given +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import io.mockk.every +import io.mockk.impl.annotations.MockK import org.junit.Before import org.junit.Rule import org.junit.Test -import org.junit.rules.MethodRule -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnit -import org.mockito.junit.MockitoJUnitRunner +import org.junit.rules.TestRule import prieto.fernando.core_android_test.util.buildDate import prieto.fernando.domain.model.LaunchDomainModel import prieto.fernando.domain.model.LinksDomainModel import prieto.fernando.domain.model.RocketDomainModel -import prieto.fernando.spacex.presentation.vm.mapper.DateTransformer -import prieto.fernando.spacex.presentation.vm.mapper.LaunchesDomainToUiModelMapperImpl import prieto.fernando.spacex.presentation.screens.launches.LaunchUiModel import prieto.fernando.spacex.presentation.screens.launches.LinksUiModel import prieto.fernando.spacex.presentation.screens.launches.RocketUiModel import kotlin.test.assertEquals -@RunWith(MockitoJUnitRunner::class) class LaunchesDomainToUiModelMapperTest { private lateinit var cut: LaunchesDomainToUiModelMapperImpl - @Mock + @MockK lateinit var dateTransformer: DateTransformer @get:Rule - var rule: MethodRule = MockitoJUnit.rule() + var rule: TestRule = InstantTaskExecutorRule() @Before fun setUp() { @@ -85,20 +80,20 @@ class LaunchesDomainToUiModelMapperTest { ) ) - given { dateTransformer.dateToDateString(buildDate("2019-12-11T12:00:00.000Z")) } - .willReturn("11-12-2019 at 12:00") - given { dateTransformer.dateToDateString(buildDate("2020-12-07T12:00:00.000Z")) } - .willReturn("07-12-2020 at 12:00") + every { dateTransformer.dateToDateString(buildDate("2019-12-11T12:00:00.000Z")) } + .returns("11-12-2019 at 12:00") + every { dateTransformer.dateToDateString(buildDate("2020-12-07T12:00:00.000Z")) } + .returns("07-12-2020 at 12:00") - given { dateTransformer.getDifferenceOfDays(buildDate("2019-12-11T12:00:00.000Z")) } - .willReturn("0") - given { dateTransformer.getDifferenceOfDays(buildDate("2020-12-07T12:00:00.000Z")) } - .willReturn("361") + every { dateTransformer.getDifferenceOfDays(buildDate("2019-12-11T12:00:00.000Z")) } + .returns("0") + every { dateTransformer.getDifferenceOfDays(buildDate("2020-12-07T12:00:00.000Z")) } + .returns("361") - given { dateTransformer.isPast(buildDate("2019-12-11T12:00:00.000Z")) } - .willReturn(true) - given { dateTransformer.isPast(buildDate("2020-12-07T12:00:00.000Z")) } - .willReturn(false) + every { dateTransformer.isPast(buildDate("2019-12-11T12:00:00.000Z")) } + .returns(true) + every { dateTransformer.isPast(buildDate("2020-12-07T12:00:00.000Z")) } + .returns(false) // When val actualValue = cut.toUiModel(launches) @@ -136,10 +131,10 @@ class LaunchesDomainToUiModelMapperTest { ) ) - given { dateTransformer.dateToDateString(buildDate("2019-12-13T13:00:00.000Z")) } - .willReturn("13-12-2019 at 13:00") - given { dateTransformer.getDifferenceOfDays(buildDate("2019-12-13T13:00:00.000Z")) } - .willReturn("1") + every { dateTransformer.dateToDateString(buildDate("2019-12-13T13:00:00.000Z")) } + .returns("13-12-2019 at 13:00") + every { dateTransformer.getDifferenceOfDays(buildDate("2019-12-13T13:00:00.000Z")) } + .returns("1") // When val actualValue = cut.toUiModel(launches) diff --git a/build.gradle.kts b/build.gradle.kts index 2797c54..772f359 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,7 +4,7 @@ buildscript { jcenter() } dependencies { - classpath("com.android.tools.build:gradle:7.0.3") + classpath("com.android.tools.build:gradle:7.0.4") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31") classpath("com.google.dagger:hilt-android-gradle-plugin:2.38.1") } diff --git a/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt b/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt index 5304c0d..d3946e6 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt @@ -122,9 +122,8 @@ open class AndroidPlugin : Plugin { testImplementation(TestDependencies.JUnit.junit) testImplementation(TestDependencies.JUnit.junitPlatformRunner) - testImplementation(TestDependencies.Mockito.mockitoCore) - testImplementation(TestDependencies.Mockito.mockitoInline) - testImplementation(TestDependencies.Mockito.mockitoKotlin) + testImplementation(TestDependencies.Mockk.mockk) + testImplementation(TestDependencies.Mockk.mockkAgentJvm) testImplementation(TestDependencies.AndroidX.coreTesting) testImplementation(Dependencies.jodaTime) } diff --git a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/TestDependencies.kt b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/TestDependencies.kt index 57110df..24cd895 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/TestDependencies.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/TestDependencies.kt @@ -40,13 +40,9 @@ object TestDependencies { const val livedataTesting = "com.jraska.livedata:testing-ktx:${Versions.livedataTesting}" - object Mockito { - const val mockitoCore = - "org.mockito:mockito-core:${Versions.mockito}" - const val mockitoInline = - "org.mockito:mockito-inline:${Versions.mockito}" - const val mockitoKotlin = - "com.nhaarman:mockito-kotlin:${Versions.mockitoKotlin}" + object Mockk { + const val mockk ="io.mockk:mockk:${Versions.mockk}" + const val mockkAgentJvm = "io.mockk:mockk-agent-jvm:${Versions.mockk}" } object Hilt{ diff --git a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt index 1f928eb..51512e7 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt @@ -22,8 +22,7 @@ object Versions { const val androidxJunit = "1.1.1" const val junit = "4.13.1" const val junitPlatformRunner = "1.0.2" - const val mockito = "3.12.3" - const val mockitoKotlin = "1.6.0" + const val mockk = "1.12.2" const val gradle = "7.0.3" const val kotlin = "1.5.31" const val timber = "4.7.1" diff --git a/data-api/src/test/java/prieto/fernando/data_api/data/SpaceXRemoteSourceImplTest.kt b/data-api/src/test/java/prieto/fernando/data_api/data/SpaceXRemoteSourceImplTest.kt index 96f4f91..d5ac268 100644 --- a/data-api/src/test/java/prieto/fernando/data_api/data/SpaceXRemoteSourceImplTest.kt +++ b/data-api/src/test/java/prieto/fernando/data_api/data/SpaceXRemoteSourceImplTest.kt @@ -1,50 +1,58 @@ package prieto.fernando.data_api.data import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.times -import com.nhaarman.mockito_kotlin.verify -import com.nhaarman.mockito_kotlin.whenever +import com.google.gson.annotations.SerializedName +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.test.runBlockingTest +import org.joda.time.DateTime import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnitRunner import prieto.fernando.core_android_test.MainCoroutineRule import prieto.fernando.data.SpaceXRemoteSource +import prieto.fernando.data.model.CompanyInfoRepositoryModel +import prieto.fernando.data.model.LaunchRepositoryModel +import prieto.fernando.data.model.LinksRepositoryModel +import prieto.fernando.data.model.RocketRepositoryModel import prieto.fernando.data_api.ApiService import prieto.fernando.data_api.mapper.CompanyInfoResponseToRepositoryModelMapper import prieto.fernando.data_api.mapper.LaunchesResponseToRepositoryModelMapper +import prieto.fernando.data_api.model.CompanyInfoResponse +import prieto.fernando.data_api.model.LaunchesResponse +import prieto.fernando.data_api.model.LinksResponse +import prieto.fernando.data_api.model.RocketResponse +import javax.inject.Inject -@RunWith(MockitoJUnitRunner::class) +@ExperimentalCoroutinesApi class SpaceXRemoteSourceImplTest { private lateinit var cut: SpaceXRemoteSource - @Mock + @Inject lateinit var apiService: ApiService - @Mock + @Inject lateinit var companyInfoRepositoryMapper: CompanyInfoResponseToRepositoryModelMapper - @Mock + @Inject lateinit var launchesRepositoryMapper: LaunchesResponseToRepositoryModelMapper @get:Rule var rule: TestRule = InstantTaskExecutorRule() - @ExperimentalCoroutinesApi @JvmField @Rule val mainCoroutineRule = MainCoroutineRule() - @FlowPreview @Before fun setUp() { + apiService = mockk() + companyInfoRepositoryMapper = mockk() + launchesRepositoryMapper = mockk() + cut = SpaceXRemoteSourceImpl( apiService, companyInfoRepositoryMapper, @@ -52,31 +60,78 @@ class SpaceXRemoteSourceImplTest { ) } - @ExperimentalCoroutinesApi @Test fun `When getCompanyInfo then apiService invoked`() { runBlockingTest { // When - whenever(apiService.getCompanyInfo()).thenReturn(mock()) - + coEvery { apiService.getCompanyInfo() } returns CompanyInfoResponse( + name = "SpaceX", + founder = "Ellon", + founded = "1999", + employees = "Some random employees", + launchSites = 1, + valuation = 100L + ) + coEvery { companyInfoRepositoryMapper.toRepositoryModel(apiService.getCompanyInfo()) } returns CompanyInfoRepositoryModel( + name = "SpaceX", + founder = "Ellon", + founded = "1999", + employees = "Some random employees", + launchSites = 1, + valuation = 100L + ) cut.getCompanyInfo() // Then - verify(apiService, times(1)).getCompanyInfo() + coVerify(exactly = 1) { apiService.getCompanyInfo() } } } - @ExperimentalCoroutinesApi @Test fun `When getAllLaunches then apiService invoked`() { runBlockingTest { + val linksResponse = LinksResponse( + missionPatchSmall = "Some mission patch", + wikipedia = "Link to wikipedia", + videoLink = "Link to Youtube" + ) + val rocketResponse = RocketResponse( + rocketName = "Rocket first", + rocketType = "Type1" + ) + val linksRepositoryModel = LinksRepositoryModel( + missionPatchSmall = "Some mission patch", + wikipedia = "Link to wikipedia", + videoLink = "Link to Youtube" + ) + val rocketRepositoryModel = RocketRepositoryModel( + rocketName = "Rocket first", + rocketType = "Type1" + ) // When - whenever(apiService.getAllLaunches()).thenReturn(mock()) + coEvery { apiService.getAllLaunches() } returns listOf( + LaunchesResponse( + missionName = "First mission", + launchDate = "Some date", + rocket = rocketResponse, + links = linksResponse, + launchSuccess = true + ) + ) + coEvery { launchesRepositoryMapper.toRepositoryModel(apiService.getAllLaunches()) }returns listOf( + LaunchRepositoryModel( + missionName = "First mission", + launchDateLocal = DateTime.now(), + rocket = rocketRepositoryModel, + links = linksRepositoryModel, + launchSuccess = true + ) + ) cut.getAllLaunches() // Then - verify(apiService, times(1)).getAllLaunches() + coVerify(exactly = 1) { apiService.getAllLaunches() } } } } diff --git a/data-api/src/test/java/prieto/fernando/data_api/mapper/LaunchesResponseToRepositoryModelMapperImplTest.kt b/data-api/src/test/java/prieto/fernando/data_api/mapper/LaunchesResponseToRepositoryModelMapperImplTest.kt index cbd31b2..4d6acd8 100644 --- a/data-api/src/test/java/prieto/fernando/data_api/mapper/LaunchesResponseToRepositoryModelMapperImplTest.kt +++ b/data-api/src/test/java/prieto/fernando/data_api/mapper/LaunchesResponseToRepositoryModelMapperImplTest.kt @@ -1,17 +1,17 @@ package prieto.fernando.data_api.mapper +import io.mockk.impl.annotations.MockK import org.joda.time.format.DateTimeFormat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized -import org.mockito.Mock -import prieto.fernando.data_api.model.LaunchesResponse -import prieto.fernando.data_api.model.LinksResponse -import prieto.fernando.data_api.model.RocketResponse import prieto.fernando.data.model.LaunchRepositoryModel import prieto.fernando.data.model.LinksRepositoryModel import prieto.fernando.data.model.RocketRepositoryModel +import prieto.fernando.data_api.model.LaunchesResponse +import prieto.fernando.data_api.model.LinksResponse +import prieto.fernando.data_api.model.RocketResponse import kotlin.test.assertEquals @RunWith(Parameterized::class) @@ -93,7 +93,7 @@ class LaunchesResponseToRepositoryModelMapperImplTest( private lateinit var cut: LaunchesResponseToRepositoryModelMapperImpl - @Mock + @MockK lateinit var dateFormatter: DateFormatter @Before diff --git a/data/src/test/java/prieto/fernando/data/repository/SpaceXRepositoryImplTest.kt b/data/src/test/java/prieto/fernando/data/repository/SpaceXRepositoryImplTest.kt index c46094b..3a71c69 100644 --- a/data/src/test/java/prieto/fernando/data/repository/SpaceXRepositoryImplTest.kt +++ b/data/src/test/java/prieto/fernando/data/repository/SpaceXRepositoryImplTest.kt @@ -1,36 +1,44 @@ package prieto.fernando.data.repository import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.nhaarman.mockito_kotlin.mock -import com.nhaarman.mockito_kotlin.times -import com.nhaarman.mockito_kotlin.verify -import com.nhaarman.mockito_kotlin.whenever +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk +import junit.framework.Assert.assertEquals import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.flow import kotlinx.coroutines.test.runBlockingTest +import org.joda.time.DateTime import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnitRunner import prieto.fernando.core_android_test.MainCoroutineRule import prieto.fernando.data.SpaceXRemoteSource import prieto.fernando.data.mapper.CompanyInfoRepositoryToDomainModelMapper import prieto.fernando.data.mapper.LaunchesRepositoryToDomainModelMapper +import prieto.fernando.data.model.CompanyInfoRepositoryModel +import prieto.fernando.data.model.LaunchRepositoryModel +import prieto.fernando.data.model.LinksRepositoryModel +import prieto.fernando.data.model.RocketRepositoryModel +import prieto.fernando.domain.model.CompanyInfoDomainModel +import prieto.fernando.domain.model.LaunchDomainModel +import prieto.fernando.domain.model.LinksDomainModel +import prieto.fernando.domain.model.RocketDomainModel +import javax.inject.Inject @ExperimentalCoroutinesApi -@RunWith(MockitoJUnitRunner::class) class SpaceXRepositoryImplTest { private lateinit var cut: SpaceXRepositoryImpl - @Mock + @Inject lateinit var spaceXRemoteSource: SpaceXRemoteSource - @Mock + @Inject lateinit var companyInfoDomainMapper: CompanyInfoRepositoryToDomainModelMapper - @Mock + @Inject lateinit var launchesDomainMapper: LaunchesRepositoryToDomainModelMapper @get:Rule @@ -42,6 +50,9 @@ class SpaceXRepositoryImplTest { @Before fun setUp() { + spaceXRemoteSource = mockk() + companyInfoDomainMapper = mockk() + launchesDomainMapper = mockk() cut = SpaceXRepositoryImpl(spaceXRemoteSource, companyInfoDomainMapper, launchesDomainMapper) } @@ -49,26 +60,94 @@ class SpaceXRepositoryImplTest { @Test fun `When getCompanyInfo then spaceXRemoteSource invoked`() { runBlockingTest { + val companyInfoRepositoryModel = CompanyInfoRepositoryModel( + name = "SpaceX", + founder = "Ellon", + founded = "1999", + employees = "Some random employees", + launchSites = 1, + valuation = 100L + ) + val expected = CompanyInfoDomainModel( + name = "SpaceX", + founder = "Ellon", + founded = "1999", + employees = "Some random employees", + launchSites = 1, + valuation = 100L + ) // When - whenever(spaceXRemoteSource.getCompanyInfo()).thenReturn(mock()) + coEvery { spaceXRemoteSource.getCompanyInfo() } returns flow { + emit( + companyInfoRepositoryModel + ) + } + coEvery { companyInfoDomainMapper.toDomainModel(companyInfoRepositoryModel) } returns expected - cut.getCompanyInfo() + val flowActual = cut.getCompanyInfo() // Then - verify(spaceXRemoteSource, times(1)).getCompanyInfo() + coVerify(exactly = 1) { + spaceXRemoteSource.getCompanyInfo() + } + flowActual.collect { actual: CompanyInfoDomainModel -> + assertEquals(expected, actual) + } } } @Test fun `When getAllLaunches then spaceXRemoteSource invoked`() { runBlockingTest { + val date = DateTime.now() + val linksRepositoryModel = LinksRepositoryModel( + missionPatchSmall = "Some mission patch", + wikipedia = "Link to wikipedia", + videoLink = "Link to Youtube" + ) + val rocketRepositoryModel = RocketRepositoryModel( + rocketName = "Rocket first", + rocketType = "Type1" + ) + val launchRepositoryModel = LaunchRepositoryModel( + missionName = "First mission", + launchDateLocal = date, + rocket = rocketRepositoryModel, + links = linksRepositoryModel, + launchSuccess = true + ) + val rocketDomainModel = RocketDomainModel( + rocketName = "Rocket first", + rocketType = "Type1" + ) + val linksDomainModel = LinksDomainModel( + missionPatchSmall = "Some mission patch", + wikipedia = "Link to wikipedia", + videoLink = "Link to Youtube" + ) + val expected = listOf( + LaunchDomainModel( + missionName = "First mission", + launchDate = date, + rocket = rocketDomainModel, + links = linksDomainModel, + launchSuccess = true + ) + ) // When - whenever(spaceXRemoteSource.getAllLaunches()).thenReturn(mock()) - - cut.getAllLaunches() + coEvery { spaceXRemoteSource.getAllLaunches() } returns flow { + emit( + listOf(launchRepositoryModel) + ) + } + coEvery { launchesDomainMapper.toDomainModel(listOf(launchRepositoryModel)) } returns expected + val flowActual = cut.getAllLaunches() // Then - verify(spaceXRemoteSource, times(1)).getAllLaunches() + coVerify(exactly = 1) { spaceXRemoteSource.getAllLaunches() } + flowActual.collect { actual: List -> + assertEquals(expected, actual) + } } } } diff --git a/domain/src/test/java/prieto/fernando/domain/mapper/LaunchesDomainFilterImplTest.kt b/domain/src/test/java/prieto/fernando/domain/mapper/LaunchesDomainFilterImplTest.kt index e309f5f..ef78f28 100644 --- a/domain/src/test/java/prieto/fernando/domain/mapper/LaunchesDomainFilterImplTest.kt +++ b/domain/src/test/java/prieto/fernando/domain/mapper/LaunchesDomainFilterImplTest.kt @@ -1,17 +1,13 @@ package prieto.fernando.domain.mapper -import org.joda.time.format.DateTimeFormat import org.junit.Before import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.junit.MockitoJUnitRunner import prieto.fernando.core_android_test.util.buildDate import prieto.fernando.domain.model.LaunchDomainModel import prieto.fernando.domain.model.LinksDomainModel import prieto.fernando.domain.model.RocketDomainModel import kotlin.test.assertEquals -@RunWith(MockitoJUnitRunner::class) class LaunchesDomainFilterImplTest { private lateinit var cut: LaunchesDomainFilterImpl diff --git a/domain/src/test/java/prieto/fernando/domain/usecase/GetCompanyInfoImplTest.kt b/domain/src/test/java/prieto/fernando/domain/usecase/GetCompanyInfoImplTest.kt index e4f7a65..4b92721 100644 --- a/domain/src/test/java/prieto/fernando/domain/usecase/GetCompanyInfoImplTest.kt +++ b/domain/src/test/java/prieto/fernando/domain/usecase/GetCompanyInfoImplTest.kt @@ -1,23 +1,20 @@ package prieto.fernando.domain.usecase import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.nhaarman.mockito_kotlin.times -import com.nhaarman.mockito_kotlin.verify -import com.nhaarman.mockito_kotlin.whenever +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.impl.annotations.MockK import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.map import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TestRule -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnitRunner import prieto.fernando.core_android_test.MainCoroutineRule import prieto.fernando.domain.SpaceXRepository import prieto.fernando.domain.model.CompanyInfoDomainModel @@ -25,11 +22,10 @@ import kotlin.test.assertEquals @FlowPreview @ExperimentalCoroutinesApi -@RunWith(MockitoJUnitRunner::class) class GetCompanyInfoImplTest { private lateinit var cut: GetCompanyInfoImpl - @Mock + @MockK lateinit var spaceXRepository: SpaceXRepository @get:Rule @@ -66,13 +62,14 @@ class GetCompanyInfoImplTest { 1, 30000 ) - whenever(spaceXRepository.getCompanyInfo()).thenReturn(channelCompanyInfo.asFlow()) + coEvery { spaceXRepository.getCompanyInfo() } returns channelCompanyInfo.asFlow() + // When val actualValue = cut.execute().first() // Then - verify(spaceXRepository, times(1)).getCompanyInfo() + coVerify(exactly = 1) { spaceXRepository.getCompanyInfo() } assertEquals(expected, actualValue) } } diff --git a/domain/src/test/java/prieto/fernando/domain/usecase/GetLaunchesImplTest.kt b/domain/src/test/java/prieto/fernando/domain/usecase/GetLaunchesImplTest.kt index 3894a5c..83a53a5 100644 --- a/domain/src/test/java/prieto/fernando/domain/usecase/GetLaunchesImplTest.kt +++ b/domain/src/test/java/prieto/fernando/domain/usecase/GetLaunchesImplTest.kt @@ -1,8 +1,8 @@ package prieto.fernando.domain.usecase -import com.nhaarman.mockito_kotlin.times -import com.nhaarman.mockito_kotlin.verify -import com.nhaarman.mockito_kotlin.whenever +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.impl.annotations.MockK import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.ConflatedBroadcastChannel import kotlinx.coroutines.flow.asFlow @@ -10,9 +10,6 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.Mock -import org.mockito.junit.MockitoJUnitRunner import prieto.fernando.core_android_test.util.buildDate import prieto.fernando.domain.SpaceXRepository import prieto.fernando.domain.mapper.LaunchesDomainFilter @@ -22,15 +19,14 @@ import prieto.fernando.domain.model.RocketDomainModel import kotlin.test.assertEquals @ExperimentalCoroutinesApi -@RunWith(MockitoJUnitRunner::class) class GetLaunchesImplTest { private lateinit var cut: GetLaunchesImpl - @Mock + @MockK lateinit var spaceXRepository: SpaceXRepository - @Mock + @MockK lateinit var launchesDomainFilter: LaunchesDomainFilter @Before @@ -77,16 +73,20 @@ class GetLaunchesImplTest { ) ) - whenever(spaceXRepository.getAllLaunches()).thenReturn(launchesChannel.asFlow()) - whenever(launchesDomainFilter.filter(launchDomainModels, -1, false)).thenReturn( - launchDomainModels - ) + coEvery { spaceXRepository.getAllLaunches() } returns launchesChannel.asFlow() + coEvery { + launchesDomainFilter.filter( + launchDomainModels, + -1, + false + ) + } returns launchDomainModels // When val actualValue = cut.execute(-1, false).first() // Then - verify(spaceXRepository, times(1)).getAllLaunches() + coVerify(exactly = 1) { spaceXRepository.getAllLaunches() } assertEquals(expected, actualValue) } } From 387d628ea332ecedfb0b84a0f7e406aa235f670e Mon Sep 17 00:00:00 2001 From: Fernando Prieto Moyano Date: Wed, 9 Feb 2022 20:53:07 +0000 Subject: [PATCH 2/4] Added tests and added jacoco plugin --- app/build.gradle.kts | 25 +++++++++++---- .../spacex/presentation/EntryPointActivity.kt | 3 +- .../presentation/vm/DashboardViewModelTest.kt | 28 +++++++++------- .../presentation/vm/LaunchesViewModelTest.kt | 32 +++++++++++-------- .../vm/mapper/DateTransformerImplTest.kt | 6 ++-- .../LaunchesDomainToUiModelMapperTest.kt | 7 ++-- build.gradle.kts | 5 ++- buildSrc/build.gradle.kts | 22 ++++++++++++- .../fernando/android/plugin/AndroidPlugin.kt | 12 ++++--- .../fernando/dependencies/AndroidSettings.kt | 2 +- .../fernando/dependencies/Dependencies.kt | 3 +- .../prieto/fernando/dependencies/Versions.kt | 5 +-- data-api/build.gradle.kts | 2 -- data/build.gradle.kts | 3 +- .../repository/SpaceXRepositoryImplTest.kt | 2 +- .../prieto/fernando/domain/di/DomainModule.kt | 1 - .../fernando/domain/usecase/GetCompanyInfo.kt | 2 -- .../domain/usecase/GetCompanyInfoImplTest.kt | 26 ++++----------- .../domain/usecase/GetLaunchesImplTest.kt | 16 +++++----- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 21 files changed, 122 insertions(+), 84 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f702926..2e629ce 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,16 +1,16 @@ -import prieto.fernando.dependencies.ProjectModules import prieto.fernando.dependencies.Dependencies +import prieto.fernando.dependencies.ProjectModules import prieto.fernando.dependencies.TestDependencies plugins { id("com.android.application") kotlin("android") - kotlin("android.extensions") id("prieto.fernando.android.plugin") id("dagger.hilt.android.plugin") + jacoco } -androidPlugin{ +androidPlugin { buildType = prieto.fernando.android.plugin.BuildType.App } @@ -22,18 +22,28 @@ android { testInstrumentationRunner = "prieto.fernando.spacex.webmock.MockTestRunner" } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = "1.8" + } + buildFeatures { compose = true viewBinding = true } composeOptions { - kotlinCompilerExtensionVersion = prieto.fernando.dependencies.Versions.compose + kotlinCompilerExtensionVersion = "1.0.5" } buildTypes { getByName("debug") { isDebuggable = true + isTestCoverageEnabled = true buildConfigField("Integer", "PORT", "8080") } getByName("release") { @@ -54,7 +64,7 @@ dependencies { implementation(Dependencies.AndroidX.fragmentKtx) implementation(Dependencies.AndroidX.lifecycleLivedataKtx) implementation(Dependencies.AndroidX.Compose.viewModel) - annotationProcessor(Dependencies.AndroidX.lifecycleCompiler) + kapt(Dependencies.AndroidX.lifecycleCompiler) implementation(Dependencies.AndroidX.archComponents) implementation(Dependencies.AndroidX.browser) @@ -68,7 +78,6 @@ dependencies { implementation(Dependencies.Hilt.hiltAndroid) implementation(Dependencies.Hilt.hiltAndroidCompiler) - implementation(Dependencies.Hilt.hiltViewModel) implementation(Dependencies.Hilt.hiltCompiler) implementation(Dependencies.Hilt.hiltNavigationCompose) @@ -100,4 +109,8 @@ dependencies { androidTestImplementation(TestDependencies.Hilt.androidTesting) kaptAndroidTest(TestDependencies.Hilt.androidCompiler) androidTestAnnotationProcessor(TestDependencies.Hilt.androidCompiler) +} + +kapt { + correctErrorTypes = true } \ No newline at end of file diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/EntryPointActivity.kt b/app/src/main/java/prieto/fernando/spacex/presentation/EntryPointActivity.kt index c721448..6ebcb4f 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/EntryPointActivity.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/EntryPointActivity.kt @@ -12,8 +12,7 @@ import prieto.fernando.spacex.theme.SpaceXTheme @AndroidEntryPoint class EntryPointActivity : ComponentActivity() { - @InternalCoroutinesApi - @ExperimentalMaterialApi + @OptIn(InternalCoroutinesApi::class, ExperimentalMaterialApi::class ) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt index f5c7356..e87b646 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt @@ -4,8 +4,8 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every -import io.mockk.impl.annotations.MockK -import junit.framework.Assert.assertEquals +import io.mockk.mockk +import org.junit.Assert.assertEquals import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow @@ -19,20 +19,23 @@ import prieto.fernando.domain.model.CompanyInfoDomainModel import prieto.fernando.domain.usecase.GetCompanyInfo import prieto.fernando.spacex.presentation.screens.dashboard.CompanyInfoUiModel import prieto.fernando.spacex.presentation.vm.mapper.CompanyInfoDomainToUiModelMapper +import javax.inject.Inject @ExperimentalCoroutinesApi class DashboardViewModelTest { private lateinit var cut: DashboardViewModel - @MockK + @Inject lateinit var getCompanyInfo: GetCompanyInfo - @MockK + @Inject lateinit var companyInfoMapper: CompanyInfoDomainToUiModelMapper @Before fun setUp() { Dispatchers.setMain(Dispatchers.Unconfined) + getCompanyInfo = mockk() + companyInfoMapper = mockk() cut = DashboardViewModel(getCompanyInfo, companyInfoMapper) } @@ -74,22 +77,23 @@ class DashboardViewModelTest { assertEquals(expected, actual) } - @Test + @Test(expected = Throwable::class) fun `Given Error When companyInfo Then expected error state`() { runBlockingTest { // Given - val expectedErrorState = true - coEvery { getCompanyInfo.execute() } returns flow { - emit(throw Exception("Network Exception")) - } + var exceptionThrown = false // When - cut.companyInfo() + coEvery { getCompanyInfo.execute() } throws java.lang.Exception("Network exception") + try { + cut.companyInfo() + } catch (exception: Exception) { + exceptionThrown = true + } val actual = cut.viewState.value.isError // Then - coVerify(exactly = 2) { getCompanyInfo } - assertEquals(expectedErrorState, actual) + assertEquals(exceptionThrown, actual) } } } diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt index 5baa9a4..c007a47 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt @@ -3,8 +3,8 @@ package prieto.fernando.spacex.presentation.vm import androidx.arch.core.executor.testing.InstantTaskExecutorRule import io.mockk.coEvery import io.mockk.coVerify -import io.mockk.impl.annotations.MockK -import junit.framework.Assert.assertEquals +import io.mockk.mockk +import org.junit.Assert.assertEquals import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow @@ -24,24 +24,28 @@ import prieto.fernando.spacex.presentation.screens.launches.LinksUiModel import prieto.fernando.spacex.presentation.screens.launches.RocketUiModel import prieto.fernando.spacex.presentation.vm.mapper.ClickableLinkProvider import prieto.fernando.spacex.presentation.vm.mapper.LaunchesDomainToUiModelMapper +import javax.inject.Inject @ExperimentalCoroutinesApi class LaunchesViewModelTest { private lateinit var cut: LaunchesViewModel - @MockK + @Inject lateinit var getLaunches: GetLaunches - @MockK + @Inject lateinit var launchesMapper: LaunchesDomainToUiModelMapper - @MockK + @Inject lateinit var clickableLinkProvider: ClickableLinkProvider @Before fun setUp() { Dispatchers.setMain(Dispatchers.Unconfined) + getLaunches = mockk() + launchesMapper = mockk() + clickableLinkProvider = mockk() cut = LaunchesViewModel(getLaunches, launchesMapper, clickableLinkProvider) } @@ -116,18 +120,20 @@ class LaunchesViewModelTest { fun `Given Error When launches Then expected error state`() { runBlockingTest { // Given - val expectedErrorState = true - coEvery { getLaunches.execute(0, false) } returns flow { - emit(throw Exception("Network Exception")) - } + var exceptionThrown = true // When - cut.launches() - val actualValue = cut.viewState.value.isError + coEvery { getLaunches.execute(0, false) } throws java.lang.Exception("Network Exception") + try { + cut.launches() + } catch (exception: Exception) { + exceptionThrown = true + } + + val actual = cut.viewState.value.isError // Then - coVerify(exactly = 2) { getLaunches.execute(0, false) } - assertEquals(expectedErrorState, actualValue) + assertEquals(exceptionThrown, actual) } } } diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/DateTransformerImplTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/DateTransformerImplTest.kt index acec565..8bb586b 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/DateTransformerImplTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/DateTransformerImplTest.kt @@ -1,20 +1,22 @@ package prieto.fernando.spacex.presentation.vm.mapper import io.mockk.every -import io.mockk.impl.annotations.MockK +import io.mockk.mockk import org.joda.time.DateTime import org.junit.Before import org.junit.Test +import javax.inject.Inject import kotlin.test.assertEquals class DateTransformerImplTest { private lateinit var cut: DateTransformerImpl - @MockK + @Inject lateinit var dateTimeProvider: DateTimeProvider @Before fun setUp() { + dateTimeProvider = mockk() cut = DateTransformerImpl(dateTimeProvider) } diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt index 89da6ba..3fc6156 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt @@ -2,7 +2,7 @@ package prieto.fernando.spacex.presentation.vm.mapper import androidx.arch.core.executor.testing.InstantTaskExecutorRule import io.mockk.every -import io.mockk.impl.annotations.MockK +import io.mockk.mockk import org.junit.Before import org.junit.Rule import org.junit.Test @@ -14,13 +14,14 @@ import prieto.fernando.domain.model.RocketDomainModel import prieto.fernando.spacex.presentation.screens.launches.LaunchUiModel import prieto.fernando.spacex.presentation.screens.launches.LinksUiModel import prieto.fernando.spacex.presentation.screens.launches.RocketUiModel +import javax.inject.Inject import kotlin.test.assertEquals class LaunchesDomainToUiModelMapperTest { private lateinit var cut: LaunchesDomainToUiModelMapperImpl - @MockK + @Inject lateinit var dateTransformer: DateTransformer @get:Rule @@ -28,6 +29,7 @@ class LaunchesDomainToUiModelMapperTest { @Before fun setUp() { + dateTransformer = mockk() cut = LaunchesDomainToUiModelMapperImpl(dateTransformer) } @@ -135,6 +137,7 @@ class LaunchesDomainToUiModelMapperTest { .returns("13-12-2019 at 13:00") every { dateTransformer.getDifferenceOfDays(buildDate("2019-12-13T13:00:00.000Z")) } .returns("1") + every { dateTransformer.isPast(buildDate("2019-12-13T13:00:00.000Z")) }.returns(false) // When val actualValue = cut.toUiModel(launches) diff --git a/build.gradle.kts b/build.gradle.kts index 772f359..b097f62 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,3 +1,5 @@ +import prieto.fernando.dependencies.Versions.jacoco + buildscript { repositories { google() @@ -7,6 +9,7 @@ buildscript { classpath("com.android.tools.build:gradle:7.0.4") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31") classpath("com.google.dagger:hilt-android-gradle-plugin:2.38.1") + classpath("org.jacoco:org.jacoco.core:0.8.7") } } @@ -20,4 +23,4 @@ allprojects { task("clean") { delete(rootProject.buildDir) -} +} \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 2ab56df..f78f269 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -6,12 +6,32 @@ repositories { plugins { `kotlin-dsl` + jacoco } dependencies { implementation(kotlin("stdlib")) - implementation("com.android.tools.build:gradle:7.0.3") + implementation("com.android.tools.build:gradle:7.1.0") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31") implementation(gradleApi()) + implementation(kotlin("script-runtime")) +} + +tasks.test { + finalizedBy(tasks.jacocoTestReport) +} + +tasks.jacocoTestReport { + dependsOn(tasks.test) +} + +tasks.jacocoTestReport { + reports { + xml.required.set(false) + csv.required.set(false) + html.outputLocation.set(layout.buildDirectory.dir("jacocoHtml")) + } + + finalizedBy("jacocoTestCoverageVerification") } diff --git a/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt b/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt index d3946e6..dcb09e0 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt @@ -4,10 +4,10 @@ import prieto.fernando.dependencies.AndroidSettings import prieto.fernando.dependencies.Dependencies import prieto.fernando.dependencies.TestDependencies import com.android.build.gradle.BaseExtension +import org.gradle.api.JavaVersion import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.* -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile open class AndroidPlugin : Plugin { override fun apply(project: Project) { @@ -20,8 +20,7 @@ open class AndroidPlugin : Plugin { } private fun androidPlugins() = listOf( - "kotlin-android", - "kotlin-android-extensions" + "kotlin-android" ) private fun Project.configurePlugins(buildType: BuildType) = listOf( @@ -42,7 +41,7 @@ open class AndroidPlugin : Plugin { versionCode = 1 versionName = "1.0" - testInstrumentationRunner = AndroidSettings.testInstrumentationRunner + testInstrumentationRunner = "prieto.fernando.spacex.webmock.MockTestRunner" packagingOptions { resources.excludes.addAll( @@ -63,6 +62,11 @@ open class AndroidPlugin : Plugin { ) } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + buildTypes { getByName("debug") { isDebuggable = true diff --git a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/AndroidSettings.kt b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/AndroidSettings.kt index 6ae4391..9a1690a 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/AndroidSettings.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/AndroidSettings.kt @@ -3,7 +3,7 @@ package prieto.fernando.dependencies object AndroidSettings { const val appVersionName = "0.1" const val compileSdk = 31 - const val buildTools = "30.0.3" + const val buildTools = "31.0.0" const val minSdk = 26 const val targetSdk = 31 const val testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" diff --git a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Dependencies.kt b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Dependencies.kt index 69304c1..b906674 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Dependencies.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Dependencies.kt @@ -66,8 +66,6 @@ object Dependencies { "com.google.dagger:hilt-android-compiler:${Versions.hilt}" const val hiltCompiler = "androidx.hilt:hilt-compiler:${Versions.hiltJetpack}" - const val hiltViewModel = - "com.google.dagger:hilt-android-compiler:${Versions.hiltVM}" const val hiltNavigationCompose = "androidx.hilt:hilt-navigation-compose:${Versions.hiltVM}" } @@ -89,4 +87,5 @@ object Dependencies { const val coilCompose = "io.coil-kt:coil-compose:${Versions.coil}" const val jodaTime = "joda-time:joda-time:${Versions.jodaTime}" + } diff --git a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt index 51512e7..c88b8b7 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt @@ -13,7 +13,7 @@ object Versions { const val lifecycleLivedataKtx = "2.2.0" const val livedataTesting = "1.1.1" const val dagger = "2.24" - const val hilt = "2.37" + const val hilt = "2.40.4" const val hiltJetpack = "1.0.0-alpha02" const val hiltVM = "1.0.0-alpha03" const val hiltTest = "2.37" @@ -21,9 +21,10 @@ object Versions { const val espresso = "3.4.0" const val androidxJunit = "1.1.1" const val junit = "4.13.1" + const val jacoco = "0.8.7" const val junitPlatformRunner = "1.0.2" const val mockk = "1.12.2" - const val gradle = "7.0.3" + const val gradle = "7.1.0" const val kotlin = "1.5.31" const val timber = "4.7.1" const val lottie = "4.2.0" diff --git a/data-api/build.gradle.kts b/data-api/build.gradle.kts index 23a1f15..b93cda8 100644 --- a/data-api/build.gradle.kts +++ b/data-api/build.gradle.kts @@ -1,6 +1,5 @@ import prieto.fernando.dependencies.Dependencies import prieto.fernando.dependencies.ProjectModules -import prieto.fernando.dependencies.ProjectModules.api plugins { id("com.android.library") @@ -19,6 +18,5 @@ dependencies { implementation(Dependencies.Hilt.hiltAndroidCompiler) implementation(Dependencies.jodaTime) - testImplementation(Dependencies.jodaTime) } \ No newline at end of file diff --git a/data/build.gradle.kts b/data/build.gradle.kts index 2fffc26..13ce856 100644 --- a/data/build.gradle.kts +++ b/data/build.gradle.kts @@ -10,8 +10,9 @@ dependencies { implementation(project(ProjectModules.domain)) testImplementation(project(ProjectModules.coreAndroidTest)) - implementation(Dependencies.jodaTime) implementation(Dependencies.Hilt.hiltAndroid) implementation(Dependencies.Hilt.hiltAndroidCompiler) + + implementation(Dependencies.jodaTime) testImplementation(Dependencies.jodaTime) } \ No newline at end of file diff --git a/data/src/test/java/prieto/fernando/data/repository/SpaceXRepositoryImplTest.kt b/data/src/test/java/prieto/fernando/data/repository/SpaceXRepositoryImplTest.kt index 3a71c69..69d4a74 100644 --- a/data/src/test/java/prieto/fernando/data/repository/SpaceXRepositoryImplTest.kt +++ b/data/src/test/java/prieto/fernando/data/repository/SpaceXRepositoryImplTest.kt @@ -4,7 +4,7 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import io.mockk.coEvery import io.mockk.coVerify import io.mockk.mockk -import junit.framework.Assert.assertEquals +import org.junit.Assert.assertEquals import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.flow diff --git a/domain/src/main/java/prieto/fernando/domain/di/DomainModule.kt b/domain/src/main/java/prieto/fernando/domain/di/DomainModule.kt index efd624a..2538cf6 100644 --- a/domain/src/main/java/prieto/fernando/domain/di/DomainModule.kt +++ b/domain/src/main/java/prieto/fernando/domain/di/DomainModule.kt @@ -4,7 +4,6 @@ import dagger.Module import dagger.Provides import dagger.Reusable import dagger.hilt.InstallIn -import dagger.hilt.android.components.ViewModelComponent import dagger.hilt.components.SingletonComponent import prieto.fernando.domain.SpaceXRepository import prieto.fernando.domain.mapper.LaunchesDomainFilter diff --git a/domain/src/main/java/prieto/fernando/domain/usecase/GetCompanyInfo.kt b/domain/src/main/java/prieto/fernando/domain/usecase/GetCompanyInfo.kt index 5734a30..40f9871 100644 --- a/domain/src/main/java/prieto/fernando/domain/usecase/GetCompanyInfo.kt +++ b/domain/src/main/java/prieto/fernando/domain/usecase/GetCompanyInfo.kt @@ -1,10 +1,8 @@ package prieto.fernando.domain.usecase import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.catch import prieto.fernando.domain.SpaceXRepository import prieto.fernando.domain.model.CompanyInfoDomainModel -import java.net.UnknownHostException import javax.inject.Inject interface GetCompanyInfo { diff --git a/domain/src/test/java/prieto/fernando/domain/usecase/GetCompanyInfoImplTest.kt b/domain/src/test/java/prieto/fernando/domain/usecase/GetCompanyInfoImplTest.kt index 4b92721..fee740d 100644 --- a/domain/src/test/java/prieto/fernando/domain/usecase/GetCompanyInfoImplTest.kt +++ b/domain/src/test/java/prieto/fernando/domain/usecase/GetCompanyInfoImplTest.kt @@ -3,13 +3,12 @@ package prieto.fernando.domain.usecase import androidx.arch.core.executor.testing.InstantTaskExecutorRule import io.mockk.coEvery import io.mockk.coVerify -import io.mockk.every import io.mockk.impl.annotations.MockK +import io.mockk.mockk import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview -import kotlinx.coroutines.channels.ConflatedBroadcastChannel -import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Rule @@ -18,14 +17,14 @@ import org.junit.rules.TestRule import prieto.fernando.core_android_test.MainCoroutineRule import prieto.fernando.domain.SpaceXRepository import prieto.fernando.domain.model.CompanyInfoDomainModel -import kotlin.test.assertEquals +import javax.inject.Inject @FlowPreview @ExperimentalCoroutinesApi class GetCompanyInfoImplTest { private lateinit var cut: GetCompanyInfoImpl - @MockK + @Inject lateinit var spaceXRepository: SpaceXRepository @get:Rule @@ -37,6 +36,7 @@ class GetCompanyInfoImplTest { @Before fun setUp() { + spaceXRepository = mockk() cut = GetCompanyInfoImpl(spaceXRepository) } @@ -52,25 +52,13 @@ class GetCompanyInfoImplTest { 1, 30000 ) - val channelCompanyInfo = ConflatedBroadcastChannel() - channelCompanyInfo.offer(companyInfoDomainModel) - val expected = CompanyInfoDomainModel( - "name", - "founder", - "foundedYear", - "employees", - 1, - 30000 - ) - coEvery { spaceXRepository.getCompanyInfo() } returns channelCompanyInfo.asFlow() - + coEvery { spaceXRepository.getCompanyInfo() } returns flowOf(companyInfoDomainModel) // When - val actualValue = cut.execute().first() + cut.execute().first() // Then coVerify(exactly = 1) { spaceXRepository.getCompanyInfo() } - assertEquals(expected, actualValue) } } } diff --git a/domain/src/test/java/prieto/fernando/domain/usecase/GetLaunchesImplTest.kt b/domain/src/test/java/prieto/fernando/domain/usecase/GetLaunchesImplTest.kt index 83a53a5..7ab8f92 100644 --- a/domain/src/test/java/prieto/fernando/domain/usecase/GetLaunchesImplTest.kt +++ b/domain/src/test/java/prieto/fernando/domain/usecase/GetLaunchesImplTest.kt @@ -2,11 +2,10 @@ package prieto.fernando.domain.usecase import io.mockk.coEvery import io.mockk.coVerify -import io.mockk.impl.annotations.MockK +import io.mockk.mockk import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.ConflatedBroadcastChannel -import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Test @@ -16,21 +15,24 @@ import prieto.fernando.domain.mapper.LaunchesDomainFilter import prieto.fernando.domain.model.LaunchDomainModel import prieto.fernando.domain.model.LinksDomainModel import prieto.fernando.domain.model.RocketDomainModel +import javax.inject.Inject import kotlin.test.assertEquals @ExperimentalCoroutinesApi class GetLaunchesImplTest { private lateinit var cut: GetLaunchesImpl - @MockK + @Inject lateinit var spaceXRepository: SpaceXRepository - @MockK + @Inject lateinit var launchesDomainFilter: LaunchesDomainFilter @Before fun setUp() { + spaceXRepository = mockk() + launchesDomainFilter = mockk() cut = GetLaunchesImpl(spaceXRepository, launchesDomainFilter) } @@ -54,8 +56,6 @@ class GetLaunchesImplTest { false ) ) - val launchesChannel = ConflatedBroadcastChannel>() - launchesChannel.offer(launchDomainModels) val expected = listOf( LaunchDomainModel( "missionName", @@ -73,7 +73,7 @@ class GetLaunchesImplTest { ) ) - coEvery { spaceXRepository.getAllLaunches() } returns launchesChannel.asFlow() + coEvery { spaceXRepository.getAllLaunches() } returns flowOf(launchDomainModels) coEvery { launchesDomainFilter.filter( launchDomainModels, diff --git a/gradle.properties b/gradle.properties index 379fe29..fea639e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,4 +18,4 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official +kotlin.code.style=official \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8f73ac0..d29702c 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-7.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip From b83d491e1753d345fd6be122da7135f36ece97e2 Mon Sep 17 00:00:00 2001 From: ferPrieto Date: Thu, 10 Feb 2022 19:56:49 +0000 Subject: [PATCH 3/4] Deleted jacoco --- app/build.gradle.kts | 16 +-------------- build.gradle.kts | 3 --- buildSrc/build.gradle.kts | 20 ------------------- .../prieto/fernando/dependencies/Versions.kt | 1 - 4 files changed, 1 insertion(+), 39 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2e629ce..91db42c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -7,7 +7,6 @@ plugins { kotlin("android") id("prieto.fernando.android.plugin") id("dagger.hilt.android.plugin") - jacoco } androidPlugin { @@ -22,15 +21,6 @@ android { testInstrumentationRunner = "prieto.fernando.spacex.webmock.MockTestRunner" } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = "1.8" - } - buildFeatures { compose = true viewBinding = true @@ -64,7 +54,7 @@ dependencies { implementation(Dependencies.AndroidX.fragmentKtx) implementation(Dependencies.AndroidX.lifecycleLivedataKtx) implementation(Dependencies.AndroidX.Compose.viewModel) - kapt(Dependencies.AndroidX.lifecycleCompiler) + annotationProcessor(Dependencies.AndroidX.lifecycleCompiler) implementation(Dependencies.AndroidX.archComponents) implementation(Dependencies.AndroidX.browser) @@ -109,8 +99,4 @@ dependencies { androidTestImplementation(TestDependencies.Hilt.androidTesting) kaptAndroidTest(TestDependencies.Hilt.androidCompiler) androidTestAnnotationProcessor(TestDependencies.Hilt.androidCompiler) -} - -kapt { - correctErrorTypes = true } \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index b097f62..4467a7e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,3 @@ -import prieto.fernando.dependencies.Versions.jacoco - buildscript { repositories { google() @@ -9,7 +7,6 @@ buildscript { classpath("com.android.tools.build:gradle:7.0.4") classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31") classpath("com.google.dagger:hilt-android-gradle-plugin:2.38.1") - classpath("org.jacoco:org.jacoco.core:0.8.7") } } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index f78f269..3d24697 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -6,7 +6,6 @@ repositories { plugins { `kotlin-dsl` - jacoco } dependencies { @@ -15,23 +14,4 @@ dependencies { implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31") implementation(gradleApi()) - implementation(kotlin("script-runtime")) -} - -tasks.test { - finalizedBy(tasks.jacocoTestReport) -} - -tasks.jacocoTestReport { - dependsOn(tasks.test) -} - -tasks.jacocoTestReport { - reports { - xml.required.set(false) - csv.required.set(false) - html.outputLocation.set(layout.buildDirectory.dir("jacocoHtml")) - } - - finalizedBy("jacocoTestCoverageVerification") } diff --git a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt index c88b8b7..8e3c295 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt @@ -21,7 +21,6 @@ object Versions { const val espresso = "3.4.0" const val androidxJunit = "1.1.1" const val junit = "4.13.1" - const val jacoco = "0.8.7" const val junitPlatformRunner = "1.0.2" const val mockk = "1.12.2" const val gradle = "7.1.0" From 073f7e62db3345fce7c92421d503d5ba26daa101 Mon Sep 17 00:00:00 2001 From: ferPrieto Date: Thu, 10 Feb 2022 20:46:11 +0000 Subject: [PATCH 4/4] Added JLLeitschuh ktlint-gradle plugin --- app/build.gradle.kts | 5 ++-- .../fernando/spacex/di/FakeNetworkModule.kt | 2 +- .../presentation/screens/MainScreenKtTest.kt | 3 +-- .../screens/base/BaseScreenTest.kt | 2 +- .../screens/dashboard/DashboardScreenTest.kt | 2 +- .../screens/launches/LaunchesScreenKtTest.kt | 25 ++++++++++++------- .../screens/launches/LaunchesScreenRobot.kt | 15 +++++------ .../spacex/webmock/AssetReaderUtil.kt | 2 +- .../spacex/webmock/ErrorDispatcher.kt | 2 +- .../fernando/spacex/webmock/MockTestRunner.kt | 2 +- .../spacex/webmock/SuccessDispatcher.kt | 2 +- .../prieto/fernando/spacex/BaseApplication.kt | 2 +- .../java/prieto/fernando/spacex/SpaceXApp.kt | 1 - .../prieto/fernando/spacex/di/AppModule.kt | 6 ----- .../spacex/presentation/EntryPointActivity.kt | 2 +- .../navigation/BottomNavigationScreens.kt | 2 +- .../spacex/presentation/screens/MainScreen.kt | 23 +++++++++-------- .../screens/common/ErrorAnimation.kt | 2 +- .../screens/dashboard/CompanyInfoUiModel.kt | 2 +- .../screens/dashboard/DashboardContract.kt | 2 +- .../screens/dashboard/DashboardScreen.kt | 6 ++--- .../screens/launches/LaunchesContract.kt | 2 +- .../screens/launches/LaunchesScreen.kt | 10 +++++--- .../presentation/vm/DashboardViewModel.kt | 4 +-- .../presentation/vm/LaunchesViewModel.kt | 3 +-- .../presentation/vm/base/BaseComponents.kt | 10 ++++---- .../presentation/vm/di/PresentationModule.kt | 2 +- .../vm/mapper/ClickableLinkProvider.kt | 2 +- .../vm/mapper/DateTimeProvider.kt | 2 +- .../presentation/vm/DashboardViewModelTest.kt | 2 +- .../presentation/vm/LaunchesViewModelTest.kt | 3 +-- .../vm/mapper/ClickableLinkProviderTest.kt | 18 +++++++------ ...anyInfoUiModelDomainToUiModelMapperTest.kt | 9 ++++--- .../LaunchesDomainToUiModelMapperTest.kt | 1 - build.gradle.kts | 1 + buildSrc/build.gradle.kts | 1 + .../fernando/android/plugin/AndroidPlugin.kt | 4 --- .../fernando/dependencies/Dependencies.kt | 2 +- .../prieto/fernando/dependencies/Versions.kt | 1 + 39 files changed, 97 insertions(+), 90 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 91db42c..58ab65e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -7,6 +7,7 @@ plugins { kotlin("android") id("prieto.fernando.android.plugin") id("dagger.hilt.android.plugin") + id("org.jlleitschuh.gradle.ktlint") version "10.2.1" } androidPlugin { @@ -54,7 +55,7 @@ dependencies { implementation(Dependencies.AndroidX.fragmentKtx) implementation(Dependencies.AndroidX.lifecycleLivedataKtx) implementation(Dependencies.AndroidX.Compose.viewModel) - annotationProcessor(Dependencies.AndroidX.lifecycleCompiler) + kapt(Dependencies.AndroidX.lifecycleCompiler) implementation(Dependencies.AndroidX.archComponents) implementation(Dependencies.AndroidX.browser) @@ -99,4 +100,4 @@ dependencies { androidTestImplementation(TestDependencies.Hilt.androidTesting) kaptAndroidTest(TestDependencies.Hilt.androidCompiler) androidTestAnnotationProcessor(TestDependencies.Hilt.androidCompiler) -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/prieto/fernando/spacex/di/FakeNetworkModule.kt b/app/src/androidTest/java/prieto/fernando/spacex/di/FakeNetworkModule.kt index 97419ef..b684a56 100644 --- a/app/src/androidTest/java/prieto/fernando/spacex/di/FakeNetworkModule.kt +++ b/app/src/androidTest/java/prieto/fernando/spacex/di/FakeNetworkModule.kt @@ -13,4 +13,4 @@ import prieto.fernando.data_api.di.NetworkModule ) class FakeNetworkModule : NetworkModule() { override fun getBaseUrl() = "http://127.0.0.1:${BuildConfig.PORT}" -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/MainScreenKtTest.kt b/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/MainScreenKtTest.kt index f154ef8..1a90ea6 100644 --- a/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/MainScreenKtTest.kt +++ b/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/MainScreenKtTest.kt @@ -12,7 +12,6 @@ import org.junit.runner.RunWith import prieto.fernando.spacex.presentation.screens.base.BaseScreenTest import prieto.fernando.spacex.webmock.SuccessDispatcher - @ExperimentalMaterialApi @RunWith(AndroidJUnit4::class) @HiltAndroidTest @@ -47,4 +46,4 @@ class MainScreenKtTest : BaseScreenTest() { .performClick() composeTestRule.onNodeWithText("LAUNCHES", useUnmergedTree = true).assertIsDisplayed() } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/base/BaseScreenTest.kt b/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/base/BaseScreenTest.kt index e89d259..cc1309a 100644 --- a/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/base/BaseScreenTest.kt +++ b/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/base/BaseScreenTest.kt @@ -42,4 +42,4 @@ open class BaseScreenTest { } } } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardScreenTest.kt b/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardScreenTest.kt index eb7cf6c..0a7e085 100644 --- a/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardScreenTest.kt +++ b/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardScreenTest.kt @@ -42,4 +42,4 @@ class DashboardScreenTest : BaseScreenTest() { onNodeWithContentDescription("404 Animation").assertIsDisplayed() } } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreenKtTest.kt b/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreenKtTest.kt index 57e0abb..1e3d931 100644 --- a/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreenKtTest.kt +++ b/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreenKtTest.kt @@ -28,7 +28,7 @@ class LaunchesScreenKtTest : BaseScreenTest() { mockWebServer.dispatcher = SuccessDispatcher() setMainContent() - launchesScreenRobot(composeTestRule) { + launchesScreenRobot(composeTestRule) { clickOnLaunchesTab() initialElementsShowed() } @@ -94,7 +94,8 @@ class LaunchesScreenKtTest : BaseScreenTest() { onEventSent = {}, effectFlow = flow { emit(LaunchesContract.Effect.ClickableLink.None) }, onLinkClicked = { }, - onClickableLinkRetrieved = { }) + onClickableLinkRetrieved = { } + ) } } @@ -119,23 +120,29 @@ class LaunchesScreenKtTest : BaseScreenTest() { state = LaunchesContract.State( listOf( LaunchUiModel( - "Mission1", "08-12-2021", true, "0", RocketUiModel( + "Mission1", "08-12-2021", true, "0", + RocketUiModel( "Rocket1", "Rocket Type1" - ), LinksUiModel("", "", "Youtube Link"), true + ), + LinksUiModel("", "", "Youtube Link"), true ), LaunchUiModel( - "Mission2", "09-12-2021", false, "0", RocketUiModel( + "Mission2", "09-12-2021", false, "0", + RocketUiModel( "Rocket2", "Rocket Type2" - ), LinksUiModel("", "WikiPedia Link", "Youtube Link"), false + ), + LinksUiModel("", "WikiPedia Link", "Youtube Link"), false ) - ), isLoading = false, isError = false + ), + isLoading = false, isError = false ), bottomSheetScaffoldState = bottomSheetScaffoldState, coroutineScope = coroutineScope, onEventSent = {}, effectFlow = flow { emit(LaunchesContract.Effect.ClickableLink.None) }, onLinkClicked = { }, - onClickableLinkRetrieved = { }) + onClickableLinkRetrieved = { } + ) } } @@ -145,4 +152,4 @@ class LaunchesScreenKtTest : BaseScreenTest() { } } } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreenRobot.kt b/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreenRobot.kt index 999c35b..aa7bc80 100644 --- a/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreenRobot.kt +++ b/app/src/androidTest/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreenRobot.kt @@ -1,12 +1,13 @@ package prieto.fernando.spacex.presentation.screens.launches -import androidx.compose.ui.test.* +import androidx.compose.ui.test.assertCountEquals +import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.junit4.AndroidComposeTestRule -import androidx.test.espresso.Espresso.onView -import androidx.test.espresso.assertion.ViewAssertions.matches -import androidx.test.espresso.matcher.ViewMatchers.* +import androidx.compose.ui.test.onAllNodesWithContentDescription +import androidx.compose.ui.test.onNodeWithContentDescription +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick import androidx.test.ext.junit.rules.ActivityScenarioRule -import kotlinx.coroutines.InternalCoroutinesApi import prieto.fernando.spacex.presentation.EntryPointActivity internal fun launchesScreenRobot( @@ -93,8 +94,8 @@ internal open class LaunchesScreenRobot constructor( listItemsShowed(0) } - fun missionOneAndTwoShowed(){ + fun missionOneAndTwoShowed() { missionOneText.assertIsDisplayed() missionTwoText.assertIsDisplayed() } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/prieto/fernando/spacex/webmock/AssetReaderUtil.kt b/app/src/androidTest/java/prieto/fernando/spacex/webmock/AssetReaderUtil.kt index 18170b4..9938ee2 100644 --- a/app/src/androidTest/java/prieto/fernando/spacex/webmock/AssetReaderUtil.kt +++ b/app/src/androidTest/java/prieto/fernando/spacex/webmock/AssetReaderUtil.kt @@ -23,4 +23,4 @@ object AssetReaderUtil { } return builder.toString() } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/prieto/fernando/spacex/webmock/ErrorDispatcher.kt b/app/src/androidTest/java/prieto/fernando/spacex/webmock/ErrorDispatcher.kt index f1085da..b5ce646 100644 --- a/app/src/androidTest/java/prieto/fernando/spacex/webmock/ErrorDispatcher.kt +++ b/app/src/androidTest/java/prieto/fernando/spacex/webmock/ErrorDispatcher.kt @@ -8,4 +8,4 @@ class ErrorDispatcher : Dispatcher() { override fun dispatch(request: RecordedRequest): MockResponse { return MockResponse().setResponseCode(404) } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/prieto/fernando/spacex/webmock/MockTestRunner.kt b/app/src/androidTest/java/prieto/fernando/spacex/webmock/MockTestRunner.kt index a0dc60a..ccb8eb2 100644 --- a/app/src/androidTest/java/prieto/fernando/spacex/webmock/MockTestRunner.kt +++ b/app/src/androidTest/java/prieto/fernando/spacex/webmock/MockTestRunner.kt @@ -20,4 +20,4 @@ class MockTestRunner : AndroidJUnitRunner() { ): Application { return super.newApplication(cl, HiltTestApplication::class.java.name, context) } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/prieto/fernando/spacex/webmock/SuccessDispatcher.kt b/app/src/androidTest/java/prieto/fernando/spacex/webmock/SuccessDispatcher.kt index 1aacde7..7420171 100644 --- a/app/src/androidTest/java/prieto/fernando/spacex/webmock/SuccessDispatcher.kt +++ b/app/src/androidTest/java/prieto/fernando/spacex/webmock/SuccessDispatcher.kt @@ -35,4 +35,4 @@ class SuccessDispatcher( errorResponse } } -} \ No newline at end of file +} diff --git a/app/src/main/java/prieto/fernando/spacex/BaseApplication.kt b/app/src/main/java/prieto/fernando/spacex/BaseApplication.kt index 5af6ea0..d16cbc4 100644 --- a/app/src/main/java/prieto/fernando/spacex/BaseApplication.kt +++ b/app/src/main/java/prieto/fernando/spacex/BaseApplication.kt @@ -2,4 +2,4 @@ package prieto.fernando.spacex import android.app.Application -open class BaseApplication : Application() \ No newline at end of file +open class BaseApplication : Application() diff --git a/app/src/main/java/prieto/fernando/spacex/SpaceXApp.kt b/app/src/main/java/prieto/fernando/spacex/SpaceXApp.kt index 3e0f279..89bc2de 100644 --- a/app/src/main/java/prieto/fernando/spacex/SpaceXApp.kt +++ b/app/src/main/java/prieto/fernando/spacex/SpaceXApp.kt @@ -1,7 +1,6 @@ package prieto.fernando.spacex import dagger.hilt.android.HiltAndroidApp -import android.app.Application @HiltAndroidApp class SpaceXApp : BaseApplication() diff --git a/app/src/main/java/prieto/fernando/spacex/di/AppModule.kt b/app/src/main/java/prieto/fernando/spacex/di/AppModule.kt index ceb7dc7..b398837 100644 --- a/app/src/main/java/prieto/fernando/spacex/di/AppModule.kt +++ b/app/src/main/java/prieto/fernando/spacex/di/AppModule.kt @@ -1,15 +1,9 @@ package prieto.fernando.spacex.di -import android.app.Application -import android.content.Context -import android.content.res.Resources import dagger.Module -import dagger.Provides import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent - @Module @InstallIn(SingletonComponent::class) open class AppModule { diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/EntryPointActivity.kt b/app/src/main/java/prieto/fernando/spacex/presentation/EntryPointActivity.kt index 6ebcb4f..f5517ac 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/EntryPointActivity.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/EntryPointActivity.kt @@ -12,7 +12,7 @@ import prieto.fernando.spacex.theme.SpaceXTheme @AndroidEntryPoint class EntryPointActivity : ComponentActivity() { - @OptIn(InternalCoroutinesApi::class, ExperimentalMaterialApi::class ) + @OptIn(InternalCoroutinesApi::class, ExperimentalMaterialApi::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/navigation/BottomNavigationScreens.kt b/app/src/main/java/prieto/fernando/spacex/presentation/navigation/BottomNavigationScreens.kt index 09ab5a4..6870a65 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/navigation/BottomNavigationScreens.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/navigation/BottomNavigationScreens.kt @@ -20,4 +20,4 @@ sealed class BottomNavigationScreens( R.string.tab_title_launches, R.drawable.ic_launches ) -} \ No newline at end of file +} diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/screens/MainScreen.kt b/app/src/main/java/prieto/fernando/spacex/presentation/screens/MainScreen.kt index e485a73..b1736fc 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/screens/MainScreen.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/screens/MainScreen.kt @@ -21,7 +21,6 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel @@ -34,15 +33,15 @@ import com.google.accompanist.systemuicontroller.rememberSystemUiController import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.InternalCoroutinesApi import prieto.fernando.spacex.R +import prieto.fernando.spacex.presentation.navigation.BottomNavigationScreens import prieto.fernando.spacex.presentation.screens.dashboard.DashboardScreen import prieto.fernando.spacex.presentation.screens.launches.LaunchesContract import prieto.fernando.spacex.presentation.screens.launches.LaunchesScreen -import prieto.fernando.spacex.presentation.navigation.BottomNavigationScreens +import prieto.fernando.spacex.presentation.vm.DashboardViewModel +import prieto.fernando.spacex.presentation.vm.LaunchesViewModel import prieto.fernando.spacex.theme.Dark import prieto.fernando.spacex.theme.Light import prieto.fernando.spacex.theme.SpaceXTypography -import prieto.fernando.spacex.presentation.vm.DashboardViewModel -import prieto.fernando.spacex.presentation.vm.LaunchesViewModel @InternalCoroutinesApi @ExperimentalMaterialApi @@ -167,16 +166,19 @@ private fun BottomSheet( youTubeLinkState.value = effect.youTubeLink wikipediaLinkState.value = effect.wikipedia } - is LaunchesContract.Effect.ClickableLink.Youtube -> youTubeLinkState.value = - effect.youTubeLink - is LaunchesContract.Effect.ClickableLink.Wikipedia -> wikipediaLinkState.value = - effect.wikipedia + is LaunchesContract.Effect.ClickableLink.Youtube -> + youTubeLinkState.value = + effect.youTubeLink + is LaunchesContract.Effect.ClickableLink.Wikipedia -> + wikipediaLinkState.value = + effect.wikipedia else -> { youTubeLinkState.value = "" wikipediaLinkState.value = "" } } - }) + } + ) } } @@ -323,7 +325,6 @@ private fun getTabColour(selected: Boolean) = else Dark.UnselectedTab } - @Composable private fun AnimatableIcon( modifier: Modifier, @@ -382,4 +383,4 @@ private fun AnimatableText( private fun currentRoute(navController: NavHostController): String? { val navBackStackEntry by navController.currentBackStackEntryAsState() return navBackStackEntry?.destination?.route -} \ No newline at end of file +} diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/screens/common/ErrorAnimation.kt b/app/src/main/java/prieto/fernando/spacex/presentation/screens/common/ErrorAnimation.kt index 86c9420..6006e4b 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/screens/common/ErrorAnimation.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/screens/common/ErrorAnimation.kt @@ -41,4 +41,4 @@ fun ErrorAnimation( modifier = modifier.semantics { contentDescription = "404 Animation" } ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/CompanyInfoUiModel.kt b/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/CompanyInfoUiModel.kt index 8353dd8..9e17a1e 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/CompanyInfoUiModel.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/CompanyInfoUiModel.kt @@ -7,4 +7,4 @@ data class CompanyInfoUiModel( val employees: String, val launchSites: Int, val valuation: Long -) \ No newline at end of file +) diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardContract.kt b/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardContract.kt index bee37cc..7769b12 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardContract.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardContract.kt @@ -14,4 +14,4 @@ class DashboardContract { ) : ViewState object Effect : ViewSideEffect -} \ No newline at end of file +} diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardScreen.kt b/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardScreen.kt index 71ed843..54c940a 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardScreen.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/screens/dashboard/DashboardScreen.kt @@ -53,9 +53,9 @@ fun DashboardScreen( when { state.isLoading -> { LottieAnimation( - composition = loadingComposition, + composition = loadingComposition, progress = loadingProgress, - modifier = Modifier.semantics { contentDescription= "Loading Animation" } + modifier = Modifier.semantics { contentDescription = "Loading Animation" } ) } state.isError -> { @@ -92,4 +92,4 @@ private fun fillCompanyInfo(companyInfoUiModel: CompanyInfoUiModel): String = companyInfoUiModel.employees, companyInfoUiModel.launchSites, companyInfoUiModel.valuation - ) \ No newline at end of file + ) diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesContract.kt b/app/src/main/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesContract.kt index 3822ef4..d4d9ac4 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesContract.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesContract.kt @@ -29,4 +29,4 @@ class LaunchesContract { data class LinkClicked(val link: String) : Effect() } -} \ No newline at end of file +} diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreen.kt b/app/src/main/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreen.kt index 9b0d399..53b1266 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreen.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/screens/launches/LaunchesScreen.kt @@ -33,10 +33,10 @@ import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import prieto.fernando.spacex.R +import prieto.fernando.spacex.presentation.screens.common.ErrorAnimation import prieto.fernando.spacex.theme.Dark import prieto.fernando.spacex.theme.Light import prieto.fernando.spacex.theme.SpaceXTypography -import prieto.fernando.spacex.presentation.screens.common.ErrorAnimation @InternalCoroutinesApi @ExperimentalMaterialApi @@ -246,7 +246,8 @@ private fun DismissButton(openDialog: MutableState) { TextButton( onClick = { openDialog.value = false - }) { + } + ) { Text( text = stringResource(id = R.string.dialog_cancel_button), style = SpaceXTypography.subtitle2, @@ -267,7 +268,8 @@ private fun ConfirmButton( onClick = { openDialog.value = false onEventSent(LaunchesContract.Event.Filter(textState, orderChecked.value)) - }) { + } + ) { Text( stringResource(id = R.string.dialog_ok_button), style = SpaceXTypography.subtitle2, @@ -472,4 +474,4 @@ private fun getSuccessDrawable(launchSuccess: Boolean) = R.drawable.ic_check } else { R.drawable.ic_clear - } \ No newline at end of file + } diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/vm/DashboardViewModel.kt b/app/src/main/java/prieto/fernando/spacex/presentation/vm/DashboardViewModel.kt index cc35dc7..3bf62ed 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/vm/DashboardViewModel.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/vm/DashboardViewModel.kt @@ -6,10 +6,10 @@ import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch -import prieto.fernando.spacex.presentation.vm.base.BaseViewModel import prieto.fernando.domain.usecase.GetCompanyInfo import prieto.fernando.spacex.presentation.screens.dashboard.CompanyInfoUiModel import prieto.fernando.spacex.presentation.screens.dashboard.DashboardContract +import prieto.fernando.spacex.presentation.vm.base.BaseViewModel import prieto.fernando.spacex.presentation.vm.mapper.CompanyInfoDomainToUiModelMapper import timber.log.Timber import javax.inject.Inject @@ -76,4 +76,4 @@ class DashboardViewModel @Inject constructor( ) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModel.kt b/app/src/main/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModel.kt index c4c5863..e3c9100 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModel.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModel.kt @@ -6,10 +6,9 @@ import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch -import prieto.fernando.spacex.presentation.vm.base.BaseViewModel import prieto.fernando.domain.usecase.GetLaunches import prieto.fernando.spacex.presentation.screens.launches.LaunchesContract -import prieto.fernando.spacex.presentation.screens.launches.LinksUiModel +import prieto.fernando.spacex.presentation.vm.base.BaseViewModel import prieto.fernando.spacex.presentation.vm.mapper.ClickableLinkProvider import prieto.fernando.spacex.presentation.vm.mapper.LaunchesDomainToUiModelMapper import timber.log.Timber diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/vm/base/BaseComponents.kt b/app/src/main/java/prieto/fernando/spacex/presentation/vm/base/BaseComponents.kt index a355bad..56767cf 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/vm/base/BaseComponents.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/vm/base/BaseComponents.kt @@ -18,10 +18,10 @@ interface ViewEvent interface ViewSideEffect abstract class BaseViewModel< - Event : ViewEvent, - UiState : ViewState, - Effect : ViewSideEffect> - : ViewModel() { + Event : ViewEvent, + UiState : ViewState, + Effect : ViewSideEffect> : + ViewModel() { private val initialState: UiState by lazy { setInitialState() } abstract fun setInitialState(): UiState @@ -61,4 +61,4 @@ abstract class BaseViewModel< val effectValue = builder() viewModelScope.launch { _effect.send(effectValue) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/vm/di/PresentationModule.kt b/app/src/main/java/prieto/fernando/spacex/presentation/vm/di/PresentationModule.kt index 05dcc4b..e27a28a 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/vm/di/PresentationModule.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/vm/di/PresentationModule.kt @@ -30,4 +30,4 @@ class PresentationModule { @Reusable fun provideCompanyInfoDomainToUiModelMapper(): CompanyInfoDomainToUiModelMapper = CompanyInfoDomainToUiModelMapperImpl() -} \ No newline at end of file +} diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/vm/mapper/ClickableLinkProvider.kt b/app/src/main/java/prieto/fernando/spacex/presentation/vm/mapper/ClickableLinkProvider.kt index 9d32aeb..3e31b5b 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/vm/mapper/ClickableLinkProvider.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/vm/mapper/ClickableLinkProvider.kt @@ -23,4 +23,4 @@ class ClickableLinkProvider @Inject constructor() { LaunchesContract.Effect.ClickableLink.None } } -} \ No newline at end of file +} diff --git a/app/src/main/java/prieto/fernando/spacex/presentation/vm/mapper/DateTimeProvider.kt b/app/src/main/java/prieto/fernando/spacex/presentation/vm/mapper/DateTimeProvider.kt index 6527ef0..6d46f35 100644 --- a/app/src/main/java/prieto/fernando/spacex/presentation/vm/mapper/DateTimeProvider.kt +++ b/app/src/main/java/prieto/fernando/spacex/presentation/vm/mapper/DateTimeProvider.kt @@ -5,4 +5,4 @@ import javax.inject.Inject class DateTimeProvider @Inject constructor() { fun today(): DateTime = DateTime.now() -} \ No newline at end of file +} diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt index e87b646..59b1012 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/DashboardViewModelTest.kt @@ -5,12 +5,12 @@ import io.mockk.coEvery import io.mockk.coVerify import io.mockk.every import io.mockk.mockk -import org.junit.Assert.assertEquals import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.test.setMain +import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule import org.junit.Test diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt index c007a47..e79d46d 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/LaunchesViewModelTest.kt @@ -4,12 +4,12 @@ import androidx.arch.core.executor.testing.InstantTaskExecutorRule import io.mockk.coEvery import io.mockk.coVerify import io.mockk.mockk -import org.junit.Assert.assertEquals import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flow import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.test.setMain +import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Rule import org.junit.Test @@ -52,7 +52,6 @@ class LaunchesViewModelTest { @get:Rule var rule: TestRule = InstantTaskExecutorRule() - @Test fun `When launches Then launchUiModelRetrieved with expected result`() { runBlockingTest { diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/ClickableLinkProviderTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/ClickableLinkProviderTest.kt index 1d54f6d..2fe8c0a 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/ClickableLinkProviderTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/ClickableLinkProviderTest.kt @@ -23,7 +23,8 @@ class ClickableLinkProviderTest( missionPatchSmall = "", wikipedia = "someWikipedia URL", youTubeLink = "someYoutube URL" - ), LaunchesContract.Effect.ClickableLink.All( + ), + LaunchesContract.Effect.ClickableLink.All( wikipedia = "someWikipedia URL", youTubeLink = "someYoutube URL" ) @@ -33,7 +34,8 @@ class ClickableLinkProviderTest( missionPatchSmall = "", wikipedia = "someWikipedia URL", youTubeLink = " " - ), LaunchesContract.Effect.ClickableLink.Wikipedia( + ), + LaunchesContract.Effect.ClickableLink.Wikipedia( wikipedia = "someWikipedia URL" ) ), @@ -42,7 +44,8 @@ class ClickableLinkProviderTest( missionPatchSmall = "", wikipedia = "", youTubeLink = "someYoutube URL" - ), LaunchesContract.Effect.ClickableLink.Youtube( + ), + LaunchesContract.Effect.ClickableLink.Youtube( youTubeLink = "someYoutube URL" ) ), @@ -51,20 +54,21 @@ class ClickableLinkProviderTest( missionPatchSmall = "", wikipedia = " ", youTubeLink = " " - ), LaunchesContract.Effect.ClickableLink.None + ), + LaunchesContract.Effect.ClickableLink.None ), arrayOf( LinksUiModel( missionPatchSmall = "", wikipedia = "", youTubeLink = "" - ), LaunchesContract.Effect.ClickableLink.None + ), + LaunchesContract.Effect.ClickableLink.None ) ) } } - private lateinit var cut: ClickableLinkProvider @Before @@ -80,4 +84,4 @@ class ClickableLinkProviderTest( // Then assertEquals(expected, actualValue) } -} \ No newline at end of file +} diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/CompanyInfoUiModelDomainToUiModelMapperTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/CompanyInfoUiModelDomainToUiModelMapperTest.kt index 8ce5fe9..9941fd2 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/CompanyInfoUiModelDomainToUiModelMapperTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/CompanyInfoUiModelDomainToUiModelMapperTest.kt @@ -26,7 +26,8 @@ class CompanyInfoUiModelDomainToUiModelMapperTest( "employees", 1, 23 - ), CompanyInfoUiModel( + ), + CompanyInfoUiModel( "name", "founder", "founded", @@ -43,7 +44,8 @@ class CompanyInfoUiModelDomainToUiModelMapperTest( "employees", 3, 27500000000 - ), CompanyInfoUiModel( + ), + CompanyInfoUiModel( "name", "founder", "founded", @@ -60,7 +62,8 @@ class CompanyInfoUiModelDomainToUiModelMapperTest( "", 0, 0 - ), CompanyInfoUiModel( + ), + CompanyInfoUiModel( "", "", "", diff --git a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt index 3fc6156..fe2590d 100644 --- a/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt +++ b/app/src/test/java/prieto/fernando/spacex/presentation/vm/mapper/LaunchesDomainToUiModelMapperTest.kt @@ -102,7 +102,6 @@ class LaunchesDomainToUiModelMapperTest { // Then assertEquals(expected, actualValue) - } @Test diff --git a/build.gradle.kts b/build.gradle.kts index 4467a7e..add6da6 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,6 +11,7 @@ buildscript { } allprojects { + repositories { google() jcenter() diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 3d24697..f713f00 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -15,3 +15,4 @@ dependencies { implementation(gradleApi()) } + diff --git a/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt b/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt index dcb09e0..f6946fb 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/android/plugin/AndroidPlugin.kt @@ -86,10 +86,6 @@ open class AndroidPlugin : Plugin { unitTests.isReturnDefaultValues = true animationsDisabled = true } - - lintOptions { - isAbortOnError = false - } } private fun Project.configureDependencies() = dependencies { diff --git a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Dependencies.kt b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Dependencies.kt index b906674..cf067e1 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Dependencies.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Dependencies.kt @@ -87,5 +87,5 @@ object Dependencies { const val coilCompose = "io.coil-kt:coil-compose:${Versions.coil}" const val jodaTime = "joda-time:joda-time:${Versions.jodaTime}" - + const val ktlint = "com.pinterest:ktlint:${Versions.ktlint}" } diff --git a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt index 8e3c295..a5d9036 100644 --- a/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt +++ b/buildSrc/src/main/kotlin/prieto/fernando/dependencies/Versions.kt @@ -34,6 +34,7 @@ object Versions { const val okhttpLoggingInterceptor = "4.9.1" const val coil = "1.4.0" const val jodaTime = "2.10.8" + const val ktlint = "0.43.1" const val mockWebServer = "4.9.0" const val browser = "1.0.0" const val kotlinxCoroutines = "1.5.2"