From 9957f9ea5ff8f106cb2fb4ac663727a69ddc4223 Mon Sep 17 00:00:00 2001 From: CXwudi Date: Sat, 2 Dec 2023 01:04:52 -0500 Subject: [PATCH] :sparkles: Added controller parameters to Composables for testability Refactored several composable functions within our main UI package by passing controllers as default parameters. This change enhances our tests' flexibility as it allows for the use of staged controllers and objects other than the real controller objects. Additionally, an overflow property with Ellipsis was added to the FinishMessagePanel. --- .../ui/component/main/FinishMessagePanel.kt | 2 ++ .../ui/component/main/MainScreen.kt | 9 +++++--- .../ui/component/main/ProgressBar.kt | 6 +++-- .../ui/component/main/RegexMatchOption.kt | 22 +++++++++---------- .../ui/component/main/ResultPanel.kt | 8 ++++--- .../songfinder/ui/component/main/SearchBar.kt | 6 +++-- 6 files changed, 32 insertions(+), 21 deletions(-) diff --git a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/FinishMessagePanel.kt b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/FinishMessagePanel.kt index 410f5c9..101bca0 100644 --- a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/FinishMessagePanel.kt +++ b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/FinishMessagePanel.kt @@ -4,11 +4,13 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextOverflow @Composable fun FinishMessagePanel(modifier: Modifier = Modifier) { Text( "All Done!", style = MaterialTheme.typography.titleMedium, + overflow = TextOverflow.Ellipsis, ) } \ No newline at end of file diff --git a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/MainScreen.kt b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/MainScreen.kt index 4bdd17d..8cb86c2 100644 --- a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/MainScreen.kt +++ b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/MainScreen.kt @@ -22,8 +22,11 @@ import mikufan.cx.songfinder.ui.theme.MyAppThemeWithSurface import java.time.LocalDateTime @Composable -fun MainScreen() { - val finishedState = getSpringBean().isFinishedState +fun MainScreen( + mainScreenController: MainScreenController = getSpringBean(), + modifier: Modifier = Modifier, +) { + val finishedState = mainScreenController.isFinishedState RealMainScreen(finishedState) } @@ -66,7 +69,7 @@ fun PreviewMainScreen() { {}, ) ) - RealRegexMatchOption(SearchRegexOption.Exact, {}) + RealRegexMatchOption(mutableStateOf(SearchRegexOption.Exact)) {} RealResultPanel( listOf( SongSearchResult( diff --git a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/ProgressBar.kt b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/ProgressBar.kt index 353149a..89ce7dd 100644 --- a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/ProgressBar.kt +++ b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/ProgressBar.kt @@ -22,8 +22,10 @@ import mikufan.cx.songfinder.ui.theme.MyAppThemeWithSurface @Composable -fun ProgressBar(modifier: Modifier = Modifier) { - val controller = getSpringBean() +fun ProgressBar( + controller: ProgressBarController = getSpringBean(), + modifier: Modifier = Modifier +) { val currentCount by controller.currentIndexState val totalCount = remember { controller.totalCount } RealProgressBar(currentCount, totalCount, modifier) diff --git a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/RegexMatchOption.kt b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/RegexMatchOption.kt index 6a9ea3a..3908d0d 100644 --- a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/RegexMatchOption.kt +++ b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/RegexMatchOption.kt @@ -1,6 +1,5 @@ package mikufan.cx.songfinder.ui.component.main -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row @@ -8,7 +7,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue +import androidx.compose.runtime.State import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -24,10 +23,11 @@ import mikufan.cx.songfinder.ui.theme.spacing * */ @Composable -fun RegexMatchOption() { - val controller = getSpringBean() - val option by controller.currentRegexOptionState - RealRegexMatchOption(option, controller::setRegexOption) +fun RegexMatchOption( + controller: RegexMatchOptionController = getSpringBean(), + modifier: Modifier = Modifier, +) { + RealRegexMatchOption(controller.currentRegexOptionState, controller::setRegexOption) } @@ -38,7 +38,8 @@ fun RegexMatchOption() { * @param onOptionSet The callback function called when a regex option is selected. */ @Composable -fun RealRegexMatchOption(option: SearchRegexOption, onOptionSet: suspend (SearchRegexOption) -> Unit) = RowCentralizedWithSpacing( +fun RealRegexMatchOption(option: State, onOptionSet: suspend (SearchRegexOption) -> Unit) = + RowCentralizedWithSpacing( horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.spacing) ) { Text("Regex Match Option: ") @@ -51,14 +52,13 @@ fun RealRegexMatchOption(option: SearchRegexOption, onOptionSet: suspend (Search * Composable function to render a single regex match option. * * @param renderedOption The regex option to render. - * @param selectedOption The currently selected regex option. + * @param selectedOptionState The currently selected regex option. * @param onOptionSet The callback function called when a regex option is selected. */ -@OptIn(ExperimentalFoundationApi::class) @Composable fun RegexMatchOptionButton( renderedOption: SearchRegexOption, - selectedOption: SearchRegexOption, + selectedOptionState: State, onOptionSet: suspend (SearchRegexOption) -> Unit ) = Row( modifier = Modifier, @@ -66,7 +66,7 @@ fun RegexMatchOptionButton( ) { val scope = rememberCoroutineScope() RadioButton( - selected = renderedOption == selectedOption, + selected = renderedOption == selectedOptionState.value, onClick = { scope.launch { onOptionSet(renderedOption) } } ) Text( diff --git a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/ResultPanel.kt b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/ResultPanel.kt index bdd61d5..ec191bf 100644 --- a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/ResultPanel.kt +++ b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/ResultPanel.kt @@ -20,10 +20,12 @@ import mikufan.cx.songfinder.ui.theme.spacing * Retrieves the current result state from the controller and passes it to the RealResultPanel composable. */ @Composable -fun ResultPanel() { - val controller = getSpringBean() +fun ResultPanel( + controller: ResultPanelController = getSpringBean(), + modifier: Modifier = Modifier, +) { val resultList = controller.currentResultState - RealResultPanel(resultList) { result -> + RealResultPanel(resultList, modifier) { result -> ResultGridCell(result) } } diff --git a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/SearchBar.kt b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/SearchBar.kt index 82b2766..594ab55 100644 --- a/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/SearchBar.kt +++ b/songfinder-app/src/main/kotlin/mikufan/cx/songfinder/ui/component/main/SearchBar.kt @@ -27,8 +27,10 @@ import mikufan.cx.songfinder.ui.common.TooltipAreaWithCard * @param modifier The modifier to be applied to the search bar. */ @Composable -fun SearchBar(modifier: Modifier = Modifier) { - val controller = getSpringBean() +fun SearchBar( + controller: SearchBarController = getSpringBean(), + modifier: Modifier = Modifier +) { val inputState = controller.currentInputState val searchStatusState = controller.currentSearchStatusState val model = SearchBarModel(