Merge branch 'main' into trambui/navigation-null-debug

pull/1728/head
Tram Bui 2 weeks ago committed by GitHub
commit 0e52982866
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -5,3 +5,13 @@
ij_kotlin_allow_trailing_comma=true
ij_kotlin_allow_trailing_comma_on_call_site=true
ktlint_function_naming_ignore_when_annotated_with=Composable, Test
ktlint_standard_backing-property-naming = disabled
ktlint_standard_binary-expression-wrapping = disabled
ktlint_standard_chain-method-continuation = disabled
ktlint_standard_class-signature = disabled
ktlint_standard_condition-wrapping = disabled
ktlint_standard_function-expression-body = disabled
ktlint_standard_function-literal = disabled
ktlint_standard_function-type-modifier-spacing = disabled
ktlint_standard_multiline-loop = disabled
ktlint_standard_function-signature = disabled

@ -93,7 +93,9 @@ jobs:
continue-on-error: false
if: steps.screenshotsverify.outcome == 'failure' && github.event.pull_request.head.repo.full_name != github.repository
run: |
echo "::error::Screenshot tests failed, please create a PR in your fork first." && exit 1
echo "::error::Screenshot tests failed, please create a PR in your fork first."
echo "Your fork's CI will take screenshots for your fork."
exit 1
# Runs if previous job failed
- name: Generate new screenshots if verification failed and it's a PR
@ -166,7 +168,7 @@ jobs:
timeout-minutes: 55
strategy:
matrix:
api-level: [26, 30]
api-level: [26]
steps:
- name: Delete unnecessary tools 🔧
@ -235,7 +237,7 @@ jobs:
- name: Display local test coverage (only API 30)
if: matrix.api-level == 30
id: jacoco
uses: madrapps/jacoco-report@v1.7.0
uses: madrapps/jacoco-report@v1.7.1
with:
title: Combined test coverage report
min-coverage-overall: 40

