[go: nahoru, domu]

blob: 9d1227e967df6e0259290c1a416f34e241aed835 [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.navigation.compose
import androidx.annotation.IdRes
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.savedinstancestate.rememberSavedInstanceState
import androidx.compose.ui.platform.ContextAmbient
import androidx.navigation.NavDestination
import androidx.navigation.NavDestinationBuilder
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.contains
import androidx.navigation.testing.TestNavHostController
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread
import androidx.ui.test.createComposeRule
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@LargeTest
@RunWith(AndroidJUnit4::class)
class NavHostTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun testSingleDestinationSet() {
lateinit var navController: NavHostController
composeTestRule.setContent {
navController = TestNavHostController(ContextAmbient.current)
NavHost(navController, startDestination = "First") {
test("First")
}
}
assertWithMessage("Destination should be added to the graph")
.that(generateId("First") in navController.graph)
.isTrue()
}
@Test
fun testNavigate() {
lateinit var navController: NavHostController
composeTestRule.setContent {
navController = TestNavHostController(ContextAmbient.current)
NavHost(navController, startDestination = "First") {
test("First")
test("Second")
}
}
assertWithMessage("Destination should be added to the graph")
.that(generateId("First") in navController.graph)
.isTrue()
runOnUiThread {
navController.navigate("Second")
}
assertWithMessage("Second destination should be current")
.that(navController.currentDestination?.id)
.isEqualTo(generateId("Second"))
}
@Test
fun testPop() {
lateinit var navController: TestNavHostController
composeTestRule.setContent {
navController = TestNavHostController(ContextAmbient.current)
NavHost(navController, startDestination = "First") {
test("First")
test("Second")
}
}
runOnUiThread {
navController.setCurrentDestination(generateId("Second"))
navController.popBackStack()
}
assertWithMessage("First destination should be current")
.that(navController.currentDestination?.id)
.isEqualTo(generateId("First"))
}
@Test
fun testChangeStartDestination() {
lateinit var navController: TestNavHostController
lateinit var state: MutableState<String>
composeTestRule.setContent {
state = remember { mutableStateOf("First") }
navController = TestNavHostController(ContextAmbient.current)
NavHost(navController, startDestination = state.value) {
test("First")
test("Second")
}
}
runOnUiThread {
state.value = "Second"
}
composeTestRule.runOnIdle {
assertWithMessage("Second destination should be current")
.that(navController.currentDestination?.id)
.isEqualTo(generateId("Second"))
}
}
@Test
fun testStateOfInactiveScreenIsRestoredWhenWeGoBackToIt() {
var increment = 0
var numberOnScreen1 = -1
lateinit var navController: NavHostController
composeTestRule.setContent {
navController = rememberNavController()
NavHost(navController, startDestination = "First") {
composable("First") {
numberOnScreen1 = rememberSavedInstanceState { increment++ }
}
composable("Second") {}
}
}
composeTestRule.runOnIdle {
assertWithMessage("Initial number should be 0")
.that(numberOnScreen1)
.isEqualTo(0)
numberOnScreen1 = -1
navController.navigate("Second")
}
composeTestRule.runOnIdle {
navController.popBackStack()
}
composeTestRule.runOnIdle {
assertWithMessage("The number should be restored")
.that(numberOnScreen1)
.isEqualTo(0)
}
}
@Test
fun stateForScreenRemovedFromBackStackIsNotRestored() {
var increment = 0
var numberOnScreen2 = -1
lateinit var navController: NavHostController
composeTestRule.setContent {
navController = rememberNavController()
NavHost(navController, startDestination = "First") {
composable("First") {
}
composable("Second") {
numberOnScreen2 = rememberSavedInstanceState { increment++ }
}
}
}
composeTestRule.runOnIdle {
navController.navigate("Second")
}
composeTestRule.runOnIdle {
assertWithMessage("Initial number should be 0")
.that(numberOnScreen2)
.isEqualTo(0)
numberOnScreen2 = -1
navController.popBackStack()
}
composeTestRule.runOnIdle {
navController.navigate("Second")
}
composeTestRule.runOnIdle {
assertWithMessage("The number shouldn't be restored")
.that(numberOnScreen2)
.isEqualTo(1)
}
}
}
private inline fun NavGraphBuilder.test(
@IdRes id: Any,
builder: NavDestinationBuilder<NavDestination>.() -> Unit = { }
) = test(generateId(id), builder)