Skip to content

Commit c51830a

Browse files
Merge pull request #790 from JoseAlcerreca/main_4.2
Version bumps and fixes
2 parents 0a26cb4 + 7183827 commit c51830a

File tree

14 files changed

+105
-92
lines changed

14 files changed

+105
-92
lines changed

app/build.gradle

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ android {
8989
kotlinOptions {
9090
jvmTarget = "1.8"
9191
}
92+
93+
packagingOptions {
94+
exclude 'META-INF/AL2.0'
95+
exclude 'META-INF/LGPL2.1'
96+
}
9297
}
9398

9499
/*
@@ -114,37 +119,34 @@ dependencies {
114119
implementation "androidx.room:room-runtime:$roomVersion"
115120
kapt "androidx.room:room-compiler:$roomVersion"
116121
implementation "androidx.room:room-ktx:$roomVersion"
117-
implementation "androidx.lifecycle:lifecycle-extensions:$archLifecycleVersion"
118122
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$archLifecycleVersion"
119123
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$archLifecycleVersion"
120124
implementation "androidx.navigation:navigation-fragment-ktx:$navigationVersion"
121125
implementation "androidx.navigation:navigation-ui-ktx:$navigationVersion"
122126

123127
// Dependencies for local unit tests
124128
testImplementation "junit:junit:$junitVersion"
125-
testImplementation "org.mockito:mockito-core:$mockitoVersion"
126129
testImplementation "org.hamcrest:hamcrest-all:$hamcrestVersion"
127130
testImplementation "androidx.arch.core:core-testing:$archTestingVersion"
128131
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"
129132
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion"
130133
testImplementation "org.robolectric:robolectric:$robolectricVersion"
134+
testImplementation "androidx.navigation:navigation-testing:$navigationVersion"
131135
testImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
132136
testImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
133137
testImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
134138
testImplementation "com.google.truth:truth:$truthVersion"
135139

136140
// Dependencies for Android unit tests
137141
androidTestImplementation "junit:junit:$junitVersion"
138-
androidTestImplementation "org.mockito:mockito-core:$mockitoVersion"
139-
androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito:$dexMakerVersion"
140142
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion"
141143

142144
// AndroidX Test - JVM testing
143145
testImplementation "androidx.test:core-ktx:$androidXTestCoreVersion"
144146
testImplementation "androidx.test.ext:junit-ktx:$androidXTestExtKotlinRunnerVersion"
145147
testImplementation "androidx.test:rules:$androidXTestRulesVersion"
146148
// Once https://issuetracker.google.com/127986458 is fixed this can be testImplementation
147-
implementation "androidx.fragment:fragment-testing:$fragmentVersion"
149+
debugImplementation "androidx.fragment:fragment-testing:$fragmentVersion"
148150
implementation "androidx.test:core:$androidXTestCoreVersion"
149151
implementation "androidx.fragment:fragment:$fragmentVersion"
150152

@@ -154,6 +156,7 @@ dependencies {
154156
androidTestImplementation "androidx.test:rules:$androidXTestRulesVersion"
155157
androidTestImplementation "androidx.room:room-testing:$roomVersion"
156158
androidTestImplementation "androidx.arch.core:core-testing:$archTestingVersion"
159+
androidTestImplementation "androidx.navigation:navigation-testing:$navigationVersion"
157160
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
158161
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
159162
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"

app/proguardTest-rules.pro

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,3 @@
1616
-dontwarn org.junit.**
1717
-dontwarn org.hamcrest.**
1818
-dontwarn com.squareup.javawriter.JavaWriter
19-
# Uncomment this if you use Mockito
20-
-dontwarn org.mockito.**

app/src/androidTestMock/java/com/example/android/architecture/blueprints/todoapp/tasks/TasksActivityTest.kt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
3333
import androidx.test.espresso.matcher.ViewMatchers.withText
3434
import androidx.test.ext.junit.runners.AndroidJUnit4
3535
import androidx.test.filters.LargeTest
36+
import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread
3637
import com.example.android.architecture.blueprints.todoapp.R
3738
import com.example.android.architecture.blueprints.todoapp.R.string
3839
import com.example.android.architecture.blueprints.todoapp.ServiceLocator
@@ -67,13 +68,19 @@ class TasksActivityTest {
6768

6869
@Before
6970
fun init() {
70-
repository = ServiceLocator.provideTasksRepository(getApplicationContext())
71-
repository.deleteAllTasksBlocking()
71+
// Run on UI thread to make sure the same instance of the SL is used.
72+
runOnUiThread {
73+
ServiceLocator.createDataBase(getApplicationContext(), inMemory = true)
74+
repository = ServiceLocator.provideTasksRepository(getApplicationContext())
75+
repository.deleteAllTasksBlocking()
76+
}
7277
}
7378

7479
@After
7580
fun reset() {
76-
ServiceLocator.resetRepository()
81+
runOnUiThread {
82+
ServiceLocator.resetRepository()
83+
}
7784
}
7885

7986
/**

app/src/main/java/com/example/android/architecture/blueprints/todoapp/addedittask/AddEditTaskFragment.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class AddEditTaskFragment : Fragment() {
4747
inflater: LayoutInflater,
4848
container: ViewGroup?,
4949
savedInstanceState: Bundle?
50-
): View? {
50+
): View {
5151
val root = inflater.inflate(R.layout.addtask_frag, container, false)
5252
viewDataBinding = AddtaskFragBinding.bind(root).apply {
5353
this.viewmodel = viewModel
@@ -57,8 +57,8 @@ class AddEditTaskFragment : Fragment() {
5757
return viewDataBinding.root
5858
}
5959

60-
override fun onActivityCreated(savedInstanceState: Bundle?) {
61-
super.onActivityCreated(savedInstanceState)
60+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
61+
super.onViewCreated(view, savedInstanceState)
6262
setupSnackbar()
6363
setupNavigation()
6464
this.setupRefreshLayout(viewDataBinding.refreshLayout)
@@ -70,7 +70,7 @@ class AddEditTaskFragment : Fragment() {
7070
}
7171

7272
private fun setupNavigation() {
73-
viewModel.taskUpdatedEvent.observe(this, EventObserver {
73+
viewModel.taskUpdatedEvent.observe(viewLifecycleOwner, EventObserver {
7474
val action = AddEditTaskFragmentDirections
7575
.actionAddEditTaskFragmentToTasksFragment(ADD_EDIT_RESULT_OK)
7676
findNavController().navigate(action)

app/src/main/java/com/example/android/architecture/blueprints/todoapp/statistics/StatisticsFragment.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ class StatisticsFragment : Fragment() {
4848
return viewDataBinding.root
4949
}
5050

51-
override fun onActivityCreated(savedInstanceState: Bundle?) {
52-
super.onActivityCreated(savedInstanceState)
51+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
52+
super.onViewCreated(view, savedInstanceState)
5353
viewDataBinding.viewmodel = viewModel
5454
viewDataBinding.lifecycleOwner = this.viewLifecycleOwner
5555
this.setupRefreshLayout(viewDataBinding.refreshLayout)

app/src/main/java/com/example/android/architecture/blueprints/todoapp/taskdetail/TaskDetailFragment.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class TaskDetailFragment : Fragment() {
4545

4646
private val viewModel by viewModels<TaskDetailViewModel> { getViewModelFactory() }
4747

48-
override fun onActivityCreated(savedInstanceState: Bundle?) {
49-
super.onActivityCreated(savedInstanceState)
48+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
49+
super.onViewCreated(view, savedInstanceState)
5050
setupFab()
5151
view?.setupSnackbar(this, viewModel.snackbarText, Snackbar.LENGTH_SHORT)
5252
setupNavigation()

app/src/main/java/com/example/android/architecture/blueprints/todoapp/tasks/TasksFragment.kt

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class TasksFragment : Fragment() {
5656
inflater: LayoutInflater,
5757
container: ViewGroup?,
5858
savedInstanceState: Bundle?
59-
): View? {
59+
): View {
6060
viewDataBinding = TasksFragBinding.inflate(inflater, container, false).apply {
6161
viewmodel = viewModel
6262
}
@@ -85,8 +85,8 @@ class TasksFragment : Fragment() {
8585
inflater.inflate(R.menu.tasks_fragment_menu, menu)
8686
}
8787

88-
override fun onActivityCreated(savedInstanceState: Bundle?) {
89-
super.onActivityCreated(savedInstanceState)
88+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
89+
super.onViewCreated(view, savedInstanceState)
9090

9191
// Set the lifecycle owner to the lifecycle of the view
9292
viewDataBinding.lifecycleOwner = this.viewLifecycleOwner
@@ -98,16 +98,16 @@ class TasksFragment : Fragment() {
9898
}
9999

100100
private fun setupNavigation() {
101-
viewModel.openTaskEvent.observe(this, EventObserver {
101+
viewModel.openTaskEvent.observe(viewLifecycleOwner, EventObserver {
102102
openTaskDetails(it)
103103
})
104-
viewModel.newTaskEvent.observe(this, EventObserver {
104+
viewModel.newTaskEvent.observe(viewLifecycleOwner, EventObserver {
105105
navigateToAddNewTask()
106106
})
107107
}
108108

109109
private fun setupSnackbar() {
110-
view?.setupSnackbar(this, viewModel.snackbarText, Snackbar.LENGTH_SHORT)
110+
view?.setupSnackbar(viewLifecycleOwner, viewModel.snackbarText, Snackbar.LENGTH_SHORT)
111111
arguments?.let {
112112
viewModel.showEditResultMessage(args.userMessage)
113113
}
@@ -132,8 +132,9 @@ class TasksFragment : Fragment() {
132132
}
133133
}
134134

135+
// TODO: Move this to databinding
135136
private fun setupFab() {
136-
activity?.findViewById<FloatingActionButton>(R.id.add_task_fab)?.let {
137+
requireView().findViewById<FloatingActionButton>(R.id.add_task_fab)?.let {
137138
it.setOnClickListener {
138139
navigateToAddNewTask()
139140
}

app/src/mock/java/com/example/android/architecture/blueprints/todoapp/ServiceLocator.kt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,23 @@ object ServiceLocator {
5555
return TasksLocalDataSource(database.taskDao())
5656
}
5757

58-
private fun createDataBase(context: Context): ToDoDatabase {
59-
val result = Room.databaseBuilder(
60-
context.applicationContext,
61-
ToDoDatabase::class.java, "Tasks.db"
62-
).build()
58+
@VisibleForTesting
59+
fun createDataBase(
60+
context: Context,
61+
inMemory: Boolean = false
62+
): ToDoDatabase {
63+
val result = if (inMemory) {
64+
// Use a faster in-memory database for tests
65+
Room.inMemoryDatabaseBuilder(context.applicationContext, ToDoDatabase::class.java)
66+
.allowMainThreadQueries()
67+
.build()
68+
} else {
69+
// Real database using SQLite
70+
Room.databaseBuilder(
71+
context.applicationContext,
72+
ToDoDatabase::class.java, "Tasks.db"
73+
).build()
74+
}
6375
database = result
6476
return result
6577
}

app/src/sharedTest/java/com/example/android/architecture/blueprints/todoapp/addedittask/AddEditTaskFragmentTest.kt

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ package com.example.android.architecture.blueprints.todoapp.addedittask
1717

1818
import android.content.Context
1919
import androidx.fragment.app.testing.launchFragmentInContainer
20-
import androidx.navigation.NavController
2120
import androidx.navigation.Navigation
21+
import androidx.navigation.testing.TestNavHostController
2222
import androidx.test.core.app.ApplicationProvider.getApplicationContext
2323
import androidx.test.espresso.Espresso.onView
2424
import androidx.test.espresso.action.ViewActions.clearText
@@ -34,7 +34,6 @@ import com.example.android.architecture.blueprints.todoapp.ServiceLocator
3434
import com.example.android.architecture.blueprints.todoapp.data.Result
3535
import com.example.android.architecture.blueprints.todoapp.data.source.FakeRepository
3636
import com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository
37-
import com.example.android.architecture.blueprints.todoapp.tasks.ADD_EDIT_RESULT_OK
3837
import com.example.android.architecture.blueprints.todoapp.util.getTasksBlocking
3938
import kotlinx.coroutines.ExperimentalCoroutinesApi
4039
import kotlinx.coroutines.test.runBlockingTest
@@ -43,8 +42,6 @@ import org.junit.Assert.assertEquals
4342
import org.junit.Before
4443
import org.junit.Test
4544
import org.junit.runner.RunWith
46-
import org.mockito.Mockito.mock
47-
import org.mockito.Mockito.verify
4845
import org.robolectric.annotation.LooperMode
4946
import org.robolectric.annotation.TextLayoutMode
5047

@@ -91,7 +88,7 @@ class AddEditTaskFragmentTest {
9188
@Test
9289
fun validTask_navigatesBack() {
9390
// GIVEN - On the "Add Task" screen.
94-
val navController = mock(NavController::class.java)
91+
val navController = TestNavHostController(getApplicationContext())
9592
launchFragment(navController)
9693

9794
// WHEN - Valid title and description combination and click save
@@ -100,27 +97,13 @@ class AddEditTaskFragmentTest {
10097
onView(withId(R.id.save_task_fab)).perform(click())
10198

10299
// THEN - Verify that we navigated back to the tasks screen.
103-
verify(navController).navigate(
104-
AddEditTaskFragmentDirections
105-
.actionAddEditTaskFragmentToTasksFragment(ADD_EDIT_RESULT_OK)
106-
)
107-
}
108-
109-
private fun launchFragment(navController: NavController?) {
110-
val bundle = AddEditTaskFragmentArgs(
111-
null,
112-
getApplicationContext<Context>().getString(R.string.add_task)
113-
).toBundle()
114-
val scenario = launchFragmentInContainer<AddEditTaskFragment>(bundle, R.style.AppTheme)
115-
scenario.onFragment {
116-
Navigation.setViewNavController(it.view!!, navController)
117-
}
100+
assertEquals(navController.currentDestination?.id, R.id.tasks_fragment_dest)
118101
}
119102

120103
@Test
121104
fun validTask_isSaved() {
122105
// GIVEN - On the "Add Task" screen.
123-
val navController = mock(NavController::class.java)
106+
val navController = TestNavHostController(getApplicationContext())
124107
launchFragment(navController)
125108

126109
// WHEN - Valid title and description combination and click save
@@ -134,4 +117,17 @@ class AddEditTaskFragmentTest {
134117
assertEquals(tasks[0].title, "title")
135118
assertEquals(tasks[0].description, "description")
136119
}
120+
121+
private fun launchFragment(navController: TestNavHostController) {
122+
val bundle = AddEditTaskFragmentArgs(
123+
null,
124+
getApplicationContext<Context>().getString(R.string.add_task)
125+
).toBundle()
126+
val scenario = launchFragmentInContainer<AddEditTaskFragment>(bundle, R.style.AppTheme)
127+
scenario.onFragment {
128+
navController.setGraph(R.navigation.nav_graph)
129+
navController.setCurrentDestination(R.id.add_edit_task_fragment_dest)
130+
Navigation.setViewNavController(it.requireView(), navController)
131+
}
132+
}
137133
}

app/src/sharedTest/java/com/example/android/architecture/blueprints/todoapp/tasks/TasksFragmentTest.kt

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616

1717
package com.example.android.architecture.blueprints.todoapp.tasks
1818

19-
import android.content.Context
2019
import android.os.Bundle
2120
import android.view.View
2221
import androidx.fragment.app.testing.launchFragmentInContainer
23-
import androidx.navigation.NavController
2422
import androidx.navigation.Navigation
23+
import androidx.navigation.testing.TestNavHostController
2524
import androidx.recyclerview.widget.RecyclerView
2625
import androidx.test.core.app.ActivityScenario
2726
import androidx.test.core.app.ActivityScenario.launch
27+
import androidx.test.core.app.ApplicationProvider
2828
import androidx.test.core.app.ApplicationProvider.getApplicationContext
2929
import androidx.test.espresso.Espresso.onView
3030
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
@@ -38,11 +38,13 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
3838
import androidx.test.ext.junit.runners.AndroidJUnit4
3939
import androidx.test.filters.MediumTest
4040
import com.example.android.architecture.blueprints.todoapp.R
41+
import com.example.android.architecture.blueprints.todoapp.R.id
4142
import com.example.android.architecture.blueprints.todoapp.ServiceLocator
4243
import com.example.android.architecture.blueprints.todoapp.data.Task
4344
import com.example.android.architecture.blueprints.todoapp.data.source.FakeRepository
4445
import com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository
4546
import com.example.android.architecture.blueprints.todoapp.util.saveTaskBlocking
47+
import junit.framework.Assert.assertEquals
4648
import kotlinx.coroutines.ExperimentalCoroutinesApi
4749
import kotlinx.coroutines.test.runBlockingTest
4850
import org.hamcrest.CoreMatchers.allOf
@@ -52,8 +54,6 @@ import org.junit.After
5254
import org.junit.Before
5355
import org.junit.Test
5456
import org.junit.runner.RunWith
55-
import org.mockito.Mockito.mock
56-
import org.mockito.Mockito.verify
5757
import org.robolectric.annotation.LooperMode
5858
import org.robolectric.annotation.TextLayoutMode
5959

@@ -314,20 +314,18 @@ class TasksFragmentTest {
314314
fun clickAddTaskButton_navigateToAddEditFragment() {
315315
// GIVEN - On the home screen
316316
val scenario = launchFragmentInContainer<TasksFragment>(Bundle(), R.style.AppTheme)
317-
val navController = mock(NavController::class.java)
317+
val navController = TestNavHostController(ApplicationProvider.getApplicationContext())
318318
scenario.onFragment {
319-
Navigation.setViewNavController(it.view!!, navController)
319+
navController.setGraph(R.navigation.nav_graph)
320+
navController.setCurrentDestination(R.id.tasks_fragment_dest)
321+
Navigation.setViewNavController(it.requireView(), navController)
320322
}
321323

322324
// WHEN - Click on the "+" button
323325
onView(withId(R.id.add_task_fab)).perform(click())
324326

325327
// THEN - Verify that we navigate to the add screen
326-
verify(navController).navigate(
327-
TasksFragmentDirections.actionTasksFragmentToAddEditTaskFragment(
328-
null, getApplicationContext<Context>().getString(R.string.add_task)
329-
)
330-
)
328+
assertEquals(navController.currentDestination?.id, id.add_edit_task_fragment_dest)
331329
}
332330

333331
private fun launchActivity(): ActivityScenario<TasksActivity>? {

0 commit comments

Comments
 (0)