Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Navigation] Introduce NavBackStackEntry#provideToCompositionLocals #175

Prev Previous commit
Next Next commit
Use TestNavigatorState to set up NavBackStackEntry instead of the ugl…
…y createActiveBackStackEntry hack

Change-Id: I8b7101292e107dded8426a7e38f100451720ac95
  • Loading branch information
jossiwolf committed May 6, 2021
commit 3755c153d7b5bd63a957bbca1e0293f23b4d0068
Original file line number Diff line number Diff line change
@@ -16,37 +16,24 @@

package androidx.navigation.compose

import android.os.Bundle
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.SaveableStateHolder
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.platform.LocalSavedStateRegistryOwner
import androidx.compose.ui.test.junit4.StateRestorationTester
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModelStoreOwner
import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner
import androidx.navigation.NavDestination
import androidx.navigation.NavigatorState
import androidx.navigation.testing.TestNavigatorState
import androidx.savedstate.SavedStateRegistryOwner
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread
import androidx.testutils.TestNavigator
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import kotlinx.coroutines.runBlocking
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.random.Random

@RunWith(AndroidJUnit4::class)
class NavBackStackEntryProviderTest {
@@ -58,10 +45,13 @@ class NavBackStackEntryProviderTest {
fun testViewModelStoreOwnerProvided() {
val testNavigator = TestNavigator()
val testNavigatorState = TestNavigatorState()
val backStackEntry = testNavigatorState.createActiveBackStackEntry(
testNavigator.onAttach(testNavigatorState)
val backStackEntry = testNavigatorState.createBackStackEntry(
testNavigator.createDestination(),
null
)
testNavigator.navigate(listOf(backStackEntry), null, null)

var viewModelStoreOwner: ViewModelStoreOwner? = null

composeTestRule.setContent {
@@ -78,9 +68,14 @@ class NavBackStackEntryProviderTest {
@Test
fun testLifecycleOwnerProvided() {
val testNavigator = TestNavigator()
val navigatorState = TestNavigatorState()
val backStackEntry =
navigatorState.createActiveBackStackEntry(testNavigator.createDestination())
val testNavigatorState = TestNavigatorState()
testNavigator.onAttach(testNavigatorState)
val backStackEntry = testNavigatorState.createBackStackEntry(
testNavigator.createDestination(),
null
)
testNavigator.navigate(listOf(backStackEntry), null, null)

var lifecycleOwner: LifecycleOwner? = null

composeTestRule.setContent {
@@ -97,9 +92,14 @@ class NavBackStackEntryProviderTest {
@Test
fun testLocalSavedStateRegistryOwnerProvided() {
val testNavigator = TestNavigator()
val navigatorState = TestNavigatorState()
val backStackEntry =
navigatorState.createActiveBackStackEntry(testNavigator.createDestination())
val testNavigatorState = TestNavigatorState()
testNavigator.onAttach(testNavigatorState)
val backStackEntry = testNavigatorState.createBackStackEntry(
testNavigator.createDestination(),
null
)
testNavigator.navigate(listOf(backStackEntry), null, null)

var localSavedStateRegistryOwner: SavedStateRegistryOwner? = null

composeTestRule.setContent {
@@ -115,14 +115,18 @@ class NavBackStackEntryProviderTest {

@Test
fun testSaveableValueInContentIsSaved() {
val testNavigator = TestNavigator()
val testNavigatorState = TestNavigatorState()
testNavigator.onAttach(testNavigatorState)
val backStackEntry = testNavigatorState.createBackStackEntry(
testNavigator.createDestination(),
null
)
testNavigator.navigate(listOf(backStackEntry), null, null)

val restorationTester = StateRestorationTester(composeTestRule)
var array: IntArray? = null

val testNavigator = TestNavigator()
val navigatorState = TestNavigatorState()
val backStackEntry =
navigatorState.createActiveBackStackEntry(testNavigator.createDestination())

restorationTester.setContent {
val saveableStateHolder = rememberSaveableStateHolder()
backStackEntry.provideToCompositionLocals(saveableStateHolder) {
@@ -144,16 +148,4 @@ class NavBackStackEntryProviderTest {

assertThat(array).isEqualTo(intArrayOf(1))
}

// By default, NavBackStackEntrys are in the INITIALIZED state and then get moved to the next
// appropriate state by the NavController. In case we aren't testing with a NavController,
// this sets the entry's lifecycle state to the passed state so that the entry is active.
private fun NavigatorState.createActiveBackStackEntry(
destination: NavDestination,
arguments: Bundle? = null,
lifecycleState: Lifecycle.State = Lifecycle.State.RESUMED
) = createBackStackEntry(destination, arguments).apply {
runOnUiThread { maxLifecycle = lifecycleState }
}

}
Original file line number Diff line number Diff line change
@@ -30,7 +30,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavBackStackEntry
import java.util.UUID


/**
* Provides [this] [NavBackStackEntry] as [LocalViewModelStoreOwner], [LocalLifecycleOwner] and
* [LocalSavedStateRegistryOwner] to the [content] and saves the [content]'s saveable states with