@ -123,7 +123,6 @@ dependencies {
testDemoImplementation(libs.roborazzi)
testDemoImplementation(projects.core.screenshotTesting)
androidTestImplementation(kotlin("test"))
androidTestImplementation(projects.core.testing)
androidTestImplementation(projects.core.dataTest)
androidTestImplementation(projects.core.datastoreTest)
@ -131,6 +130,7 @@ dependencies {
androidTestImplementation(libs.androidx.navigation.testing)
androidTestImplementation(libs.androidx.compose.ui.test)
androidTestImplementation(libs.hilt.android.testing)
androidTestImplementation(libs.kotlin.test)
baselineProfile(projects.benchmarks)
}

@ -89,38 +89,38 @@ androidx.hilt:hilt-navigation:1.2.0
androidx.hilt:hilt-work:1.2.0
androidx.interpolator:interpolator:1.0.0
androidx.legacy:legacy-support-core-utils:1.0.0
androidx.lifecycle:lifecycle-common-java8:2.8.6
androidx.lifecycle:lifecycle-common-jvm:2.8.6
androidx.lifecycle:lifecycle-common:2.8.6
androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.6
androidx.lifecycle:lifecycle-livedata-core:2.8.6
androidx.lifecycle:lifecycle-livedata:2.8.6
androidx.lifecycle:lifecycle-process:2.8.6
androidx.lifecycle:lifecycle-runtime-android:2.8.6
androidx.lifecycle:lifecycle-runtime-compose-android:2.8.6
androidx.lifecycle:lifecycle-runtime-compose:2.8.6
androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.6
androidx.lifecycle:lifecycle-runtime-ktx:2.8.6
androidx.lifecycle:lifecycle-runtime:2.8.6
androidx.lifecycle:lifecycle-service:2.8.6
androidx.lifecycle:lifecycle-viewmodel-android:2.8.6
androidx.lifecycle:lifecycle-viewmodel-compose-android:2.8.6
androidx.lifecycle:lifecycle-viewmodel-compose:2.8.6
androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.6
androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.6
androidx.lifecycle:lifecycle-viewmodel:2.8.6
androidx.lifecycle:lifecycle-common-java8:2.8.7
androidx.lifecycle:lifecycle-common-jvm:2.8.7
androidx.lifecycle:lifecycle-common:2.8.7
androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.7
androidx.lifecycle:lifecycle-livedata-core:2.8.7
androidx.lifecycle:lifecycle-livedata:2.8.7
androidx.lifecycle:lifecycle-process:2.8.7
androidx.lifecycle:lifecycle-runtime-android:2.8.7
androidx.lifecycle:lifecycle-runtime-compose-android:2.8.7
androidx.lifecycle:lifecycle-runtime-compose:2.8.7
androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.7
androidx.lifecycle:lifecycle-runtime-ktx:2.8.7
androidx.lifecycle:lifecycle-runtime:2.8.7
androidx.lifecycle:lifecycle-service:2.8.7
androidx.lifecycle:lifecycle-viewmodel-android:2.8.7
androidx.lifecycle:lifecycle-viewmodel-compose-android:2.8.7
androidx.lifecycle:lifecycle-viewmodel-compose:2.8.7
androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7
androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.7
androidx.lifecycle:lifecycle-viewmodel:2.8.7
androidx.loader:loader:1.0.0
androidx.localbroadcastmanager:localbroadcastmanager:1.0.0
androidx.metrics:metrics-performance:1.0.0-beta01
androidx.navigation:navigation-common-ktx:2.8.0
androidx.navigation:navigation-common:2.8.0
androidx.navigation:navigation-compose:2.8.0
androidx.navigation:navigation-runtime-ktx:2.8.0
androidx.navigation:navigation-runtime:2.8.0
androidx.navigation:navigation-common-ktx:2.8.4
androidx.navigation:navigation-common:2.8.4
androidx.navigation:navigation-compose:2.8.4
androidx.navigation:navigation-runtime-ktx:2.8.4
androidx.navigation:navigation-runtime:2.8.4
androidx.print:print:1.0.0
androidx.privacysandbox.ads:ads-adservices-java:1.0.0-beta05
androidx.privacysandbox.ads:ads-adservices:1.0.0-beta05
androidx.profileinstaller:profileinstaller:1.3.1
androidx.profileinstaller:profileinstaller:1.4.1
androidx.resourceinspection:resourceinspection-annotation:1.0.1
androidx.room:room-common:2.6.1
androidx.room:room-ktx:2.6.1
@ -141,11 +141,11 @@ androidx.window.extensions.core:core:1.0.0
androidx.window:window-core-android:1.3.0
androidx.window:window-core:1.3.0
androidx.window:window:1.3.0
androidx.work:work-runtime-ktx:2.9.0
androidx.work:work-runtime:2.9.0
androidx.work:work-runtime-ktx:2.9.1
androidx.work:work-runtime:2.9.1
com.caverock:androidsvg-aar:1.4
com.google.accompanist:accompanist-drawablepainter:0.32.0
com.google.accompanist:accompanist-permissions:0.34.0
com.google.accompanist:accompanist-permissions:0.36.0
com.google.android.datatransport:transport-api:3.2.0
com.google.android.datatransport:transport-backend-cct:3.3.0
com.google.android.datatransport:transport-runtime:3.3.0
@ -153,12 +153,12 @@ com.google.android.gms:play-services-ads-identifier:18.0.0
com.google.android.gms:play-services-base:18.5.0
com.google.android.gms:play-services-basement:18.4.0
com.google.android.gms:play-services-cloud-messaging:17.2.0
com.google.android.gms:play-services-measurement-api:22.1.0
com.google.android.gms:play-services-measurement-base:22.1.0
com.google.android.gms:play-services-measurement-impl:22.1.0
com.google.android.gms:play-services-measurement-sdk-api:22.1.0
com.google.android.gms:play-services-measurement-sdk:22.1.0
com.google.android.gms:play-services-measurement:22.1.0
com.google.android.gms:play-services-measurement-api:22.1.2
com.google.android.gms:play-services-measurement-base:22.1.2
com.google.android.gms:play-services-measurement-impl:22.1.2
com.google.android.gms:play-services-measurement-sdk-api:22.1.2
com.google.android.gms:play-services-measurement-sdk:22.1.2
com.google.android.gms:play-services-measurement:22.1.2
com.google.android.gms:play-services-oss-licenses:17.1.0
com.google.android.gms:play-services-stats:17.0.2
com.google.android.gms:play-services-tasks:18.2.0
@ -169,15 +169,15 @@ com.google.dagger:hilt-android:2.52
com.google.dagger:hilt-core:2.52
com.google.errorprone:error_prone_annotations:2.26.0
com.google.firebase:firebase-abt:21.1.1
com.google.firebase:firebase-analytics:22.1.0
com.google.firebase:firebase-analytics:22.1.2
com.google.firebase:firebase-annotations:16.2.0
com.google.firebase:firebase-bom:33.3.0
com.google.firebase:firebase-bom:33.7.0
com.google.firebase:firebase-common-ktx:21.0.0
com.google.firebase:firebase-common:21.0.0
com.google.firebase:firebase-components:18.0.0
com.google.firebase:firebase-config-interop:16.0.1
com.google.firebase:firebase-config:22.0.0
com.google.firebase:firebase-crashlytics:19.1.0
com.google.firebase:firebase-config:22.0.1
com.google.firebase:firebase-crashlytics:19.3.0
com.google.firebase:firebase-datatransport:19.0.0
com.google.firebase:firebase-encoders-json:18.0.1
com.google.firebase:firebase-encoders-proto:16.0.0
@ -186,16 +186,15 @@ com.google.firebase:firebase-iid-interop:17.1.0
com.google.firebase:firebase-installations-interop:17.2.0
com.google.firebase:firebase-installations:18.0.0
com.google.firebase:firebase-measurement-connector:20.0.1
com.google.firebase:firebase-messaging:24.0.1
com.google.firebase:firebase-perf:21.0.1
com.google.firebase:firebase-sessions:2.0.4
com.google.firebase:protolite-well-known-types:18.0.0
com.google.firebase:firebase-messaging:24.1.0
com.google.firebase:firebase-perf:21.0.3
com.google.firebase:firebase-sessions:2.0.7
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:31.1-android
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.j2objc:j2objc-annotations:1.3
com.google.protobuf:protobuf-javalite:4.26.1
com.google.protobuf:protobuf-kotlin-lite:4.26.1
com.google.protobuf:protobuf-javalite:4.28.2
com.google.protobuf:protobuf-kotlin-lite:4.28.2
com.squareup.okhttp3:logging-interceptor:4.12.0
com.squareup.okhttp3:okhttp:4.12.0
com.squareup.okio:okio-jvm:3.9.0

@ -21,6 +21,7 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.gradle.kotlin.dsl.exclude
class AndroidApplicationFirebaseConventionPlugin : Plugin<Project> {
override fun apply(target: Project) {
@ -35,7 +36,16 @@ class AndroidApplicationFirebaseConventionPlugin : Plugin<Project> {
val bom = libs.findLibrary("firebase-bom").get()
add("implementation", platform(bom))
"implementation"(libs.findLibrary("firebase.analytics").get())
"implementation"(libs.findLibrary("firebase.performance").get())
"implementation"(libs.findLibrary("firebase.performance").get()) {
/*
Exclusion of protobuf / protolite dependencies is necessary as the
datastore-proto brings in protobuf dependencies. These are the source of truth
for Now in Android.
That's why the duplicate classes from below dependencies are excluded.
*/
exclude(group = "com.google.protobuf", module = "protobuf-javalite")
exclude(group = "com.google.firebase", module = "protolite-well-known-types")
}
"implementation"(libs.findLibrary("firebase.crashlytics").get())
}

@ -53,8 +53,8 @@ class AndroidLibraryConventionPlugin : Plugin<Project> {
disableUnnecessaryAndroidTests(target)
}
dependencies {
add("androidTestImplementation", kotlin("test"))
add("testImplementation", kotlin("test"))
add("androidTestImplementation", libs.findLibrary("kotlin.test").get())
add("testImplementation", libs.findLibrary("kotlin.test").get())
add("implementation", libs.findLibrary("androidx.tracing.ktx").get())
}

@ -15,6 +15,7 @@
*/
import com.google.samples.apps.nowinandroid.configureKotlinJvm
import com.google.samples.apps.nowinandroid.libs
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.dependencies
@ -29,7 +30,7 @@ class JvmLibraryConventionPlugin : Plugin<Project> {
}
configureKotlinJvm()
dependencies {
add("testImplementation", kotlin("test"))
add("testImplementation", libs.findLibrary("kotlin.test").get())
}
}
}

@ -30,6 +30,6 @@ import org.gradle.api.Project
internal fun LibraryAndroidComponentsExtension.disableUnnecessaryAndroidTests(
project: Project,
) = beforeVariants {
it.enableAndroidTest = it.enableAndroidTest
it.androidTest.enable = it.androidTest.enable
&& project.projectDir.resolve("src/androidTest").exists()
}

@ -16,7 +16,13 @@
dependencyResolutionManagement {
repositories {
google()
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
}
versionCatalogs {

@ -16,7 +16,13 @@
buildscript {
repositories {
google()
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
// Android Build Server

@ -18,7 +18,6 @@ package com.google.samples.apps.nowinandroid.feature.bookmarks
import androidx.activity.ComponentActivity
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertHasClickAction
import androidx.compose.ui.test.filter
@ -33,6 +32,7 @@ import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.performScrollToNode
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.testing.TestLifecycleOwner
import com.google.samples.apps.nowinandroid.core.testing.data.userNewsResourcesTestData
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState

@ -522,6 +522,7 @@ private fun SearchTextField(
.focusRequester(focusRequester)
.onKeyEvent {
if (it.key == Key.Enter) {
if (searchQuery.isBlank()) return@onKeyEvent false
onSearchExplicitlyTriggered()
true
} else {
@ -536,6 +537,7 @@ private fun SearchTextField(
),
keyboardActions = KeyboardActions(
onSearch = {
if (searchQuery.isBlank()) return@KeyboardActions
onSearchExplicitlyTriggered()
},
),

@ -59,7 +59,7 @@ class SearchViewModel @Inject constructor(
flowOf(SearchResultUiState.SearchNotReady)
} else {
searchQuery.flatMapLatest { query ->
if (query.length < SEARCH_QUERY_MIN_LENGTH) {
if (query.trim().length < SEARCH_QUERY_MIN_LENGTH) {
flowOf(SearchResultUiState.EmptyQuery)
} else {
getSearchContentsUseCase(query)
@ -102,6 +102,7 @@ class SearchViewModel @Inject constructor(
* search query in the search text field, defining this method.
*/
fun onSearchTriggered(query: String) {
if (query.isBlank()) return
viewModelScope.launch {
recentSearchRepository.insertOrReplaceRecentSearch(searchQuery = query)
}

@ -41,6 +41,7 @@ import org.junit.Rule
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
import kotlin.test.assertNull
/**
* To learn more about how this test handles Flows created with stateIn, see
@ -122,6 +123,43 @@ class SearchViewModelTest {
assertEquals(SearchNotReady, viewModel.searchResultUiState.value)
}
@Test
fun emptySearchText_isNotAddedToRecentSearches() = runTest {
viewModel.onSearchTriggered("")
val recentSearchQueriesStream = getRecentQueryUseCase()
val recentSearchQueries = recentSearchQueriesStream.first()
val recentSearchQuery = recentSearchQueries.firstOrNull()
assertNull(recentSearchQuery)
}
@Test
fun searchTextWithThreeSpaces_isEmptyQuery() = runTest {
searchContentsRepository.addNewsResources(newsResourcesTestData)
searchContentsRepository.addTopics(topicsTestData)
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }
viewModel.onSearchQueryChanged(" ")
assertIs<EmptyQuery>(viewModel.searchResultUiState.value)
collectJob.cancel()
}
@Test
fun searchTextWithThreeSpacesAndOneLetter_isEmptyQuery() = runTest {
searchContentsRepository.addNewsResources(newsResourcesTestData)
searchContentsRepository.addTopics(topicsTestData)
val collectJob = launch(UnconfinedTestDispatcher()) { viewModel.searchResultUiState.collect() }
viewModel.onSearchQueryChanged(" a")
assertIs<EmptyQuery>(viewModel.searchResultUiState.value)
collectJob.cancel()
}
@Test
fun whenToggleNewsResourceSavedIsCalled_bookmarkStateIsUpdated() = runTest {
val newsResourceId = "123"

@ -27,7 +27,8 @@ then
echo "The 'dot' command is not found. This is required to generate SVGs from the Graphviz files."
echo "Installation instructions:"
echo " - On macOS: You can install Graphviz using Homebrew with the command: 'brew install graphviz'"
echo " - On Ubuntu: You can install Graphviz using APT with the command: 'sudo apt-get install graphviz'"
echo " - On Ubuntu: You can install Graphviz using APT with the command: 'sudo apt install graphviz'"
echo " - Others: Visit https://graphviz.org/download/"
exit 1
fi

@ -14,10 +14,10 @@
* limitations under the License.
*/
val ktlintVersion = "1.0.1"
val ktlintVersion = "1.4.0"
initscript {
val spotlessVersion = "6.23.3"
val spotlessVersion = "6.25.0"
repositories {
mavenCentral()

@ -1,9 +1,9 @@
[versions]
accompanist = "0.34.0"
androidDesugarJdkLibs = "2.0.4"
accompanist = "0.36.0"
androidDesugarJdkLibs = "2.1.3"
# AGP and tools should be updated together
androidGradlePlugin = "8.6.1"
androidTools = "31.7.2"
androidTools = "31.7.3"
androidxActivity = "1.9.3"
androidxAppCompat = "1.7.0"
androidxBrowser = "1.8.0"
@ -14,11 +14,11 @@ androidxCoreSplashscreen = "1.0.1"
androidxDataStore = "1.1.1"
androidxEspresso = "3.6.1"
androidxHiltNavigationCompose = "1.2.0"
androidxLifecycle = "2.8.6"
androidxMacroBenchmark = "1.3.0"
androidxLifecycle = "2.8.7"
androidxMacroBenchmark = "1.3.3"
androidxMetrics = "1.0.0-beta01"
androidxNavigation = "2.8.4"
androidxProfileinstaller = "1.3.1"
androidxProfileinstaller = "1.4.1"
androidxTestCore = "1.6.1"
androidxTestExt = "1.2.1"
androidxTestRules = "1.6.1"
@ -26,13 +26,13 @@ androidxTestRunner = "1.6.2"
androidxTracing = "1.3.0-alpha02"
androidxUiAutomator = "2.3.0"
androidxWindowManager = "1.3.0"
androidxWork = "2.9.0"
androidxWork = "2.9.1"
coil = "2.7.0"
dependencyGuard = "0.5.0"
firebaseBom = "33.3.0"
firebaseCrashlyticsPlugin = "2.9.9"
firebaseBom = "33.7.0"
firebaseCrashlyticsPlugin = "3.0.2"
firebasePerfPlugin = "1.4.2"
gmsPlugin = "4.4.1"
gmsPlugin = "4.4.2"
googleOss = "17.1.0"
googleOssPlugin = "0.10.6"
hilt = "2.52"
@ -46,15 +46,15 @@ kotlinxSerializationJson = "1.6.3"
ksp = "2.0.20-1.0.25"
moduleGraph = "2.7.1"
okhttp = "4.12.0"
protobuf = "4.26.1"
protobuf = "4.28.2"
protobufPlugin = "0.9.4"
retrofit = "2.11.0"
retrofitKotlinxSerializationJson = "1.0.0"
robolectric = "4.14"
roborazzi = "1.32.2"
robolectric = "4.14.1"
roborazzi = "1.36.0"
room = "2.6.1"
secrets = "2.0.1"
truth = "1.4.2"
truth = "1.4.4"
turbine = "1.1.0"
[bundles]

@ -38,7 +38,7 @@ kotlin {
dependencies {
compileOnly(libs.kotlin.stdlib)
compileOnly(libs.lint.api)
testImplementation(libs.kotlin.test)
testImplementation(libs.lint.checks)
testImplementation(libs.lint.tests)
testImplementation(kotlin("test"))
}

@ -17,7 +17,13 @@
pluginManagement {
includeBuild("build-logic")
repositories {
google()
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
@ -26,7 +32,13 @@ pluginManagement {
dependencyResolutionManagement {
repositoriesMode = RepositoriesMode.FAIL_ON_PROJECT_REPOS
repositories {
google()
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
}
}

Loading…
Cancel
Save