Update project dependencies#148
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the project to Gradle 9.5.1, bumps various library versions, and centralizes Kotlin configuration by removing the kotlin-android plugin from individual modules. It also includes a critical fix in ThemeDataMapper.kt to correctly map AppTheme.System to UiModeManager.MODE_NIGHT_AUTO and refactors test helpers in SettingsViewModelTest to use more idiomatic Turbine-based assertions.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| AppTheme.DarkAppTheme -> UiModeManager.MODE_NIGHT_YES | ||
| AppTheme.LightAppTheme -> UiModeManager.MODE_NIGHT_NO | ||
| AppTheme.System -> UiModeManager.MODE_NIGHT_AUTO | ||
| AppTheme.System -> UiModeManager.MODE_NIGHT_CUSTOM |
There was a problem hiding this comment.
Mapping AppTheme.System to UiModeManager.MODE_NIGHT_CUSTOM is incorrect and will cause a bug. MODE_NIGHT_CUSTOM is used for custom night mode schedules (e.g., specific start/end times), which does not align with following the system-wide theme.
According to the Android documentation for UiModeManager.setApplicationNightMode (the API used to set app-specific night mode on API 31+), UiModeManager.MODE_NIGHT_AUTO should be used to reset the application night mode to follow the system night mode. Therefore, AppTheme.System should map to UiModeManager.MODE_NIGHT_AUTO.
| AppTheme.System -> UiModeManager.MODE_NIGHT_CUSTOM | |
| AppTheme.System -> UiModeManager.MODE_NIGHT_AUTO |
| internal suspend fun SettingsViewModel.assertHasState( | ||
| expected: SettingsState, | ||
| action: SettingsViewModel.() -> Unit, | ||
| ) = | ||
| state.test { | ||
| awaitItem() | ||
| delay(1) | ||
| this@assertHasState.action() | ||
| var current = this@assertHasState.state.value | ||
| var attempts = 0 | ||
| while (current != expected && attempts < STATE_ASSERTION_ATTEMPTS) { | ||
| delay(1) | ||
| current = this@assertHasState.state.value | ||
| attempts++ | ||
| } | ||
| assertThat(current).isEqualTo(expected) | ||
| cancelAndIgnoreRemainingEvents() | ||
| } |
There was a problem hiding this comment.
Instead of using a manual polling loop with delay(1) and STATE_ASSERTION_ATTEMPTS to assert the state, you can reuse the existing assertHasState(expected) extension function defined on TurbineTestContext<SettingsState> (lines 198-202).
This approach is much cleaner, idiomatic, and leverages Turbine's built-in flow collection and timeout mechanisms, completely eliminating the need for manual delays and polling.
internal suspend fun SettingsViewModel.assertHasState(
expected: SettingsState,
action: SettingsViewModel.() -> Unit,
) =
state.test {
awaitItem()
this@assertHasState.action()
assertHasState(expected)
cancelAndIgnoreRemainingEvents()
}
Summary
Notes
Validation
JAVA_HOME=$(/usr/libexec/java_home -v 21) ./gradlew assembleDebug testDebugUnitTest --stacktrace --no-daemon --no-configuration-cache --no-parallel --console=plain