mirror of
https://github.com/msfjarvis/compose-lobsters
synced 2025-08-18 03:17:03 +05:30
Add test for BottomNavigationLayout
Signed-off-by: Aditya Wasan <adityawasan55@gmail.com>
This commit is contained in:
parent
91cfb0b2d2
commit
25b3ad4f8e
2 changed files with 125 additions and 10 deletions
|
@ -0,0 +1,115 @@
|
||||||
|
package dev.msfjarvis.lobsters
|
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.ui.test.assertContentDescriptionEquals
|
||||||
|
import androidx.compose.ui.test.assertCountEquals
|
||||||
|
import androidx.compose.ui.test.assertHasClickAction
|
||||||
|
import androidx.compose.ui.test.assertIsDisplayed
|
||||||
|
import androidx.compose.ui.test.assertIsNotSelected
|
||||||
|
import androidx.compose.ui.test.assertIsSelected
|
||||||
|
import androidx.compose.ui.test.assertTextEquals
|
||||||
|
import androidx.compose.ui.test.junit4.createComposeRule
|
||||||
|
import androidx.compose.ui.test.onChildAt
|
||||||
|
import androidx.compose.ui.test.onChildren
|
||||||
|
import androidx.compose.ui.test.onNodeWithTag
|
||||||
|
import androidx.compose.ui.test.performClick
|
||||||
|
import dev.msfjarvis.lobsters.ui.main.LobstersBottomNav
|
||||||
|
import dev.msfjarvis.lobsters.ui.navigation.Destination
|
||||||
|
import dev.msfjarvis.lobsters.ui.theme.LobstersTheme
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
||||||
|
class BottomNavigationLayoutTest {
|
||||||
|
|
||||||
|
@get:Rule
|
||||||
|
val composeTestRule = createComposeRule()
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setUp() {
|
||||||
|
composeTestRule.setContent {
|
||||||
|
LobstersTheme {
|
||||||
|
var mutableDestination by remember { mutableStateOf(Destination.startDestination) }
|
||||||
|
|
||||||
|
LobstersBottomNav(
|
||||||
|
currentDestination = mutableDestination,
|
||||||
|
navigateToDestination = { mutableDestination = it },
|
||||||
|
jumpToIndex = {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun bottomNavItemCountTest() {
|
||||||
|
// Test to make sure total items are equal to enum objects present in Destination
|
||||||
|
composeTestRule.onNodeWithTag("LobstersBottomNav")
|
||||||
|
.assertExists()
|
||||||
|
.assertIsDisplayed()
|
||||||
|
.onChildren()
|
||||||
|
.assertCountEquals(Destination.values().size)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun bottomNavItemTest() {
|
||||||
|
// Check hottest BottomNavItem is rendered correctly
|
||||||
|
composeTestRule.onNodeWithTag("LobstersBottomNav")
|
||||||
|
.assertExists()
|
||||||
|
.assertIsDisplayed()
|
||||||
|
.onChildAt(0)
|
||||||
|
.assertTextEquals("Hottest")
|
||||||
|
.assertContentDescriptionEquals("Hottest")
|
||||||
|
.assertHasClickAction()
|
||||||
|
|
||||||
|
// Check saved BottomNavItem is rendered correctly
|
||||||
|
composeTestRule.onNodeWithTag("LobstersBottomNav")
|
||||||
|
.assertExists()
|
||||||
|
.assertIsDisplayed()
|
||||||
|
.onChildAt(1)
|
||||||
|
.assertTextEquals("Saved")
|
||||||
|
.assertContentDescriptionEquals("Saved")
|
||||||
|
.assertHasClickAction()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun bottomNavItemSelectedTest() {
|
||||||
|
// Check hottest BottomNav item is selected
|
||||||
|
composeTestRule.onNodeWithTag("LobstersBottomNav")
|
||||||
|
.assertExists()
|
||||||
|
.assertIsDisplayed()
|
||||||
|
.onChildAt(0)
|
||||||
|
.assertIsSelected()
|
||||||
|
.assertTextEquals("Hottest")
|
||||||
|
|
||||||
|
// Check saved BottomNav item is not selected
|
||||||
|
composeTestRule.onNodeWithTag("LobstersBottomNav")
|
||||||
|
.assertExists()
|
||||||
|
.assertIsDisplayed()
|
||||||
|
.onChildAt(1)
|
||||||
|
.assertIsNotSelected()
|
||||||
|
|
||||||
|
// Select the saved BottomNav item
|
||||||
|
composeTestRule.onNodeWithTag("LobstersBottomNav")
|
||||||
|
.onChildAt(1)
|
||||||
|
.performClick()
|
||||||
|
|
||||||
|
// Check hottest BottomNav item is not selected
|
||||||
|
composeTestRule.onNodeWithTag("LobstersBottomNav")
|
||||||
|
.assertExists()
|
||||||
|
.assertIsDisplayed()
|
||||||
|
.onChildAt(0)
|
||||||
|
.assertIsNotSelected()
|
||||||
|
|
||||||
|
// Check saved BottomNav item is selected
|
||||||
|
composeTestRule.onNodeWithTag("LobstersBottomNav")
|
||||||
|
.assertExists()
|
||||||
|
.assertIsDisplayed()
|
||||||
|
.onChildAt(1)
|
||||||
|
.assertIsSelected()
|
||||||
|
.assertTextEquals("Saved")
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import android.os.Bundle
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material.BottomNavigation
|
import androidx.compose.material.BottomNavigation
|
||||||
import androidx.compose.material.BottomNavigationItem
|
import androidx.compose.material.BottomNavigationItem
|
||||||
|
@ -16,6 +15,7 @@ import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.testTag
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import androidx.navigation.compose.KEY_ROUTE
|
import androidx.navigation.compose.KEY_ROUTE
|
||||||
|
@ -35,7 +35,6 @@ import dev.msfjarvis.lobsters.ui.urllauncher.UrlLauncher
|
||||||
import dev.msfjarvis.lobsters.ui.viewmodel.LobstersViewModel
|
import dev.msfjarvis.lobsters.ui.viewmodel.LobstersViewModel
|
||||||
import dev.msfjarvis.lobsters.util.IconResource
|
import dev.msfjarvis.lobsters.util.IconResource
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
|
@ -73,14 +72,18 @@ fun LobstersApp() {
|
||||||
popUpTo(navController.graph.startDestination) { inclusive = false }
|
popUpTo(navController.graph.startDestination) { inclusive = false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val jumpToIndex: (Int) -> Unit = {
|
||||||
|
coroutineScope.launch {
|
||||||
|
hottestPostsListState.snapToItemIndex(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
LobstersBottomNav(
|
LobstersBottomNav(
|
||||||
hottestPostsListState,
|
|
||||||
coroutineScope,
|
|
||||||
currentDestination,
|
currentDestination,
|
||||||
navigateToDestination,
|
navigateToDestination,
|
||||||
|
jumpToIndex,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) { innerPadding ->
|
) { innerPadding ->
|
||||||
|
@ -107,12 +110,11 @@ fun LobstersApp() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LobstersBottomNav(
|
fun LobstersBottomNav(
|
||||||
hottestPostsListState: LazyListState,
|
|
||||||
coroutineScope: CoroutineScope,
|
|
||||||
currentDestination: Destination,
|
currentDestination: Destination,
|
||||||
navigateToDestination: (destination: Destination) -> Unit,
|
navigateToDestination: (destination: Destination) -> Unit,
|
||||||
|
jumpToIndex: (index: Int) -> Unit,
|
||||||
) {
|
) {
|
||||||
BottomNavigation {
|
BottomNavigation(modifier = Modifier.testTag("LobstersBottomNav")) {
|
||||||
Destination.values().forEach { screen ->
|
Destination.values().forEach { screen ->
|
||||||
BottomNavigationItem(
|
BottomNavigationItem(
|
||||||
icon = {
|
icon = {
|
||||||
|
@ -128,9 +130,7 @@ fun LobstersBottomNav(
|
||||||
if (screen != currentDestination) {
|
if (screen != currentDestination) {
|
||||||
navigateToDestination(screen)
|
navigateToDestination(screen)
|
||||||
} else if (screen.route == Destination.Hottest.route) {
|
} else if (screen.route == Destination.Hottest.route) {
|
||||||
coroutineScope.launch {
|
jumpToIndex(0)
|
||||||
hottestPostsListState.snapToItemIndex(0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue