未验证 提交 c51830a7 编写于 作者: J Jose Alcérreca 提交者: GitHub

Merge pull request #790 from JoseAlcerreca/main_4.2

Version bumps and fixes
......@@ -89,6 +89,11 @@ android {
kotlinOptions {
jvmTarget = "1.8"
}
packagingOptions {
exclude 'META-INF/AL2.0'
exclude 'META-INF/LGPL2.1'
}
}
/*
......@@ -114,7 +119,6 @@ dependencies {
implementation "androidx.room:room-runtime:$roomVersion"
kapt "androidx.room:room-compiler:$roomVersion"
implementation "androidx.room:room-ktx:$roomVersion"
implementation "androidx.lifecycle:lifecycle-extensions:$archLifecycleVersion"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$archLifecycleVersion"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$archLifecycleVersion"
implementation "androidx.navigation:navigation-fragment-ktx:$navigationVersion"
......@@ -122,12 +126,12 @@ dependencies {
// Dependencies for local unit tests
testImplementation "junit:junit:$junitVersion"
testImplementation "org.mockito:mockito-core:$mockitoVersion"
testImplementation "org.hamcrest:hamcrest-all:$hamcrestVersion"
testImplementation "androidx.arch.core:core-testing:$archTestingVersion"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion"
testImplementation "org.robolectric:robolectric:$robolectricVersion"
testImplementation "androidx.navigation:navigation-testing:$navigationVersion"
testImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
testImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
testImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
......@@ -135,8 +139,6 @@ dependencies {
// Dependencies for Android unit tests
androidTestImplementation "junit:junit:$junitVersion"
androidTestImplementation "org.mockito:mockito-core:$mockitoVersion"
androidTestImplementation "com.linkedin.dexmaker:dexmaker-mockito:$dexMakerVersion"
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion"
// AndroidX Test - JVM testing
......@@ -144,7 +146,7 @@ dependencies {
testImplementation "androidx.test.ext:junit-ktx:$androidXTestExtKotlinRunnerVersion"
testImplementation "androidx.test:rules:$androidXTestRulesVersion"
// Once https://issuetracker.google.com/127986458 is fixed this can be testImplementation
implementation "androidx.fragment:fragment-testing:$fragmentVersion"
debugImplementation "androidx.fragment:fragment-testing:$fragmentVersion"
implementation "androidx.test:core:$androidXTestCoreVersion"
implementation "androidx.fragment:fragment:$fragmentVersion"
......@@ -154,6 +156,7 @@ dependencies {
androidTestImplementation "androidx.test:rules:$androidXTestRulesVersion"
androidTestImplementation "androidx.room:room-testing:$roomVersion"
androidTestImplementation "androidx.arch.core:core-testing:$archTestingVersion"
androidTestImplementation "androidx.navigation:navigation-testing:$navigationVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
......
......@@ -16,5 +16,3 @@
-dontwarn org.junit.**
-dontwarn org.hamcrest.**
-dontwarn com.squareup.javawriter.JavaWriter
# Uncomment this if you use Mockito
-dontwarn org.mockito.**
\ No newline at end of file
......@@ -33,6 +33,7 @@ import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread
import com.example.android.architecture.blueprints.todoapp.R
import com.example.android.architecture.blueprints.todoapp.R.string
import com.example.android.architecture.blueprints.todoapp.ServiceLocator
......@@ -67,13 +68,19 @@ class TasksActivityTest {
@Before
fun init() {
repository = ServiceLocator.provideTasksRepository(getApplicationContext())
repository.deleteAllTasksBlocking()
// Run on UI thread to make sure the same instance of the SL is used.
runOnUiThread {
ServiceLocator.createDataBase(getApplicationContext(), inMemory = true)
repository = ServiceLocator.provideTasksRepository(getApplicationContext())
repository.deleteAllTasksBlocking()
}
}
@After
fun reset() {
ServiceLocator.resetRepository()
runOnUiThread {
ServiceLocator.resetRepository()
}
}
/**
......
......@@ -47,7 +47,7 @@ class AddEditTaskFragment : Fragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
): View {
val root = inflater.inflate(R.layout.addtask_frag, container, false)
viewDataBinding = AddtaskFragBinding.bind(root).apply {
this.viewmodel = viewModel
......@@ -57,8 +57,8 @@ class AddEditTaskFragment : Fragment() {
return viewDataBinding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupSnackbar()
setupNavigation()
this.setupRefreshLayout(viewDataBinding.refreshLayout)
......@@ -70,7 +70,7 @@ class AddEditTaskFragment : Fragment() {
}
private fun setupNavigation() {
viewModel.taskUpdatedEvent.observe(this, EventObserver {
viewModel.taskUpdatedEvent.observe(viewLifecycleOwner, EventObserver {
val action = AddEditTaskFragmentDirections
.actionAddEditTaskFragmentToTasksFragment(ADD_EDIT_RESULT_OK)
findNavController().navigate(action)
......
......@@ -48,8 +48,8 @@ class StatisticsFragment : Fragment() {
return viewDataBinding.root
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewDataBinding.viewmodel = viewModel
viewDataBinding.lifecycleOwner = this.viewLifecycleOwner
this.setupRefreshLayout(viewDataBinding.refreshLayout)
......
......@@ -45,8 +45,8 @@ class TaskDetailFragment : Fragment() {
private val viewModel by viewModels<TaskDetailViewModel> { getViewModelFactory() }
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupFab()
view?.setupSnackbar(this, viewModel.snackbarText, Snackbar.LENGTH_SHORT)
setupNavigation()
......
......@@ -56,7 +56,7 @@ class TasksFragment : Fragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
): View {
viewDataBinding = TasksFragBinding.inflate(inflater, container, false).apply {
viewmodel = viewModel
}
......@@ -85,8 +85,8 @@ class TasksFragment : Fragment() {
inflater.inflate(R.menu.tasks_fragment_menu, menu)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Set the lifecycle owner to the lifecycle of the view
viewDataBinding.lifecycleOwner = this.viewLifecycleOwner
......@@ -98,16 +98,16 @@ class TasksFragment : Fragment() {
}
private fun setupNavigation() {
viewModel.openTaskEvent.observe(this, EventObserver {
viewModel.openTaskEvent.observe(viewLifecycleOwner, EventObserver {
openTaskDetails(it)
})
viewModel.newTaskEvent.observe(this, EventObserver {
viewModel.newTaskEvent.observe(viewLifecycleOwner, EventObserver {
navigateToAddNewTask()
})
}
private fun setupSnackbar() {
view?.setupSnackbar(this, viewModel.snackbarText, Snackbar.LENGTH_SHORT)
view?.setupSnackbar(viewLifecycleOwner, viewModel.snackbarText, Snackbar.LENGTH_SHORT)
arguments?.let {
viewModel.showEditResultMessage(args.userMessage)
}
......@@ -132,8 +132,9 @@ class TasksFragment : Fragment() {
}
}
// TODO: Move this to databinding
private fun setupFab() {
activity?.findViewById<FloatingActionButton>(R.id.add_task_fab)?.let {
requireView().findViewById<FloatingActionButton>(R.id.add_task_fab)?.let {
it.setOnClickListener {
navigateToAddNewTask()
}
......
......@@ -55,11 +55,23 @@ object ServiceLocator {
return TasksLocalDataSource(database.taskDao())
}
private fun createDataBase(context: Context): ToDoDatabase {
val result = Room.databaseBuilder(
context.applicationContext,
ToDoDatabase::class.java, "Tasks.db"
).build()
@VisibleForTesting
fun createDataBase(
context: Context,
inMemory: Boolean = false
): ToDoDatabase {
val result = if (inMemory) {
// Use a faster in-memory database for tests
Room.inMemoryDatabaseBuilder(context.applicationContext, ToDoDatabase::class.java)
.allowMainThreadQueries()
.build()
} else {
// Real database using SQLite
Room.databaseBuilder(
context.applicationContext,
ToDoDatabase::class.java, "Tasks.db"
).build()
}
database = result
return result
}
......
......@@ -17,8 +17,8 @@ package com.example.android.architecture.blueprints.todoapp.addedittask
import android.content.Context
import androidx.fragment.app.testing.launchFragmentInContainer
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.navigation.testing.TestNavHostController
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.clearText
......@@ -34,7 +34,6 @@ import com.example.android.architecture.blueprints.todoapp.ServiceLocator
import com.example.android.architecture.blueprints.todoapp.data.Result
import com.example.android.architecture.blueprints.todoapp.data.source.FakeRepository
import com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository
import com.example.android.architecture.blueprints.todoapp.tasks.ADD_EDIT_RESULT_OK
import com.example.android.architecture.blueprints.todoapp.util.getTasksBlocking
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
......@@ -43,8 +42,6 @@ import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.robolectric.annotation.LooperMode
import org.robolectric.annotation.TextLayoutMode
......@@ -91,7 +88,7 @@ class AddEditTaskFragmentTest {
@Test
fun validTask_navigatesBack() {
// GIVEN - On the "Add Task" screen.
val navController = mock(NavController::class.java)
val navController = TestNavHostController(getApplicationContext())
launchFragment(navController)
// WHEN - Valid title and description combination and click save
......@@ -100,27 +97,13 @@ class AddEditTaskFragmentTest {
onView(withId(R.id.save_task_fab)).perform(click())
// THEN - Verify that we navigated back to the tasks screen.
verify(navController).navigate(
AddEditTaskFragmentDirections
.actionAddEditTaskFragmentToTasksFragment(ADD_EDIT_RESULT_OK)
)
}
private fun launchFragment(navController: NavController?) {
val bundle = AddEditTaskFragmentArgs(
null,
getApplicationContext<Context>().getString(R.string.add_task)
).toBundle()
val scenario = launchFragmentInContainer<AddEditTaskFragment>(bundle, R.style.AppTheme)
scenario.onFragment {
Navigation.setViewNavController(it.view!!, navController)
}
assertEquals(navController.currentDestination?.id, R.id.tasks_fragment_dest)
}
@Test
fun validTask_isSaved() {
// GIVEN - On the "Add Task" screen.
val navController = mock(NavController::class.java)
val navController = TestNavHostController(getApplicationContext())
launchFragment(navController)
// WHEN - Valid title and description combination and click save
......@@ -134,4 +117,17 @@ class AddEditTaskFragmentTest {
assertEquals(tasks[0].title, "title")
assertEquals(tasks[0].description, "description")
}
private fun launchFragment(navController: TestNavHostController) {
val bundle = AddEditTaskFragmentArgs(
null,
getApplicationContext<Context>().getString(R.string.add_task)
).toBundle()
val scenario = launchFragmentInContainer<AddEditTaskFragment>(bundle, R.style.AppTheme)
scenario.onFragment {
navController.setGraph(R.navigation.nav_graph)
navController.setCurrentDestination(R.id.add_edit_task_fragment_dest)
Navigation.setViewNavController(it.requireView(), navController)
}
}
}
......@@ -16,15 +16,15 @@
package com.example.android.architecture.blueprints.todoapp.tasks
import android.content.Context
import android.os.Bundle
import android.view.View
import androidx.fragment.app.testing.launchFragmentInContainer
import androidx.navigation.NavController
import androidx.navigation.Navigation
import androidx.navigation.testing.TestNavHostController
import androidx.recyclerview.widget.RecyclerView
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ActivityScenario.launch
import androidx.test.core.app.ApplicationProvider
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu
......@@ -38,11 +38,13 @@ import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import com.example.android.architecture.blueprints.todoapp.R
import com.example.android.architecture.blueprints.todoapp.R.id
import com.example.android.architecture.blueprints.todoapp.ServiceLocator
import com.example.android.architecture.blueprints.todoapp.data.Task
import com.example.android.architecture.blueprints.todoapp.data.source.FakeRepository
import com.example.android.architecture.blueprints.todoapp.data.source.TasksRepository
import com.example.android.architecture.blueprints.todoapp.util.saveTaskBlocking
import junit.framework.Assert.assertEquals
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import org.hamcrest.CoreMatchers.allOf
......@@ -52,8 +54,6 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.robolectric.annotation.LooperMode
import org.robolectric.annotation.TextLayoutMode
......@@ -314,20 +314,18 @@ class TasksFragmentTest {
fun clickAddTaskButton_navigateToAddEditFragment() {
// GIVEN - On the home screen
val scenario = launchFragmentInContainer<TasksFragment>(Bundle(), R.style.AppTheme)
val navController = mock(NavController::class.java)
val navController = TestNavHostController(ApplicationProvider.getApplicationContext())
scenario.onFragment {
Navigation.setViewNavController(it.view!!, navController)
navController.setGraph(R.navigation.nav_graph)
navController.setCurrentDestination(R.id.tasks_fragment_dest)
Navigation.setViewNavController(it.requireView(), navController)
}
// WHEN - Click on the "+" button
onView(withId(R.id.add_task_fab)).perform(click())
// THEN - Verify that we navigate to the add screen
verify(navController).navigate(
TasksFragmentDirections.actionTasksFragmentToAddEditTaskFragment(
null, getApplicationContext<Context>().getString(R.string.add_task)
)
)
assertEquals(navController.currentDestination?.id, id.add_edit_task_fragment_dest)
}
private fun launchActivity(): ActivityScenario<TasksActivity>? {
......
......@@ -105,7 +105,7 @@ fun DataBindingIdlingResource.monitorActivity(
/**
* Sets the fragment from a [FragmentScenario] to be used from [DataBindingIdlingResource].
*/
fun DataBindingIdlingResource.monitorFragment(fragmentScenario: FragmentScenario<out Fragment>) {
fun <T : Fragment> DataBindingIdlingResource.monitorFragment(fragmentScenario: FragmentScenario<T>) {
fragmentScenario.onFragment {
this.activity = it.requireActivity()
}
......
buildscript {
ext.kotlinVersion = '1.3.61'
ext.navigationVersion = '2.2.0-rc02'
ext.kotlinVersion = '1.5.10'
ext.navigationVersion = '2.3.5'
ext.ktlintVersion = '0.33.0'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.2'
classpath 'com.android.tools.build:gradle:4.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"
......@@ -17,7 +17,7 @@ buildscript {
}
plugins {
id "com.diffplug.gradle.spotless" version "3.24.0"
id "com.diffplug.spotless" version "5.12.5"
}
allprojects {
......@@ -25,7 +25,7 @@ allprojects {
google()
jcenter()
}
apply plugin: 'com.diffplug.gradle.spotless'
apply plugin: 'com.diffplug.spotless'
spotless {
kotlin {
target "**/*.kt"
......@@ -38,35 +38,34 @@ allprojects {
// Define versions in a single place
ext {
// Sdk and tools
// Support library and architecture components support minSdk 14 and above.
minSdkVersion = 14
targetSdkVersion = 28
compileSdkVersion = 28
minSdkVersion = 21
targetSdkVersion = 30
compileSdkVersion = 30
// App dependencies
androidXVersion = '1.0.0'
androidXTestCoreVersion = '1.2.0'
androidXTestExtKotlinRunnerVersion = '1.1.1'
androidXTestCoreVersion = '1.3.0'
androidXTestExtKotlinRunnerVersion = '1.1.2'
androidXTestRulesVersion = '1.2.0'
androidXAnnotations = '1.1.0'
androidXAnnotations = '1.2.0'
androidXLegacySupport = '1.0.0'
appCompatVersion = '1.1.0'
archLifecycleVersion = '2.2.0-rc02'
appCompatVersion = '1.3.0'
archLifecycleVersion = '2.3.1'
archTestingVersion = '2.1.0'
cardVersion = '1.0.0'
coroutinesVersion = '1.2.1'
coroutinesVersion = '1.5.0'
dexMakerVersion = '2.12.1'
espressoVersion = '3.2.0'
fragmentVersion = '1.2.0-rc02'
fragmentKtxVersion = '1.1.0-rc01'
espressoVersion = '3.3.0'
fragmentVersion = '1.3.4'
fragmentKtxVersion = '1.3.4'
hamcrestVersion = '1.3'
junitVersion = '4.12'
materialVersion = '1.0.0'
mockitoVersion = '2.19.0'
recyclerViewVersion = '1.1.0'
robolectricVersion = '4.3.1'
roomVersion = '2.2.2'
junitVersion = '4.13.1'
materialVersion = '1.3.0'
multiDexVersion = '2.0.1'
recyclerViewVersion = '1.2.0'
robolectricVersion = '4.5.1'
roomVersion = '2.3.0'
rulesVersion = '1.0.1'
timberVersion = '4.7.1'
truthVersion = '1.0'
truthVersion = '1.1.2'
}
......@@ -18,6 +18,5 @@
# org.gradle.parallel=true
android.enableJetifier=true
android.useAndroidX=true
android.enableUnitTestBinaryResources=true
android.enableR8=true
kapt.incremental.apt=true
#Thu Apr 04 11:20:54 PDT 2019
#Tue Jun 01 08:01:38 UTC 2021
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
zipStoreBase=GRADLE_USER_HOME
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册