Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
57bd271
feat: add auto scroll switch composable
superus8r Aug 30, 2025
664b0cd
tests: add auto scroll setting to getFakeUserSettingRepository
superus8r Aug 30, 2025
5c7e9bf
res: add auto-scroll terminal output label to settings
superus8r Aug 30, 2025
4f164cf
feat: add auto scroll preference to UserSettingRepository; move tests…
superus8r Aug 30, 2025
be838c1
feat: implement GetAutoScrollUseCase and its test
superus8r Aug 30, 2025
e618352
feat: implement SetAutoScrollUseCase and its test
superus8r Aug 30, 2025
6bd22b2
tests: enhance GetAutoScrollUseCaseTest with additional assertions fo…
superus8r Aug 30, 2025
18c9e99
feat: add providers for GetAutoScrollUseCase and SetAutoScrollUseCase…
superus8r Aug 30, 2025
6bb5700
feat: add autoScroll preference to UserSettingPreferences data class
superus8r Aug 30, 2025
795acff
test: add cleanup method
superus8r Aug 30, 2025
398efae
feat: add autoScroll functionality to SettingViewModel and add tests …
superus8r Aug 30, 2025
e69868a
feat: add auto-scroll toggle to settings UI
superus8r Aug 30, 2025
9ecf7b2
feat: implement auto-scroll functionality in MainActivity based on se…
superus8r Aug 30, 2025
cb894e6
feat: set default auto-scroll value when the user clicks on default b…
superus8r Aug 30, 2025
b51a688
test: move Get/Set-CustomBaudRateUseCase tests to unit tests director…
superus8r Aug 30, 2025
db7935e
refactor: remove FrequentMocks.kt
superus8r Aug 30, 2025
5929df8
test: add Compose tests for SettingContent to verify displayed texts
superus8r Aug 30, 2025
2b59b2e
fix: improve auto-scroll text in settings item
superus8r Aug 30, 2025
14945c3
refactor: rename auto-scroll setting component to SettingSwitchItem f…
superus8r Aug 30, 2025
e8450f3
tests: add Android Compose tests for SettingSwitchItem functionality
superus8r Aug 30, 2025
90dd528
refactor: change interface declaration to a fun interface for GetAuto…
superus8r Aug 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ dependencies {

// Instrumented Test Libraries
androidTestImplementation(composeBom)
androidTestImplementation(libs.compose.ui.test.junit4)
debugImplementation(libs.compose.ui.test.manifest)
androidTestImplementation(libs.coroutines.test)
androidTestImplementation(libs.androidx.test.core)
androidTestImplementation(libs.androidx.test.ext.junit)
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package org.kabiri.android.usbterminal.ui.setting

import androidx.activity.ComponentActivity
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.mockk.every
import io.mockk.mockk
import kotlinx.coroutines.flow.flowOf
import org.hamcrest.CoreMatchers.notNullValue
import org.hamcrest.MatcherAssert.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.kabiri.android.usbterminal.R
import org.kabiri.android.usbterminal.ui.theme.UsbTerminalTheme

@RunWith(AndroidJUnit4::class)
class SettingContentAndroidTest {
@get:Rule
val composeRule = createAndroidComposeRule<ComponentActivity>()

private fun showContet(viewModel: SettingViewModel) {
composeRule.setContent {
UsbTerminalTheme {
SettingContent(
settingViewModel = viewModel,
onDismiss = {},
)
}
}
}

@Test
fun settingContent_displaysExpectedTexts() {
// arrange
val context = composeRule.activity
assertThat(context, notNullValue())
val viewModel = mockk<SettingViewModel>(relaxed = true)
every { viewModel.currentBaudRate } returns flowOf(9600)
every { viewModel.currentAutoScroll } returns flowOf(true)

// act
showContet(viewModel)

// assert
composeRule.onNodeWithText(context.getString(R.string.settings_title)).assertIsDisplayed()
composeRule
.onNodeWithText(context.getString(R.string.settings_subtitle))
.assertIsDisplayed()

// Baud rate label (ensure unmerged tree so label is found)
composeRule
.onNodeWithText(
context.getString(R.string.settings_label_baud_rate),
useUnmergedTree = true,
).assertIsDisplayed()

// Buttons and bottom text
composeRule
.onNodeWithText(context.getString(R.string.settings_bt_reset_default))
.assertIsDisplayed()
composeRule
.onNodeWithText(context.getString(R.string.settings_bt_dismiss_sheet))
.assertIsDisplayed()
composeRule
.onNodeWithText(context.getString(R.string.settings_bottom_text))
.assertIsDisplayed()

// Auto-scroll label
composeRule
.onNodeWithText(context.getString(R.string.settings_label_auto_scroll))
.assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package org.kabiri.android.usbterminal.ui.setting

import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsOff
import androidx.compose.ui.test.assertIsOn
import androidx.compose.ui.test.hasAnySibling
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.isToggleable
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.kabiri.android.usbterminal.R
import org.kabiri.android.usbterminal.ui.theme.UsbTerminalTheme

@RunWith(AndroidJUnit4::class)
class SettingSwitchItemAndroidTest {
@get:Rule
val composeRule = createAndroidComposeRule<ComponentActivity>()

private fun showContet(enabled: Boolean = true) {
composeRule.setContent {
UsbTerminalTheme {
SettingSwitchItem(
enabled = enabled,
onToggle = {},
modifier = Modifier.fillMaxSize(),
)
}
}
}

@Test
fun autoScrollSwitch_displaysLabel() {
// arrange
val context = composeRule.activity

// act
showContet()

// assert
composeRule
.onNodeWithText(context.getString(R.string.settings_label_auto_scroll))
.assertIsDisplayed()
}

@Test
fun autoScrollSwitch_isOn_whenEnabledTrue() {
// arrange
val context = composeRule.activity

// act
showContet(enabled = true)

// assert
composeRule
.onNode(
hasAnySibling(
hasText(context.getString(R.string.settings_label_auto_scroll)),
).and(isToggleable()),
).assertIsOn()
}

@Test
fun autoScrollSwitch_isOff_whenEnabledFalse() {
// arrange
val context = composeRule.activity

// act
showContet(enabled = false)

// assert
composeRule
.onNode(
hasAnySibling(
hasText(context.getString(R.string.settings_label_auto_scroll)),
).and(isToggleable()),
).assertIsOff()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,19 @@ class MainActivity : AppCompatActivity() {
// make the text view scrollable:
tvOutput.movementMethod = ScrollingMovementMethod()

var autoScrollEnabled = true
lifecycleScope.launch {
settingViewModel.currentAutoScroll.collect { enabled ->
autoScrollEnabled = enabled
}
}

lifecycleScope.launch {
viewModel.getLiveOutput()
viewModel.output.collect {
tvOutput.apply {
text = it
scrollToLastLine()
if (autoScrollEnabled) scrollToLastLine()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.launch
import org.kabiri.android.usbterminal.R
import org.kabiri.android.usbterminal.domain.IGetCustomBaudRateUseCase
import org.kabiri.android.usbterminal.model.defaultBaudRate
import org.kabiri.android.usbterminal.model.DEFAULT_BAUD_RATE
import javax.inject.Inject

/**
Expand Down Expand Up @@ -44,7 +44,7 @@ internal class ArduinoRepository
private val getBaudRate: IGetCustomBaudRateUseCase,
): IArduinoRepository {

private var currentBaudRate = defaultBaudRate // Default value
private var currentBaudRate = DEFAULT_BAUD_RATE // Default value

private val _messageFlow = MutableStateFlow("")
override val messageFlow: Flow<String>
Expand Down
Loading