Skip to content

Commit

Permalink
Use layout tag in all layout xml files. Use androidx to fix compilati…
Browse files Browse the repository at this point in the history
…on issues

Configure listener with data binding

Map all super hero detail fields into the layout

Use data binding in the edit super heroes screen

Migrate to pure data binding super hero detail

Finish migrating to data binding

Fix all tests

Add comment explaining why are we using our own InstrumentationRegistry class

Remove useless call
  • Loading branch information
Serchinastico committed Mar 15, 2019
1 parent 4170d28 commit bc14ca9
Show file tree
Hide file tree
Showing 19 changed files with 435 additions and 330 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package android.support.test

import android.content.Context
import androidx.test.core.app.ApplicationProvider

/**
* This solves the issue with mockito looking for InstrumentationRegistry with reflection.
* Hopefully this class won't be required with a mockito update.
*
* Report: https://github.com/mockito/mockito/issues/1472
* Solution: https://github.com/mockito/mockito/pull/1583
*/
class InstrumentationRegistry {
companion object {
@JvmStatic
fun getTargetContext(): Context? {
return ApplicationProvider.getApplicationContext()
}
}
}
2 changes: 1 addition & 1 deletion app/src/androidTest/java/com/karumi/TestRunner.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.karumi
import android.app.Application
import android.content.Context
import android.os.Bundle
import android.support.test.runner.AndroidJUnitRunner
import androidx.test.runner.AndroidJUnitRunner
import com.facebook.testing.screenshot.ScreenshotRunner
import com.github.tmurakami.dexopener.DexOpener

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.karumi.jetpack.superheroes.data.repository.room

