Skip to content

Commit

Permalink
Merge pull request #61 from BruceTrindade/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
BruceTrindade authored Nov 14, 2022
2 parents e95ac76 + 206b0e9 commit 5c72b81
Show file tree
Hide file tree
Showing 35 changed files with 274 additions and 211 deletions.
10 changes: 10 additions & 0 deletions .idea/ktlint.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file removed Screen Shot 2022-07-12 at 21.21.52.png
Binary file not shown.
Binary file removed Screen Shot 2022-07-19 at 09.01.07.png
Binary file not shown.
28 changes: 25 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ android {
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
testInstrumentationRunner "com.example.pokedex.HiltTestRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
testCoverageEnabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
Expand All @@ -36,6 +39,9 @@ android {
composeOptions {
kotlinCompilerExtensionVersion compose_version
}
hilt {
enableTransformForLocalTests = true
}
buildFeatures {
viewBinding true
compose true
Expand All @@ -54,6 +60,21 @@ dependencies {
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.4.0'
androidTestImplementation 'androidx.navigation:navigation-testing:2.5.2'

debugImplementation 'androidx.fragment:fragment-testing:1.5.3'

testImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
testAnnotationProcessor "com.google.dagger:hilt-android-compiler:$hilt_version"
androidTestAnnotationProcessor "com.google.dagger:hilt-android-compiler:$hilt_version"

kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.37'

androidTestImplementation 'org.mockito:mockito-android:3.2.4'

debugImplementation "androidx.fragment:fragment-testing:1.3.0-alpha08"

//compose
implementation "androidx.compose.ui:ui:$compose_version"
Expand All @@ -78,9 +99,10 @@ dependencies {
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

// Dagger - Hilt
implementation "com.google.dagger:hilt-android:$hilt_version"
implementation "com.google.dagger:hilt-android:2.37"
kapt "com.google.dagger:hilt-android-compiler:2.37"

implementation "androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
kapt "androidx.hilt:hilt-compiler:1.0.0"

def fragment_version = "1.4.1"
Expand Down
49 changes: 49 additions & 0 deletions app/src/androidTest/kotlin/com/example/pokedex/HiltExt.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.example.pokedex

import android.content.ComponentName
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentFactory
import androidx.fragment.app.testing.FragmentScenario
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.core.internal.deps.dagger.internal.Preconditions
import com.example.pokedex.testing.HiltTestActivity
import kotlinx.coroutines.ExperimentalCoroutinesApi

@ExperimentalCoroutinesApi
inline fun <reified T : Fragment> launchFragmentInHiltContainer(
fragmentArgs: Bundle? = null,
themeResId: Int = R.style.FragmentScenarioEmptyFragmentActivityTheme,
fragmentFactory: FragmentFactory? = null,
crossinline action: T.() -> Unit = {}
) {
val mainActivityIntent = Intent.makeMainActivity(
ComponentName(
ApplicationProvider.getApplicationContext(),
HiltTestActivity::class.java
)
).putExtra(
"androidx.fragment.app.testing.FragmentScenario.EmptyFragmentActivity.THEME_EXTRAS_BUNDLE_KEY",
themeResId
)

ActivityScenario.launch<HiltTestActivity>(mainActivityIntent).onActivity { activity ->
fragmentFactory?.let {
activity.supportFragmentManager.fragmentFactory = it
}
val fragment = activity.supportFragmentManager.fragmentFactory.instantiate(
Preconditions.checkNotNull(T::class.java.classLoader),
T::class.java.name
)
fragment.arguments = fragmentArgs

activity.supportFragmentManager.beginTransaction()
.add(android.R.id.content, fragment, "")
.commitNow()

(fragment as T).action()
}

}
15 changes: 15 additions & 0 deletions app/src/androidTest/kotlin/com/example/pokedex/HiltTestRunner.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.pokedex

import android.app.Application
import android.content.Context
import androidx.test.runner.AndroidJUnitRunner
import dagger.hilt.android.testing.HiltTestApplication

@Suppress("unused")
class HiltTestRunner : AndroidJUnitRunner() {
override fun newApplication(
cl: ClassLoader?,
className: String?,
context: Context?
): Application = super.newApplication(cl, HiltTestApplication::class.java.name, context)
}
20 changes: 20 additions & 0 deletions app/src/androidTest/kotlin/com/example/pokedex/MockPokemon.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.pokedex

import androidx.navigation.NavController
import com.example.pokedex.data.Pokemon
import com.example.pokedex.data.PokemonType
import org.mockito.Mockito

object MockPokemon {

val navController = Mockito.mock(NavController::class.java)

val list: List<PokemonType> = listOf(PokemonType("grass"), PokemonType("poison"))

val mockPokemon: Pokemon = Pokemon(
number = "3",
name = "venusaur",
types = list,
imageUrl = "3"
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.example.pokedex.ui.details

import androidx.core.os.bundleOf
import androidx.navigation.Navigation
import androidx.test.espresso.Espresso
import androidx.test.espresso.assertion.ViewAssertions
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.matcher.ViewMatchers.withId
import com.example.pokedex.MockPokemon
import com.example.pokedex.MockPokemon.navController
import com.example.pokedex.R
import com.example.pokedex.launchFragmentInHiltContainer
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Before
import org.junit.Rule
import org.junit.Test

@ExperimentalCoroutinesApi
@HiltAndroidTest
class PokedexDetailsFragmentTest {

@get:Rule
var hiltRule = HiltAndroidRule(this)

@Before
fun setup() {
hiltRule.inject()

launchFragmentInHiltContainer<PokedexDetailsFragment>(fragmentArgs = bundleOf("pokemon" to MockPokemon.mockPokemon)) {
Navigation.setViewNavController(requireView(), navController)
}
}

@Test
fun checkIfAfterPassArgumentThePokemonNameIsCorrect() {
Espresso.onView(withId(R.id.pokemon_name))
.check(ViewAssertions.matches(ViewMatchers.withText("Venusaur")))
}

@Test
fun checkIfAfterPassArgumentThePokemonNumberIsCorrect() {
Espresso.onView(withId(R.id.pokemon_number))
.check(ViewAssertions.matches(ViewMatchers.withText("003")))
}

@Test
fun checkIfAfterPassArgumentThePokemonTypeIsCorrect() {
Espresso.onView(withId(R.id.pokemon_primary_type))
.check(ViewAssertions.matches(ViewMatchers.withText("grass")))
}

@Test
fun checkIfAfterPassArgumentThePokemonSecondTypeIsCorrect() {
Espresso.onView(withId(R.id.pokemon_second_type))
.check(ViewAssertions.matches(ViewMatchers.withText("poison")))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.example.pokedex.ui.home

import androidx.navigation.Navigation
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers.*
import com.example.pokedex.MockPokemon.mockPokemon
import com.example.pokedex.MockPokemon.navController
import com.example.pokedex.R
import com.example.pokedex.launchFragmentInHiltContainer
import dagger.hilt.android.testing.HiltAndroidRule
import dagger.hilt.android.testing.HiltAndroidTest
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.Mockito.verify

@ExperimentalCoroutinesApi
@HiltAndroidTest
class PokedexHomeFragmentTest {

@get:Rule
var hiltRule = HiltAndroidRule(this)

@Before
fun setup() {
hiltRule.inject()

launchFragmentInHiltContainer<PokedexHomeFragment> {
Navigation.setViewNavController(requireView(), navController)
}
}

@Test
fun navigate_to_detailsPokedex() {
onView(withId(R.id.pokemon_recycler))
.perform(
RecyclerViewActions
.actionOnItemAtPosition<RecyclerView.ViewHolder>(2, click())
)

verify(navController).navigate(
PokedexHomeFragmentDirections.actionFirstDestinationToPokedexDetailsFragment(mockPokemon)
)
}
}
14 changes: 14 additions & 0 deletions app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.pokedex">

<uses-permission android:name="android.permission.INTERNET"/>

<application>
<activity
android:name=".testing.HiltTestActivity"
android:exported="true">
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.pokedex.testing

import androidx.appcompat.app.AppCompatActivity
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class HiltTestActivity : AppCompatActivity()
4 changes: 2 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
android:supportsRtl="true"
android:theme="@style/Theme.Pokedex">
<activity
android:name=".ui.SplashActivity"
android:name=".ui.splash.SplashActivity"
android:theme="@style/SplashTheme"
android:exported="true">
<intent-filter>
Expand All @@ -23,7 +23,7 @@
</intent-filter>
</activity>
<activity
android:name=".ui.MainActivity"
android:name=".ui.main.MainActivity"
android:exported="true">
</activity>
</application>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class PokedexApplication : Application()
class PokedexApplication : Application()
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ interface PokemonService {
suspend fun getPokemon(
@Path("number") number: Int
): Response<PokemonApiResult>
}
}
32 changes: 1 addition & 31 deletions app/src/main/kotlin/com/example/pokedex/data/Pokemon.kt
Original file line number Diff line number Diff line change
@@ -1,45 +1,15 @@
package com.example.pokedex.data

import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
import androidx.room.TypeConverters
import com.example.pokedex.data.local.PokedexConverters
import kotlinx.android.parcel.Parcelize
import kotlinx.android.parcel.RawValue

@Parcelize
@Entity(tableName = "pokemon")
@TypeConverters(PokedexConverters::class)
data class Pokemon(
@PrimaryKey
val number: String,
val name: String,
val types: @RawValue List<PokemonType>,
val imageUrl: String
) : Parcelable {

// val formattedNumber = when {
// number.length < 2 -> "00$number"
// number.length < 3 -> "0$number"
// else -> number
// }
//
// val formattedName = name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
//
// val imageUrl = "https://assets.pokemon.com/assets/cms2/img/pokedex/full/$formattedNumber.png"
}

/*
@Entity(tableName = "pokemon")
data class Pokemon(
@PrimaryKey(autoGenerate = true)
@SerializedName("number")
val number: String,
@SerializedName("name")
val name: String,
@SerializedName("types")
val types: @RawValue List<PokemonType>
) : Serializable {
*/
) : Parcelable
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
package com.example.pokedex.data

import com.example.pokedex.api.PokemonService
import com.example.pokedex.data.local.PokedexDao
import javax.inject.Inject

class PokemonRepository @Inject constructor(
private val service: PokemonService,
private val dao: PokedexDao
private val service: PokemonService
) {

suspend fun listPokemons(limit: Int = 100) = service.listPokemons(limit)
suspend fun listPokemons(limit: Int = 500) = service.listPokemons(limit)
suspend fun getPokemons(number: Int) = service.getPokemon(number)

suspend fun insert(pokemonModel: Pokemon) = dao.insert(pokemonModel)
fun getAll() = dao.getAll()
suspend fun delete(pokemonModel: Pokemon) = dao.delete(pokemonModel)
}
Loading

0 comments on commit 5c72b81

Please sign in to comment.