import android.support.test.InstrumentationRegistry
import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.platform.app.InstrumentationRegistry
import com.karumi.jetpack.superheroes.common.Migrations
import com.karumi.jetpack.superheroes.common.SuperHeroesDatabase
import org.junit.Assert.assertEquals
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ package com.karumi.jetpack.superheroes.ui.view
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.support.test.InstrumentationRegistry
import android.support.test.espresso.intent.rule.IntentsTestRule
import android.support.test.filters.LargeTest
import android.support.test.runner.AndroidJUnit4
import com.karumi.jetpack.superheroes.asApp
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.intent.rule.IntentsTestRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.karumi.jetpack.superheroes.SuperHeroesApplication
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.mock
import org.junit.Before
Expand Down Expand Up @@ -38,10 +38,9 @@ abstract class AcceptanceTest<T : Activity>(clazz: Class<T>) : ScreenshotTest {
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
val app = InstrumentationRegistry.getInstrumentation().targetContext.asApp()
val app = ApplicationProvider.getApplicationContext<SuperHeroesApplication>()
app.override(Kodein.Module("Base test dependencies", allowSilentOverride = true) {
import(testDependencies, allowOverride = true)

bind<ExecutorService>() with instance(executorServiceOnUiThread)
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package com.karumi.jetpack.superheroes.ui.view

import android.app.Activity
import android.content.Context
import android.support.test.InstrumentationRegistry.getInstrumentation
import android.util.DisplayMetrics
import android.view.View
import android.view.WindowManager
import androidx.recyclerview.widget.RecyclerView
import androidx.test.platform.app.InstrumentationRegistry
import com.facebook.testing.screenshot.Screenshot
import com.facebook.testing.screenshot.ViewHelpers

Expand All @@ -20,7 +20,7 @@ interface ScreenshotTest {
}

fun compareScreenshot(view: View, height: Int) {
val context = getInstrumentation().targetContext
val context = InstrumentationRegistry.getInstrumentation().targetContext
val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
val metrics = DisplayMetrics()
windowManager.defaultDisplay.getMetrics(metrics)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.karumi.jetpack.superheroes.ui.view

import android.support.test.InstrumentationRegistry.getInstrumentation
import android.view.LayoutInflater
import androidx.test.platform.app.InstrumentationRegistry
import com.karumi.jetpack.superheroes.R
import com.karumi.jetpack.superheroes.domain.model.SuperHero
import com.karumi.jetpack.superheroes.ui.presenter.SuperHeroesPresenter
Expand Down Expand Up @@ -52,7 +52,7 @@ class SuperHeroViewHolderTest : ScreenshotTest {
}

private fun givenASuperHeroViewHolder(): SuperHeroViewHolder {
val context = getInstrumentation().targetContext
val context = InstrumentationRegistry.getInstrumentation().targetContext
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.super_hero_row, null, false)
return SuperHeroViewHolder(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.karumi.jetpack.superheroes

import android.app.Application
import android.content.Context
import com.karumi.jetpack.superheroes.common.SuperHeroesDatabase
import com.karumi.jetpack.superheroes.common.module
import com.karumi.jetpack.superheroes.data.repository.LocalSuperHeroDataSource
Expand Down Expand Up @@ -53,6 +52,4 @@ class SuperHeroesApplication : Application(), KodeinAware {
Executors.newCachedThreadPool()
}
}
}

fun Context.asApp() = this.applicationContext as SuperHeroesApplication
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class EditSuperHeroPresenter(
private val getSuperHeroById: GetSuperHeroById,
private val saveSuperHero: SaveSuperHero,
private val executor: ExecutorService
) : LifecycleObserver {
) : EditSuperHeroListener, LifecycleObserver {

private val view: View? by weak(view)
private lateinit var id: String
Expand All @@ -40,7 +40,7 @@ class EditSuperHeroPresenter(
executor.shutdownNow()
}

fun onSaveSuperHeroSelected(
override fun onSaveSuperHeroSelected(
name: String,
description: String,
isAvenger: Boolean
Expand Down Expand Up @@ -74,8 +74,16 @@ class EditSuperHeroPresenter(

interface View {
fun close()
fun showLoading()
fun hideLoading()
fun showLoading()
fun showSuperHero(superHero: SuperHero)
}
}

interface EditSuperHeroListener {
fun onSaveSuperHeroSelected(
name: String,
description: String,
isAvenger: Boolean
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class SuperHeroDetailPresenter(
view: View,
private val getSuperHeroById: GetSuperHeroById,
private val executor: ExecutorService
) : LifecycleObserver {
) : SuperHeroDetailListener, LifecycleObserver {

private val view: View? by weak(view)

Expand All @@ -38,7 +38,7 @@ class SuperHeroDetailPresenter(
executor.shutdownNow()
}

fun onEditSelected() {
override fun onEditSelected() {
view?.openEditSuperHero(id)
}

Expand All @@ -50,9 +50,13 @@ class SuperHeroDetailPresenter(

interface View {
fun close()
fun showLoading()
fun hideLoading()
fun showLoading()
fun showSuperHero(superHero: SuperHero)
fun openEditSuperHero(superHeroId: String)
}
}

interface SuperHeroDetailListener {
fun onEditSelected()
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ class SuperHeroesPresenter(

interface View {
fun hideLoading()
fun showSuperHeroes(superHeroes: List<SuperHero>)
fun showLoading()
fun showEmptyCase()
fun showSuperHeroes(superHeroes: List<SuperHero>)
fun openDetail(id: String)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.LifecycleObserver
import org.kodein.di.Kodein
import org.kodein.di.KodeinAware
import org.kodein.di.android.closestKodein

abstract class BaseActivity : AppCompatActivity(), KodeinAware {
abstract class BaseActivity<T : ViewDataBinding> : AppCompatActivity(), KodeinAware {

private val appKodein by closestKodein()
override val kodein: Kodein = Kodein.lazy {
Expand All @@ -20,11 +22,13 @@ abstract class BaseActivity : AppCompatActivity(), KodeinAware {
abstract val layoutId: Int
abstract val toolbarView: Toolbar
abstract val activityModules: Kodein.Module
protected lateinit var binding: T

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lifecycle.addObserver(presenter)
setContentView(layoutId)
binding = DataBindingUtil.setContentView(this, layoutId)
configureBinding(binding)
setSupportActionBar(toolbarView)
prepare(intent)
}
Expand All @@ -34,5 +38,6 @@ abstract class BaseActivity : AppCompatActivity(), KodeinAware {
lifecycle.removeObserver(presenter)
}

abstract fun configureBinding(binding: T)
open fun prepare(intent: Intent?) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package com.karumi.jetpack.superheroes.ui.view
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.View
import androidx.appcompat.widget.Toolbar
import com.karumi.jetpack.superheroes.R
import com.karumi.jetpack.superheroes.common.module
import com.karumi.jetpack.superheroes.databinding.EditSuperHeroActivityBinding
import com.karumi.jetpack.superheroes.domain.model.SuperHero
import com.karumi.jetpack.superheroes.domain.usecase.GetSuperHeroById
import com.karumi.jetpack.superheroes.domain.usecase.SaveSuperHero
Expand All @@ -17,7 +17,10 @@ import org.kodein.di.erased.bind
import org.kodein.di.erased.instance
import org.kodein.di.erased.provider

class EditSuperHeroActivity : BaseActivity(), EditSuperHeroPresenter.View {
class EditSuperHeroActivity :
BaseActivity<EditSuperHeroActivityBinding>(),
EditSuperHeroPresenter.View {

companion object {
private const val SUPER_HERO_ID_KEY = "super_hero_id_key"

Expand Down Expand Up @@ -45,6 +48,11 @@ class EditSuperHeroActivity : BaseActivity(), EditSuperHeroPresenter.View {
}
}

override fun configureBinding(binding: EditSuperHeroActivityBinding) {
binding.listener = presenter
binding.isLoading = false
}

override fun prepare(intent: Intent?) {
title = superHeroId
presenter.preparePresenter(superHeroId)
Expand All @@ -55,24 +63,16 @@ class EditSuperHeroActivity : BaseActivity(), EditSuperHeroPresenter.View {
}

override fun showLoading() = runOnUiThread {
et_super_hero_name.isEnabled = false
et_super_hero_description.isEnabled = false
bt_save_edition.isEnabled = false
progress_bar.visibility = View.VISIBLE
binding.isLoading = true
}

override fun hideLoading() = runOnUiThread {
et_super_hero_name.isEnabled = true
et_super_hero_description.isEnabled = true
bt_save_edition.isEnabled = true
progress_bar.visibility = View.GONE
binding.isLoading = false
}

override fun showSuperHero(superHero: SuperHero) = runOnUiThread {
et_super_hero_name.setText(superHero.name)
et_super_hero_description.setText(superHero.description)
binding.superHero = superHero
iv_super_hero_photo.setImageBackground(superHero.photo)
cb_is_avenger.isChecked = superHero.isAvenger
}

override val activityModules = module {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.karumi.jetpack.superheroes.ui.view

import android.os.Bundle
import android.view.View
import androidx.appcompat.widget.Toolbar
import androidx.recyclerview.widget.LinearLayoutManager
import com.karumi.jetpack.superheroes.R
import com.karumi.jetpack.superheroes.common.module
import com.karumi.jetpack.superheroes.databinding.MainActivityBinding
import com.karumi.jetpack.superheroes.domain.model.SuperHero
import com.karumi.jetpack.superheroes.domain.usecase.GetSuperHeroes
import com.karumi.jetpack.superheroes.ui.presenter.SuperHeroesPresenter
Expand All @@ -15,7 +15,7 @@ import org.kodein.di.erased.bind
import org.kodein.di.erased.instance
import org.kodein.di.erased.provider

class MainActivity : BaseActivity(), SuperHeroesPresenter.View {
class MainActivity : BaseActivity<MainActivityBinding>(), SuperHeroesPresenter.View {

override val presenter: SuperHeroesPresenter by instance()
private lateinit var adapter: SuperHeroesAdapter
Expand All @@ -29,6 +29,11 @@ class MainActivity : BaseActivity(), SuperHeroesPresenter.View {
initializeRecyclerView()
}

override fun configureBinding(binding: MainActivityBinding) {
binding.isLoading = false
binding.isShowingEmptyCase = false
}

private fun initializeAdapter() {
adapter = SuperHeroesAdapter(presenter)
}
Expand All @@ -40,15 +45,15 @@ class MainActivity : BaseActivity(), SuperHeroesPresenter.View {
}

override fun showLoading() = runOnUiThread {
progress_bar.visibility = View.VISIBLE
binding.isLoading = true
}

override fun hideLoading() = runOnUiThread {
progress_bar.visibility = View.GONE
binding.isLoading = false
}

override fun showEmptyCase() = runOnUiThread {
tv_empty_case.visibility = View.VISIBLE
binding.isShowingEmptyCase = true
}

override fun showSuperHeroes(superHeroes: List<SuperHero>) = runOnUiThread {
Expand Down
Loading

0 comments on commit bc14ca9

Please sign in to comment.