From a888c87c5f153309ec28a977f0a7d92655cb6277 Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Sat, 8 Jun 2024 21:44:27 +0900 Subject: [PATCH 01/51] Below than api24,use decodeFromString Change-Id: Icf428ebfe7e153e132e112c2dc6926bd40ab3951 --- .../core/network/demo/DemoNiaNetworkDataSource.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt index b7c912c00..0f91e0337 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt @@ -17,6 +17,7 @@ package com.google.samples.apps.nowinandroid.core.network.demo import JvmUnitTestDemoAssetManager +import android.os.Build import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.network.NiaNetworkDataSource @@ -28,6 +29,7 @@ import kotlinx.coroutines.withContext import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream +import okio.use import javax.inject.Inject /** @@ -42,13 +44,21 @@ class DemoNiaNetworkDataSource @Inject constructor( @OptIn(ExperimentalSerializationApi::class) override suspend fun getTopics(ids: List?): List = withContext(ioDispatcher) { - assets.open(TOPICS_ASSET).use(networkJson::decodeFromStream) + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + assets.open(TOPICS_ASSET).use(networkJson::decodeFromStream) + } else { + networkJson.decodeFromString(assets.open(TOPICS_ASSET).toString()) + } } @OptIn(ExperimentalSerializationApi::class) override suspend fun getNewsResources(ids: List?): List = withContext(ioDispatcher) { - assets.open(NEWS_ASSET).use(networkJson::decodeFromStream) + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + assets.open(NEWS_ASSET).use(networkJson::decodeFromStream) + } else { + networkJson.decodeFromString(assets.open(TOPICS_ASSET).toString()) + } } override suspend fun getTopicChangeList(after: Int?): List = From a928bf1c51a8cbd218592236607b80b1a1d6827a Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Sat, 8 Jun 2024 23:42:32 +0900 Subject: [PATCH 02/51] Create convertStreamToString. Change-Id: I07dbb58813bc891f407773fddab7f1487f1ed24f --- .../network/demo/DemoNiaNetworkDataSource.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt index 0f91e0337..203a1e0c5 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt @@ -30,7 +30,11 @@ import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream import okio.use +import java.io.ByteArrayOutputStream +import java.io.InputStream +import java.nio.charset.StandardCharsets import javax.inject.Inject +import kotlin.coroutines.coroutineContext /** * [NiaNetworkDataSource] implementation that provides static news resources to aid development @@ -67,6 +71,21 @@ class DemoNiaNetworkDataSource @Inject constructor( override suspend fun getNewsResourceChangeList(after: Int?): List = getNewsResources().mapToChangeList(NetworkNewsResource::id) + private suspend fun convertStreamToString(inputStream: InputStream): String = withContext( + coroutineContext, + ) { + val result = ByteArrayOutputStream() + val buffer = ByteArray(1024) + var length = 0 + while (true) { + length = inputStream.read(buffer) + if (length == -1) break + result.write(buffer, 0, length) + } + + result.toString(StandardCharsets.UTF_8.name()) + } + companion object { private const val NEWS_ASSET = "news.json" private const val TOPICS_ASSET = "topics.json" From 29e514f359b61218fa0f2506b260fd0eabbe21eb Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Sat, 8 Jun 2024 23:44:53 +0900 Subject: [PATCH 03/51] Take capability below API 24, and add comment. Change-Id: I86d99fa9e74a8475c0b2bad202cfb4697ab1016b --- .../core/network/demo/DemoNiaNetworkDataSource.kt | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt index 203a1e0c5..eaeafa12d 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt @@ -48,20 +48,26 @@ class DemoNiaNetworkDataSource @Inject constructor( @OptIn(ExperimentalSerializationApi::class) override suspend fun getTopics(ids: List?): List = withContext(ioDispatcher) { - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { assets.open(TOPICS_ASSET).use(networkJson::decodeFromStream) } else { - networkJson.decodeFromString(assets.open(TOPICS_ASSET).toString()) + // Use decodeFromString to capability with API 24 below. + // https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342 + val topicsJsonString = convertStreamToString(assets.open(TOPICS_ASSET)) + networkJson.decodeFromString(topicsJsonString) } } @OptIn(ExperimentalSerializationApi::class) override suspend fun getNewsResources(ids: List?): List = withContext(ioDispatcher) { - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { assets.open(NEWS_ASSET).use(networkJson::decodeFromStream) } else { - networkJson.decodeFromString(assets.open(TOPICS_ASSET).toString()) + // Use decodeFromString to capability with API 24 below. + // https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342 + val newsJsonString = convertStreamToString(assets.open(NEWS_ASSET)) + networkJson.decodeFromString(newsJsonString) } } From 6a205b14a7e5d89c5be294cb808c6d6129f1f34d Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Sat, 8 Jun 2024 23:45:43 +0900 Subject: [PATCH 04/51] Add KDoC for convertStreamToString. Change-Id: Idb7fc085e889f8012234d14ad7bc0a4713073d6e --- .../nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt index eaeafa12d..671197bcc 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt @@ -77,6 +77,9 @@ class DemoNiaNetworkDataSource @Inject constructor( override suspend fun getNewsResourceChangeList(after: Int?): List = getNewsResources().mapToChangeList(NetworkNewsResource::id) + /** + * Convert [InputStream] to [String]. + */ private suspend fun convertStreamToString(inputStream: InputStream): String = withContext( coroutineContext, ) { From f394e3eb3857b26b66daa3e8ac80e6684b065cc8 Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Sat, 8 Jun 2024 23:46:51 +0900 Subject: [PATCH 05/51] Add API 21 to CI. Change-Id: I7e1406da9bf7d8aca44f48d9d7dfeb123d67a562 --- .github/workflows/Build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index 6bee0ddfb..7bbb75e07 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -153,7 +153,7 @@ jobs: timeout-minutes: 55 strategy: matrix: - api-level: [26, 30] + api-level: [21, 26, 30] steps: - name: Delete unnecessary tools 🔧 From 622ae698dbe601a8c19f816b385c30ba6c281ecc Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Sun, 9 Jun 2024 11:06:16 +0900 Subject: [PATCH 06/51] Remove `okio.use` and redundant length init. Change-Id: Ibac659c7aff6d8be99f52d012d603f8251bbd23d --- .../nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt index 671197bcc..ac6c21739 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt @@ -29,7 +29,6 @@ import kotlinx.coroutines.withContext import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream -import okio.use import java.io.ByteArrayOutputStream import java.io.InputStream import java.nio.charset.StandardCharsets @@ -85,7 +84,7 @@ class DemoNiaNetworkDataSource @Inject constructor( ) { val result = ByteArrayOutputStream() val buffer = ByteArray(1024) - var length = 0 + var length: Int while (true) { length = inputStream.read(buffer) if (length == -1) break From 093ff2c7f2fa22fc000a3f6a250d42a8eadf8fc1 Mon Sep 17 00:00:00 2001 From: Rob Orgiu Date: Mon, 18 Nov 2024 15:26:57 +0100 Subject: [PATCH 07/51] Simplify Drag&Drop implementation --- .../nowinandroid/core/ui/NewsResourceCard.kt | 21 +++++++------------ gradle/libs.versions.toml | 4 ++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index 2395eb156..ff10b8d38 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -24,7 +24,6 @@ import androidx.compose.foundation.Canvas import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.draganddrop.dragAndDropSource -import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -140,18 +139,14 @@ fun NewsResourceCardExpanded( modifier = Modifier .fillMaxWidth((.8f)) .dragAndDropSource { - detectTapGestures( - onLongPress = { - startTransfer( - DragAndDropTransferData( - ClipData.newPlainText( - sharingLabel, - sharingContent, - ), - flags = dragAndDropFlags, - ), - ) - }, + startTransfer( + DragAndDropTransferData( + ClipData.newPlainText( + sharingLabel, + sharingContent, + ), + flags = dragAndDropFlags, + ), ) }, ) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b1d9232ee..61ac0ee05 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,12 +2,12 @@ accompanist = "0.34.0" androidDesugarJdkLibs = "2.0.4" # AGP and tools should be updated together -androidGradlePlugin = "8.6.1" +androidGradlePlugin = "8.7.2" androidTools = "31.7.2" androidxActivity = "1.9.3" androidxAppCompat = "1.7.0" androidxBrowser = "1.8.0" -androidxComposeBom = "2024.09.00" +androidxComposeBom = "2024.11.00" androidxComposeRuntimeTracing = "1.0.0-beta01" androidxCore = "1.13.1" androidxCoreSplashscreen = "1.0.1" From cdb1d253067b7977ac19883119edf2d95d7766e4 Mon Sep 17 00:00:00 2001 From: blue928sky Date: Mon, 23 Sep 2024 10:08:31 +0900 Subject: [PATCH 08/51] Move Android instrumented test NiaAppStateTest to unit test Change-Id: I0a84dc37184a9ea7d4c18fa598bc447b0c48eb62 --- app/build.gradle.kts | 3 ++- .../samples/apps/nowinandroid/ui/NiaAppStateTest.kt | 11 ++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) rename app/src/{androidTest => testDemo}/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt (94%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5434df8c2..5b131b5d6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -119,15 +119,16 @@ dependencies { testImplementation(projects.sync.syncTest) testImplementation(libs.kotlin.test) + testDemoImplementation(libs.androidx.navigation.testing) testDemoImplementation(libs.robolectric) testDemoImplementation(libs.roborazzi) testDemoImplementation(projects.core.screenshotTesting) + testDemoImplementation(projects.core.testing) androidTestImplementation(projects.core.testing) androidTestImplementation(projects.core.dataTest) androidTestImplementation(projects.core.datastoreTest) androidTestImplementation(libs.androidx.test.espresso.core) - androidTestImplementation(libs.androidx.navigation.testing) androidTestImplementation(libs.androidx.compose.ui.test) androidTestImplementation(libs.hilt.android.testing) androidTestImplementation(libs.kotlin.test) diff --git a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt similarity index 94% rename from app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt rename to app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt index c2c74458d..c6ddb54fb 100644 --- a/app/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt +++ b/app/src/testDemo/kotlin/com/google/samples/apps/nowinandroid/ui/NiaAppStateTest.kt @@ -31,6 +31,8 @@ import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepo import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository import com.google.samples.apps.nowinandroid.core.testing.util.TestNetworkMonitor import com.google.samples.apps.nowinandroid.core.testing.util.TestTimeZoneMonitor +import dagger.hilt.android.testing.HiltAndroidTest +import dagger.hilt.android.testing.HiltTestApplication import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.test.UnconfinedTestDispatcher @@ -38,15 +40,18 @@ import kotlinx.coroutines.test.runTest import kotlinx.datetime.TimeZone import org.junit.Rule import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config import kotlin.test.assertEquals import kotlin.test.assertTrue /** * Tests [NiaAppState]. - * - * Note: This could become an unit test if Robolectric is added to the project and the Context - * is faked. */ +@RunWith(RobolectricTestRunner::class) +@Config(application = HiltTestApplication::class) +@HiltAndroidTest class NiaAppStateTest { @get:Rule From 95ab14601fbd59ca18d8dc9b2d503b6a15dabeca Mon Sep 17 00:00:00 2001 From: Andrea Severi Date: Wed, 11 Dec 2024 09:13:46 +0100 Subject: [PATCH 09/51] opt out of forced dark mode --- app/src/main/res/values-v29/themes.xml | 21 +++++++++++++++++++++ app/src/main/res/values/themes.xml | 4 +++- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/values-v29/themes.xml diff --git a/app/src/main/res/values-v29/themes.xml b/app/src/main/res/values-v29/themes.xml new file mode 100644 index 000000000..beba8427b --- /dev/null +++ b/app/src/main/res/values-v29/themes.xml @@ -0,0 +1,21 @@ + + + + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 7cdd25527..743ea737c 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -21,7 +21,9 @@ - From ad9945537891fb8b44c2b40e7142c6a7f6a18e11 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 00:45:43 +0000 Subject: [PATCH 14/51] Update all dependencies 1.9.0 to v1.10.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5ac8236e9..ea68a516c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -41,7 +41,7 @@ hiltExt = "1.2.0" jacoco = "0.8.12" junit4 = "4.13.2" kotlin = "2.1.0" -kotlinxCoroutines = "1.9.0" +kotlinxCoroutines = "1.10.0" kotlinxDatetime = "0.6.1" kotlinxSerializationJson = "1.7.3" ksp = "2.1.0-1.0.29" From 89e68b2fd2c3803c44a49494975499086bb3703c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Fri, 20 Dec 2024 00:48:31 +0000 Subject: [PATCH 15/51] =?UTF-8?q?=F0=9F=A4=96=20Updates=20baselines=20for?= =?UTF-8?q?=20Dependency=20Guard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/dependencies/prodReleaseRuntimeClasspath.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/dependencies/prodReleaseRuntimeClasspath.txt b/app/dependencies/prodReleaseRuntimeClasspath.txt index 2db7fa46c..d7c2fa1df 100644 --- a/app/dependencies/prodReleaseRuntimeClasspath.txt +++ b/app/dependencies/prodReleaseRuntimeClasspath.txt @@ -216,12 +216,12 @@ org.jetbrains.kotlin:kotlin-stdlib-common:2.1.0 org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0 org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0 org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0 -org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.9.0 -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.9.0 -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0 -org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.9.0 -org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.9.0 +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.0 +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.0 +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.0 +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.0 +org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.10.0 +org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.0 org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.1 org.jetbrains.kotlinx:kotlinx-datetime:0.6.1 org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3 From c10d867e1cf921adf4597e3d8ad0f5075b76a54c Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Fri, 20 Dec 2024 09:55:42 +0100 Subject: [PATCH 16/51] Add bot emails in `renovate.json` Followup on https://github.com/android/nowinandroid/pull/1766 --- .github/renovate.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/renovate.json b/.github/renovate.json index a9eab3c4d..bdd63664f 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -7,6 +7,8 @@ "main" ], "gitIgnoredAuthors": [ - "41898282+github-actions[bot]@users.noreply.github.com" + "41898282+github-actions[bot]@users.noreply.github.com", + "github-actions[bot]@users.noreply.github.com", + "renovate[bot]@users.noreply.github.com" ] } From 7cfe3bd7a2d4a44a593fb89473ef82684d246f5f Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Fri, 20 Dec 2024 10:00:42 +0100 Subject: [PATCH 17/51] Re-order entries to limit changes in diff --- .github/renovate.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/renovate.json b/.github/renovate.json index bdd63664f..0eec647d9 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -7,8 +7,8 @@ "main" ], "gitIgnoredAuthors": [ - "41898282+github-actions[bot]@users.noreply.github.com", + "renovate[bot]@users.noreply.github.com", "github-actions[bot]@users.noreply.github.com", - "renovate[bot]@users.noreply.github.com" + "41898282+github-actions[bot]@users.noreply.github.com" ] } From 1f285ce07040983b9a42fc78752ae2d67332fa04 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Fri, 20 Dec 2024 10:32:33 +0100 Subject: [PATCH 18/51] Fix CI workflow OOM Don't change the start directory with `-p :build-logic` which makes Gradle look for `build-logic/gradle.properties` file that does not exist. Therefore, the heap size was configured with default values (`-Xmx512m`) which is definitely not enough for our linting. Fixes #1769 --- .github/workflows/Build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index e090e2155..cb7148ce7 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -52,7 +52,7 @@ jobs: run: yes | sdkmanager --licenses || true - name: Check build-logic - run: ./gradlew check -p build-logic + run: ./gradlew :build-logic:convention:check - name: Check spotless run: ./gradlew spotlessCheck --init-script gradle/init.gradle.kts --no-configuration-cache From 4e2060278c78c799b444fe20bd8b2d08f54dc748 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Fri, 20 Dec 2024 10:34:56 +0100 Subject: [PATCH 19/51] Update NightlyBaselineProfiles.yaml --- .github/workflows/NightlyBaselineProfiles.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/NightlyBaselineProfiles.yaml b/.github/workflows/NightlyBaselineProfiles.yaml index de626b0a5..cc48ff9c9 100644 --- a/.github/workflows/NightlyBaselineProfiles.yaml +++ b/.github/workflows/NightlyBaselineProfiles.yaml @@ -44,7 +44,7 @@ jobs: run: yes | sdkmanager --licenses || true - name: Check build-logic - run: ./gradlew check -p build-logic + run: ./gradlew :build-logic:convention:check - name: Setup GMD run: ./gradlew :benchmarks:pixel6Api33Setup @@ -57,4 +57,4 @@ jobs: run: ./gradlew :app:generateReleaseBaselineProfile -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=baselineprofile -Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect" - --stacktrace \ No newline at end of file + --stacktrace From e5f1b842ee8e3418ea50d92a09f07fef30978d9b Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Fri, 20 Dec 2024 10:48:35 +0100 Subject: [PATCH 20/51] Gradle Configuration Cache on CI - https://github.com/gradle/actions/blob/main/docs/setup-gradle.md#saving-configuration-cache-data - https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:secrets And enable parallel Configuration Cache: - https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:usage:parallel This needs a `GRADLE_ENCRYPTION_KEY` secret to be configured in the repository [settings/secrets/actions](https://github.com/android/nowinandroid/settings/secrets/actions), otherwise no configuration cache will be saved or restored. As explained in the docs, you can use this tool to generate a configuration-cache compatible key: `openssl rand -base64 16`. --- .github/ci-gradle.properties | 2 ++ .github/workflows/Build.yaml | 4 ++++ .github/workflows/NightlyBaselineProfiles.yaml | 2 ++ .github/workflows/Release.yml | 2 ++ build-logic/gradle.properties | 2 ++ gradle.properties | 1 + 6 files changed, 13 insertions(+) diff --git a/.github/ci-gradle.properties b/.github/ci-gradle.properties index dbafa68cd..a9abe496a 100644 --- a/.github/ci-gradle.properties +++ b/.github/ci-gradle.properties @@ -17,6 +17,8 @@ org.gradle.daemon=false org.gradle.parallel=true org.gradle.workers.max=2 +org.gradle.configuration-cache=true +org.gradle.configuration-cache.parallel=true kotlin.incremental=false diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index e090e2155..8454da821 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -44,6 +44,8 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 + with: + cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - name: Setup Android SDK uses: android-actions/setup-android@v3 @@ -199,6 +201,8 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 + with: + cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - name: Build projects and run instrumentation tests uses: reactivecircus/android-emulator-runner@v2 diff --git a/.github/workflows/NightlyBaselineProfiles.yaml b/.github/workflows/NightlyBaselineProfiles.yaml index de626b0a5..a6914b6b5 100644 --- a/.github/workflows/NightlyBaselineProfiles.yaml +++ b/.github/workflows/NightlyBaselineProfiles.yaml @@ -36,6 +36,8 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 + with: + cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - name: Setup Android SDK uses: android-actions/setup-android@v3 diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 71ee060e1..149a7bb6f 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -33,6 +33,8 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 + with: + cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} - name: Setup Android SDK uses: android-actions/setup-android@v3 diff --git a/build-logic/gradle.properties b/build-logic/gradle.properties index 1c9073eb9..5e07c65d0 100644 --- a/build-logic/gradle.properties +++ b/build-logic/gradle.properties @@ -2,3 +2,5 @@ org.gradle.parallel=true org.gradle.caching=true org.gradle.configureondemand=true +org.gradle.configuration-cache=true +org.gradle.configuration-cache.parallel=true diff --git a/gradle.properties b/gradle.properties index 30c4eae04..2e9d9fc30 100644 --- a/gradle.properties +++ b/gradle.properties @@ -39,6 +39,7 @@ org.gradle.caching=true # Enable configuration caching between builds. org.gradle.configuration-cache=true +org.gradle.configuration-cache.parallel=true # This option is set because of https://github.com/google/play-services-plugins/issues/246 # to generate the Configuration Cache regardless of incompatible tasks. # See https://github.com/android/nowinandroid/issues/1022 before using it. From 008b9893978026800704a25b0e28263690bd6f31 Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Fri, 20 Dec 2024 21:18:31 +0900 Subject: [PATCH 21/51] Create readText method. Change-Id: I15df6f18343bcf36d2d583a19cd47d6344942201 --- .../apps/nowinandroid/core/network/demo/DemoAssetManager.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoAssetManager.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoAssetManager.kt index e5fb07bb3..d3264a251 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoAssetManager.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoAssetManager.kt @@ -18,6 +18,7 @@ package com.google.samples.apps.nowinandroid.core.network.demo import java.io.InputStream -fun interface DemoAssetManager { +interface DemoAssetManager { fun open(fileName: String): InputStream + fun readText(fileName: String): String } From 9320d592b40b793159c8b62e69dca5e25a351298 Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Fri, 20 Dec 2024 21:18:42 +0900 Subject: [PATCH 22/51] Override readText. Change-Id: Ibf7fca9de5461e7285ed6d68092e36d70408f3bd --- core/network/src/main/kotlin/JvmUnitTestDemoAssetManager.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/network/src/main/kotlin/JvmUnitTestDemoAssetManager.kt b/core/network/src/main/kotlin/JvmUnitTestDemoAssetManager.kt index 2ef418517..7017cb0e2 100644 --- a/core/network/src/main/kotlin/JvmUnitTestDemoAssetManager.kt +++ b/core/network/src/main/kotlin/JvmUnitTestDemoAssetManager.kt @@ -17,6 +17,7 @@ import com.google.samples.apps.nowinandroid.core.network.demo.DemoAssetManager import java.io.File import java.io.InputStream +import java.nio.charset.StandardCharsets import java.util.Properties /** @@ -38,4 +39,5 @@ internal object JvmUnitTestDemoAssetManager : DemoAssetManager { private val assets = File(properties["android_merged_assets"].toString()) override fun open(fileName: String): InputStream = File(assets, fileName).inputStream() + override fun readText(fileName: String): String = File(assets, fileName).readText(StandardCharsets.UTF_8) } From 301f7f5ad62753fa8b02e7bb1d630118ef4d8f15 Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Fri, 20 Dec 2024 21:19:20 +0900 Subject: [PATCH 23/51] Pass new DemoAssetManager with open and readText methods. Change-Id: I4b58c250e76f6d41e794087ff3b467fc61c88eca --- .../apps/nowinandroid/core/network/di/NetworkModule.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt index a97540f2b..08e186d01 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt @@ -32,6 +32,7 @@ import kotlinx.serialization.json.Json import okhttp3.Call import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor +import java.io.InputStream import javax.inject.Singleton @Module @@ -48,7 +49,10 @@ internal object NetworkModule { @Singleton fun providesDemoAssetManager( @ApplicationContext context: Context, - ): DemoAssetManager = DemoAssetManager(context.assets::open) + ): DemoAssetManager = object : DemoAssetManager { + override fun open(fileName: String): InputStream = context.assets.open(fileName) + override fun readText(fileName: String): String = context.assets.open(fileName).bufferedReader().use { it.readText() } + } @Provides @Singleton From 80172dcf826fdfe03c8e850cf06e8d045719eb02 Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Fri, 20 Dec 2024 21:20:02 +0900 Subject: [PATCH 24/51] Replace manual string converter to readText method. Change-Id: If8cc6c27bd399fcdf8446ec411626f13d39e707c --- .../network/demo/DemoNiaNetworkDataSource.kt | 26 ++----------------- 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt index ac6c21739..abb2a4b72 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt @@ -29,11 +29,7 @@ import kotlinx.coroutines.withContext import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream -import java.io.ByteArrayOutputStream -import java.io.InputStream -import java.nio.charset.StandardCharsets import javax.inject.Inject -import kotlin.coroutines.coroutineContext /** * [NiaNetworkDataSource] implementation that provides static news resources to aid development @@ -52,7 +48,7 @@ class DemoNiaNetworkDataSource @Inject constructor( } else { // Use decodeFromString to capability with API 24 below. // https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342 - val topicsJsonString = convertStreamToString(assets.open(TOPICS_ASSET)) + val topicsJsonString = assets.readText(TOPICS_ASSET) networkJson.decodeFromString(topicsJsonString) } } @@ -65,7 +61,7 @@ class DemoNiaNetworkDataSource @Inject constructor( } else { // Use decodeFromString to capability with API 24 below. // https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342 - val newsJsonString = convertStreamToString(assets.open(NEWS_ASSET)) + val newsJsonString = assets.readText(NEWS_ASSET) networkJson.decodeFromString(newsJsonString) } } @@ -76,24 +72,6 @@ class DemoNiaNetworkDataSource @Inject constructor( override suspend fun getNewsResourceChangeList(after: Int?): List = getNewsResources().mapToChangeList(NetworkNewsResource::id) - /** - * Convert [InputStream] to [String]. - */ - private suspend fun convertStreamToString(inputStream: InputStream): String = withContext( - coroutineContext, - ) { - val result = ByteArrayOutputStream() - val buffer = ByteArray(1024) - var length: Int - while (true) { - length = inputStream.read(buffer) - if (length == -1) break - result.write(buffer, 0, length) - } - - result.toString(StandardCharsets.UTF_8.name()) - } - companion object { private const val NEWS_ASSET = "news.json" private const val TOPICS_ASSET = "topics.json" From 5084e5c3d6b79a3f239c930666cfc7347de56a50 Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Sat, 21 Dec 2024 16:11:24 +0900 Subject: [PATCH 25/51] Revert exposed `readText` method. Change-Id: I8076fabed4b4f2f460c74b43ad1c3e38a5268005 --- core/network/src/main/kotlin/JvmUnitTestDemoAssetManager.kt | 2 -- .../apps/nowinandroid/core/network/demo/DemoAssetManager.kt | 3 +-- .../apps/nowinandroid/core/network/di/NetworkModule.kt | 6 +----- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/core/network/src/main/kotlin/JvmUnitTestDemoAssetManager.kt b/core/network/src/main/kotlin/JvmUnitTestDemoAssetManager.kt index 7017cb0e2..2ef418517 100644 --- a/core/network/src/main/kotlin/JvmUnitTestDemoAssetManager.kt +++ b/core/network/src/main/kotlin/JvmUnitTestDemoAssetManager.kt @@ -17,7 +17,6 @@ import com.google.samples.apps.nowinandroid.core.network.demo.DemoAssetManager import java.io.File import java.io.InputStream -import java.nio.charset.StandardCharsets import java.util.Properties /** @@ -39,5 +38,4 @@ internal object JvmUnitTestDemoAssetManager : DemoAssetManager { private val assets = File(properties["android_merged_assets"].toString()) override fun open(fileName: String): InputStream = File(assets, fileName).inputStream() - override fun readText(fileName: String): String = File(assets, fileName).readText(StandardCharsets.UTF_8) } diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoAssetManager.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoAssetManager.kt index d3264a251..e5fb07bb3 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoAssetManager.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoAssetManager.kt @@ -18,7 +18,6 @@ package com.google.samples.apps.nowinandroid.core.network.demo import java.io.InputStream -interface DemoAssetManager { +fun interface DemoAssetManager { fun open(fileName: String): InputStream - fun readText(fileName: String): String } diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt index 08e186d01..a97540f2b 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/NetworkModule.kt @@ -32,7 +32,6 @@ import kotlinx.serialization.json.Json import okhttp3.Call import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor -import java.io.InputStream import javax.inject.Singleton @Module @@ -49,10 +48,7 @@ internal object NetworkModule { @Singleton fun providesDemoAssetManager( @ApplicationContext context: Context, - ): DemoAssetManager = object : DemoAssetManager { - override fun open(fileName: String): InputStream = context.assets.open(fileName) - override fun readText(fileName: String): String = context.assets.open(fileName).bufferedReader().use { it.readText() } - } + ): DemoAssetManager = DemoAssetManager(context.assets::open) @Provides @Singleton From 696bd7de62965359336e860c4a00d5377f3890a6 Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Sat, 21 Dec 2024 16:12:12 +0900 Subject: [PATCH 26/51] Create `getDemoDataFromJson` method and use it. Change-Id: I19336b061e74a378cc70470fbd6af8ee4c7533e0 --- .../network/demo/DemoNiaNetworkDataSource.kt | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt index abb2a4b72..5d04ee4c8 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt @@ -17,7 +17,8 @@ package com.google.samples.apps.nowinandroid.core.network.demo import JvmUnitTestDemoAssetManager -import android.os.Build +import android.os.Build.VERSION.SDK_INT +import android.os.Build.VERSION_CODES.N import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.network.NiaNetworkDataSource @@ -29,6 +30,7 @@ import kotlinx.coroutines.withContext import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream +import java.io.BufferedReader import javax.inject.Inject /** @@ -40,31 +42,11 @@ class DemoNiaNetworkDataSource @Inject constructor( private val assets: DemoAssetManager = JvmUnitTestDemoAssetManager, ) : NiaNetworkDataSource { - @OptIn(ExperimentalSerializationApi::class) override suspend fun getTopics(ids: List?): List = - withContext(ioDispatcher) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - assets.open(TOPICS_ASSET).use(networkJson::decodeFromStream) - } else { - // Use decodeFromString to capability with API 24 below. - // https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342 - val topicsJsonString = assets.readText(TOPICS_ASSET) - networkJson.decodeFromString(topicsJsonString) - } - } + getDemoDataFromJson(TOPICS_ASSET) - @OptIn(ExperimentalSerializationApi::class) override suspend fun getNewsResources(ids: List?): List = - withContext(ioDispatcher) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - assets.open(NEWS_ASSET).use(networkJson::decodeFromStream) - } else { - // Use decodeFromString to capability with API 24 below. - // https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342 - val newsJsonString = assets.readText(NEWS_ASSET) - networkJson.decodeFromString(newsJsonString) - } - } + getDemoDataFromJson(NEWS_ASSET) override suspend fun getTopicChangeList(after: Int?): List = getTopics().mapToChangeList(NetworkTopic::id) @@ -72,6 +54,23 @@ class DemoNiaNetworkDataSource @Inject constructor( override suspend fun getNewsResourceChangeList(after: Int?): List = getNewsResources().mapToChangeList(NetworkNewsResource::id) + /** + * Get Demo data form a [fileName] Json file. + */ + @OptIn(ExperimentalSerializationApi::class) + private suspend inline fun getDemoDataFromJson(fileName: String): List = + withContext(ioDispatcher) { + assets.open(fileName).use { inputStream -> + if (SDK_INT >= N) { + networkJson.decodeFromStream(inputStream) + } // https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342 + else { + inputStream.bufferedReader().use(BufferedReader::readText) + .let(networkJson::decodeFromString) + } + } + } + companion object { private const val NEWS_ASSET = "news.json" private const val TOPICS_ASSET = "topics.json" From 05621615da8c72d7d201d43db2948f3a71f6c0a8 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Sun, 22 Dec 2024 09:46:28 +0100 Subject: [PATCH 27/51] Disable NightlyBaselineProfiles workflow on forks --- .github/workflows/NightlyBaselineProfiles.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/NightlyBaselineProfiles.yaml b/.github/workflows/NightlyBaselineProfiles.yaml index f76d820eb..c8e2651c5 100644 --- a/.github/workflows/NightlyBaselineProfiles.yaml +++ b/.github/workflows/NightlyBaselineProfiles.yaml @@ -7,6 +7,7 @@ on: jobs: baseline_profiles: name: "Generate Baseline Profiles" + if: github.repository == 'android/nowinandroid' runs-on: ubuntu-latest permissions: From d47315e61240e1158e0d339b4bc7d0e82910f2e9 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Sun, 22 Dec 2024 09:48:34 +0100 Subject: [PATCH 28/51] Disable Release workflow on forks --- .github/workflows/Release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 149a7bb6f..b952ccb50 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -7,6 +7,7 @@ on: jobs: build: + if: github.repository == 'android/nowinandroid' runs-on: ubuntu-latest timeout-minutes: 120 From 85cc2921ecc6c851778b7dc8c085170d999603c4 Mon Sep 17 00:00:00 2001 From: Jaehwa Noh Date: Wed, 25 Dec 2024 11:59:56 +0900 Subject: [PATCH 29/51] Follow kotlin dsl without type-safe documentation on plugins https://docs.gradle.org/current/userguide/kotlin_dsl.html#ex-configuring-plugins-without-type-safe-accessors Change-Id: I194844ace17cc2bfa2c80bcc4a338bccfd050a9e --- .../kotlin/AndroidApplicationConventionPlugin.kt | 12 +++++------- .../AndroidApplicationFirebaseConventionPlugin.kt | 9 ++++----- .../AndroidApplicationJacocoConventionPlugin.kt | 4 +++- .../main/kotlin/AndroidFeatureConventionPlugin.kt | 14 ++++++++------ .../main/kotlin/AndroidLibraryConventionPlugin.kt | 13 +++++++------ .../kotlin/AndroidLibraryJacocoConventionPlugin.kt | 5 +++-- .../src/main/kotlin/AndroidLintConventionPlugin.kt | 3 ++- .../src/main/kotlin/AndroidRoomConventionPlugin.kt | 5 +++-- .../src/main/kotlin/AndroidTestConventionPlugin.kt | 8 +++----- .../src/main/kotlin/HiltConventionPlugin.kt | 6 ++++-- .../src/main/kotlin/JvmLibraryConventionPlugin.kt | 8 ++++---- 11 files changed, 46 insertions(+), 41 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt index 72be1cb74..1ab3a2ca0 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationConventionPlugin.kt @@ -23,18 +23,17 @@ import com.google.samples.apps.nowinandroid.configureKotlinAndroid import com.google.samples.apps.nowinandroid.configurePrintApksTask import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.getByType class AndroidApplicationConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - with(pluginManager) { - apply("com.android.application") - apply("org.jetbrains.kotlin.android") - apply("nowinandroid.android.lint") - apply("com.dropbox.dependency-guard") - } + apply(plugin = "com.android.application") + apply(plugin = "org.jetbrains.kotlin.android") + apply(plugin = "nowinandroid.android.lint") + apply(plugin = "com.dropbox.dependency-guard") extensions.configure { configureKotlinAndroid(this) @@ -49,5 +48,4 @@ class AndroidApplicationConventionPlugin : Plugin { } } } - } diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt index 7aacc0ffe..be3ec0365 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationFirebaseConventionPlugin.kt @@ -19,6 +19,7 @@ import com.google.firebase.crashlytics.buildtools.gradle.CrashlyticsExtension import com.google.samples.apps.nowinandroid.libs import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.dependencies import org.gradle.kotlin.dsl.exclude @@ -26,11 +27,9 @@ import org.gradle.kotlin.dsl.exclude class AndroidApplicationFirebaseConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - with(pluginManager) { - apply("com.google.gms.google-services") - apply("com.google.firebase.firebase-perf") - apply("com.google.firebase.crashlytics") - } + apply(plugin = "com.google.gms.google-services") + apply(plugin = "com.google.firebase.firebase-perf") + apply(plugin = "com.google.firebase.crashlytics") dependencies { val bom = libs.findLibrary("firebase-bom").get() diff --git a/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt index 5bd58fabe..b0eece41d 100644 --- a/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidApplicationJacocoConventionPlugin.kt @@ -19,12 +19,14 @@ import com.android.build.api.variant.ApplicationAndroidComponentsExtension import com.google.samples.apps.nowinandroid.configureJacoco import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.getByType class AndroidApplicationJacocoConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - pluginManager.apply("jacoco") + apply(plugin = "jacoco") + val androidExtension = extensions.getByType() androidExtension.buildTypes.configureEach { diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt index aa30f5115..1af5523c5 100644 --- a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -19,17 +19,17 @@ import com.google.samples.apps.nowinandroid.configureGradleManagedDevices import com.google.samples.apps.nowinandroid.libs import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.dependencies class AndroidFeatureConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - pluginManager.apply { - apply("nowinandroid.android.library") - apply("nowinandroid.hilt") - apply("org.jetbrains.kotlin.plugin.serialization") - } + apply(plugin = "nowinandroid.android.library") + apply(plugin = "nowinandroid.hilt") + apply(plugin = "org.jetbrains.kotlin.plugin.serialization") + extensions.configure { testOptions.animationsDisabled = true configureGradleManagedDevices(this) @@ -47,7 +47,9 @@ class AndroidFeatureConventionPlugin : Plugin { "implementation"(libs.findLibrary("kotlinx.serialization.json").get()) "testImplementation"(libs.findLibrary("androidx.navigation.testing").get()) - "androidTestImplementation"(libs.findLibrary("androidx.lifecycle.runtimeTesting").get()) + "androidTestImplementation"( + libs.findLibrary("androidx.lifecycle.runtimeTesting").get(), + ) } } } diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt index feffa5037..3fe727410 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryConventionPlugin.kt @@ -24,17 +24,16 @@ import com.google.samples.apps.nowinandroid.disableUnnecessaryAndroidTests import com.google.samples.apps.nowinandroid.libs import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.dependencies class AndroidLibraryConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - with(pluginManager) { - apply("com.android.library") - apply("org.jetbrains.kotlin.android") - apply("nowinandroid.android.lint") - } + apply(plugin = "com.android.library") + apply(plugin = "org.jetbrains.kotlin.android") + apply(plugin = "nowinandroid.android.lint") extensions.configure { configureKotlinAndroid(this) @@ -45,7 +44,9 @@ class AndroidLibraryConventionPlugin : Plugin { configureGradleManagedDevices(this) // The resource prefix is derived from the module name, // so resources inside ":core:module1" must be prefixed with "core_module1_" - resourcePrefix = path.split("""\W""".toRegex()).drop(1).distinct().joinToString(separator = "_").lowercase() + "_" + resourcePrefix = + path.split("""\W""".toRegex()).drop(1).distinct().joinToString(separator = "_") + .lowercase() + "_" } extensions.configure { configurePrintApksTask(this) diff --git a/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt index 6f2ff60c5..d249e4cbf 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLibraryJacocoConventionPlugin.kt @@ -15,17 +15,18 @@ */ import com.android.build.api.dsl.LibraryExtension -import com.android.build.api.variant.ApplicationAndroidComponentsExtension import com.android.build.api.variant.LibraryAndroidComponentsExtension import com.google.samples.apps.nowinandroid.configureJacoco import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.getByType class AndroidLibraryJacocoConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - pluginManager.apply("jacoco") + apply(plugin = "jacoco") + val androidExtension = extensions.getByType() androidExtension.buildTypes.configureEach { diff --git a/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt index 1a01a7725..884d6f076 100644 --- a/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt @@ -19,6 +19,7 @@ import com.android.build.api.dsl.LibraryExtension import com.android.build.api.dsl.Lint import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure class AndroidLintConventionPlugin : Plugin { @@ -32,7 +33,7 @@ class AndroidLintConventionPlugin : Plugin { configure { lint(Lint::configure) } else -> { - pluginManager.apply("com.android.lint") + apply(plugin = "com.android.lint") configure(Lint::configure) } } diff --git a/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt index 5a8d648f3..6919b5e5d 100644 --- a/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidRoomConventionPlugin.kt @@ -19,6 +19,7 @@ import com.google.devtools.ksp.gradle.KspExtension import com.google.samples.apps.nowinandroid.libs import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.dependencies @@ -26,8 +27,8 @@ class AndroidRoomConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - pluginManager.apply("androidx.room") - pluginManager.apply("com.google.devtools.ksp") + apply(plugin = "androidx.room") + apply(plugin = "com.google.devtools.ksp") extensions.configure { arg("room.generateKotlin", "true") diff --git a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt index 8a084598f..67933f77d 100644 --- a/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidTestConventionPlugin.kt @@ -19,15 +19,14 @@ import com.google.samples.apps.nowinandroid.configureGradleManagedDevices import com.google.samples.apps.nowinandroid.configureKotlinAndroid import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.configure class AndroidTestConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - with(pluginManager) { - apply("com.android.test") - apply("org.jetbrains.kotlin.android") - } + apply(plugin = "com.android.test") + apply(plugin = "org.jetbrains.kotlin.android") extensions.configure { configureKotlinAndroid(this) @@ -36,5 +35,4 @@ class AndroidTestConventionPlugin : Plugin { } } } - } diff --git a/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt b/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt index 24d8c3382..5a90ff98f 100644 --- a/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/HiltConventionPlugin.kt @@ -18,12 +18,14 @@ import com.android.build.gradle.api.AndroidBasePlugin import com.google.samples.apps.nowinandroid.libs import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.kotlin.dsl.apply import org.gradle.kotlin.dsl.dependencies class HiltConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - pluginManager.apply("com.google.devtools.ksp") + apply(plugin = "com.google.devtools.ksp") + dependencies { "ksp"(libs.findLibrary("hilt.compiler").get()) } @@ -37,7 +39,7 @@ class HiltConventionPlugin : Plugin { /** Add support for Android modules, based on [AndroidBasePlugin] */ pluginManager.withPlugin("com.android.base") { - pluginManager.apply("dagger.hilt.android.plugin") + apply(plugin = "dagger.hilt.android.plugin") dependencies { "implementation"(libs.findLibrary("hilt.android").get()) } diff --git a/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt b/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt index f9ae4a1c4..a1477891d 100644 --- a/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/JvmLibraryConventionPlugin.kt @@ -18,15 +18,15 @@ 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.apply import org.gradle.kotlin.dsl.dependencies class JvmLibraryConventionPlugin : Plugin { override fun apply(target: Project) { with(target) { - with(pluginManager) { - apply("org.jetbrains.kotlin.jvm") - apply("nowinandroid.android.lint") - } + apply(plugin = "org.jetbrains.kotlin.jvm") + apply(plugin = "nowinandroid.android.lint") + configureKotlinJvm() dependencies { "testImplementation"(libs.findLibrary("kotlin.test").get()) From 2515867c9d491fc06a4844bbb41e0ba8bb55810c Mon Sep 17 00:00:00 2001 From: Tobi Oyelekan Date: Fri, 27 Dec 2024 02:33:17 +0100 Subject: [PATCH 30/51] add topicdao test --- .../core/database/dao/TopicDaoTest.kt | 145 ++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt new file mode 100644 index 000000000..80ed0b721 --- /dev/null +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt @@ -0,0 +1,145 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.database.dao + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import com.google.samples.apps.nowinandroid.core.database.NiaDatabase +import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Before +import org.junit.Test +import kotlin.test.assertEquals + +class TopicDaoTest { + private lateinit var topicDao: TopicDao + private lateinit var db: NiaDatabase + + @Before + fun createDb() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder( + context, + NiaDatabase::class.java, + ).build() + topicDao = db.topicDao() + } + + @After + fun closeDb() = db.close() + + @Test + fun topicDao_fetchTopics() = runTest { + insertTopics() + + val savedTopics = topicDao.getTopicEntities().first() + + assertEquals( + listOf("1", "2", "3"), savedTopics.map { it.id }, + ) + } + + @Test + fun topicDao_getSingleTopicEntity() = runTest { + insertTopics() + + val savedTopicEntity = topicDao.getTopicEntity("2").first() + + assertEquals("performance", savedTopicEntity.name) + } + + @Test + fun topicDao_getOneOffTopicEntity() = runTest { + insertTopics() + + val savedTopics = topicDao.getOneOffTopicEntities() + + assertEquals( + listOf("1", "2", "3"), savedTopics.map { it.id }, + ) + } + + @Test + fun topicDao_getTopicEntities_ByIds() = runTest { + insertTopics() + + val savedTopics = topicDao.getTopicEntities(setOf("1", "2")) + .first() + + assertEquals(listOf("compose", "performance"), savedTopics.map { it.name }) + } + + @Test + fun topicDao_IgnoreNewEntry_If_EntityExists() = runTest { + insertTopics() + topicDao.insertOrIgnoreTopics( + listOf(testTopicEntity("1", "compose")), + ) + + val savedTopics = topicDao.getOneOffTopicEntities() + + assertEquals(3, savedTopics.size) + } + + @Test + fun topicDao_Upsert_Entities() = runTest { + insertTopics() + topicDao.upsertTopics( + listOf(testTopicEntity("1", "newName")), + ) + + val savedTopics = topicDao.getOneOffTopicEntities() + + assertEquals(3, savedTopics.size) + assertEquals("newName", savedTopics.first().name) + } + + @Test + fun topicDao_Delete_Entities() = runTest { + insertTopics() + topicDao.deleteTopics(listOf("1", "2")) + + val savedTopics = topicDao.getOneOffTopicEntities() + + assertEquals(1, savedTopics.size) + assertEquals("3", savedTopics.first().id) + } + + private suspend fun insertTopics() { + val topicEntities = listOf( + testTopicEntity("1", "compose"), + testTopicEntity("2", "performance"), + testTopicEntity("3", "headline"), + ) + topicDao.insertOrIgnoreTopics(topicEntities) + } +} + +private fun testTopicEntity( + id: String = "0", + name: String, +) = TopicEntity( + id = id, + name = name, + shortDescription = "", + longDescription = "", + url = "", + imageUrl = "", +) From 6414c4dd68c8828943b088528b342cbaa6af014c Mon Sep 17 00:00:00 2001 From: Tobi Oyelekan Date: Fri, 27 Dec 2024 02:41:12 +0100 Subject: [PATCH 31/51] extract common db setup --- .../core/database/TestDatabaseSetup.kt | 45 +++++++++++++++++++ .../core/database/dao/NewsResourceDaoTest.kt | 28 +----------- .../core/database/dao/TopicDaoTest.kt | 25 +---------- 3 files changed, 49 insertions(+), 49 deletions(-) create mode 100644 core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/TestDatabaseSetup.kt diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/TestDatabaseSetup.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/TestDatabaseSetup.kt new file mode 100644 index 000000000..7c0d2f1e7 --- /dev/null +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/TestDatabaseSetup.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.samples.apps.nowinandroid.core.database + +import android.content.Context +import androidx.room.Room +import androidx.test.core.app.ApplicationProvider +import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceDao +import com.google.samples.apps.nowinandroid.core.database.dao.TopicDao +import org.junit.After +import org.junit.Before + +abstract class TestDatabaseSetup { + protected lateinit var newsResourceDao: NewsResourceDao + protected lateinit var topicDao: TopicDao + private lateinit var db: NiaDatabase + + @Before + fun createDb() { + val context = ApplicationProvider.getApplicationContext() + db = Room.inMemoryDatabaseBuilder( + context, + NiaDatabase::class.java, + ).build() + newsResourceDao = db.newsResourceDao() + topicDao = db.topicDao() + } + + @After + fun closeDb() = db.close() +} diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt index 535ab61a7..86af0fa21 100644 --- a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt @@ -16,10 +16,7 @@ package com.google.samples.apps.nowinandroid.core.database.dao -import android.content.Context -import androidx.room.Room -import androidx.test.core.app.ApplicationProvider -import com.google.samples.apps.nowinandroid.core.database.NiaDatabase +import com.google.samples.apps.nowinandroid.core.database.TestDatabaseSetup import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceEntity import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceTopicCrossRef import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity @@ -27,31 +24,10 @@ import com.google.samples.apps.nowinandroid.core.database.model.asExternalModel import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import kotlinx.datetime.Instant -import org.junit.After -import org.junit.Before import org.junit.Test import kotlin.test.assertEquals -class NewsResourceDaoTest { - - private lateinit var newsResourceDao: NewsResourceDao - private lateinit var topicDao: TopicDao - private lateinit var db: NiaDatabase - - @Before - fun createDb() { - val context = ApplicationProvider.getApplicationContext() - db = Room.inMemoryDatabaseBuilder( - context, - NiaDatabase::class.java, - ).build() - newsResourceDao = db.newsResourceDao() - topicDao = db.topicDao() - } - - @After - fun closeDb() = db.close() - +class NewsResourceDaoTest : TestDatabaseSetup() { @Test fun newsResourceDao_fetches_items_by_descending_publish_date() = runTest { val newsResourceEntities = listOf( diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt index 80ed0b721..d774253e1 100644 --- a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt @@ -16,35 +16,14 @@ package com.google.samples.apps.nowinandroid.core.database.dao -import android.content.Context -import androidx.room.Room -import androidx.test.core.app.ApplicationProvider -import com.google.samples.apps.nowinandroid.core.database.NiaDatabase +import com.google.samples.apps.nowinandroid.core.database.TestDatabaseSetup import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest -import org.junit.After -import org.junit.Before import org.junit.Test import kotlin.test.assertEquals -class TopicDaoTest { - private lateinit var topicDao: TopicDao - private lateinit var db: NiaDatabase - - @Before - fun createDb() { - val context = ApplicationProvider.getApplicationContext() - db = Room.inMemoryDatabaseBuilder( - context, - NiaDatabase::class.java, - ).build() - topicDao = db.topicDao() - } - - @After - fun closeDb() = db.close() - +class TopicDaoTest : TestDatabaseSetup() { @Test fun topicDao_fetchTopics() = runTest { insertTopics() From 5269e0773094a2f6b1681c99a933387073aae960 Mon Sep 17 00:00:00 2001 From: Tobi Oyelekan Date: Fri, 27 Dec 2024 02:44:10 +0100 Subject: [PATCH 32/51] format code --- .../apps/nowinandroid/core/database/dao/TopicDaoTest.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt index d774253e1..4d78ade5d 100644 --- a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt @@ -31,7 +31,8 @@ class TopicDaoTest : TestDatabaseSetup() { val savedTopics = topicDao.getTopicEntities().first() assertEquals( - listOf("1", "2", "3"), savedTopics.map { it.id }, + listOf("1", "2", "3"), + savedTopics.map { it.id }, ) } @@ -51,7 +52,8 @@ class TopicDaoTest : TestDatabaseSetup() { val savedTopics = topicDao.getOneOffTopicEntities() assertEquals( - listOf("1", "2", "3"), savedTopics.map { it.id }, + listOf("1", "2", "3"), + savedTopics.map { it.id }, ) } From cf441fbbc69c0aa80d159ae4a26687446abb68e1 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Mon, 6 Jan 2025 16:49:03 +0000 Subject: [PATCH 33/51] Update comment about internal build path --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9a8652956..b7989bab4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -25,7 +25,7 @@ buildscript { } mavenCentral() - // Android Build Server + // This is used only for internal Google builds. maven { url = uri("../nowinandroid-prebuilts/m2repository") } } dependencies { From eb1f5d2580819ca6c045846e7b3576d43f389c28 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:58:26 +0000 Subject: [PATCH 34/51] Update all dependencies --- gradle/libs.versions.toml | 10 +++++----- gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ea68a516c..ce4bd2c64 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] accompanist = "0.37.0" -androidDesugarJdkLibs = "2.1.3" +androidDesugarJdkLibs = "2.1.4" # AGP and tools should be updated together androidGradlePlugin = "8.7.3" androidTools = "31.7.3" @@ -36,14 +36,14 @@ firebasePerfPlugin = "1.4.2" gmsPlugin = "4.4.2" googleOss = "17.1.0" googleOssPlugin = "0.10.6" -hilt = "2.53.1" +hilt = "2.54" hiltExt = "1.2.0" jacoco = "0.8.12" junit4 = "4.13.2" kotlin = "2.1.0" -kotlinxCoroutines = "1.10.0" +kotlinxCoroutines = "1.10.1" kotlinxDatetime = "0.6.1" -kotlinxSerializationJson = "1.7.3" +kotlinxSerializationJson = "1.8.0" ksp = "2.1.0-1.0.29" moduleGraph = "2.7.1" okhttp = "4.12.0" @@ -52,7 +52,7 @@ protobufPlugin = "0.9.4" retrofit = "2.11.0" retrofitKotlinxSerializationJson = "1.0.0" robolectric = "4.14.1" -roborazzi = "1.37.0" +roborazzi = "1.39.0" room = "2.6.1" secrets = "2.0.1" truth = "1.4.4" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e2847c820..cea7a793a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 149e759ae0dbc2b7fcd883584ab63d1562cae856 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Mon, 6 Jan 2025 17:03:30 +0000 Subject: [PATCH 35/51] =?UTF-8?q?=F0=9F=A4=96=20Updates=20baselines=20for?= =?UTF-8?q?=20Dependency=20Guard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dependencies/releaseRuntimeClasspath.txt | 8 ++--- .../prodReleaseRuntimeClasspath.txt | 30 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt index 852b3db52..f36981625 100644 --- a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt +++ b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt @@ -96,10 +96,10 @@ androidx.window:window-core:1.3.0 androidx.window:window:1.3.0 com.google.accompanist:accompanist-drawablepainter:0.32.0 com.google.code.findbugs:jsr305:3.0.2 -com.google.dagger:dagger-lint-aar:2.53.1 -com.google.dagger:dagger:2.53.1 -com.google.dagger:hilt-android:2.53.1 -com.google.dagger:hilt-core:2.53.1 +com.google.dagger:dagger-lint-aar:2.54 +com.google.dagger:dagger:2.54 +com.google.dagger:hilt-android:2.54 +com.google.dagger:hilt-core:2.54 com.google.guava:listenablefuture:1.0 com.squareup.okhttp3:okhttp:4.12.0 com.squareup.okio:okio-jvm:3.9.0 diff --git a/app/dependencies/prodReleaseRuntimeClasspath.txt b/app/dependencies/prodReleaseRuntimeClasspath.txt index d7c2fa1df..e334aa676 100644 --- a/app/dependencies/prodReleaseRuntimeClasspath.txt +++ b/app/dependencies/prodReleaseRuntimeClasspath.txt @@ -164,10 +164,10 @@ 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 com.google.code.findbugs:jsr305:3.0.2 -com.google.dagger:dagger-lint-aar:2.53.1 -com.google.dagger:dagger:2.53.1 -com.google.dagger:hilt-android:2.53.1 -com.google.dagger:hilt-core:2.53.1 +com.google.dagger:dagger-lint-aar:2.54 +com.google.dagger:dagger:2.54 +com.google.dagger:hilt-android:2.54 +com.google.dagger:hilt-core:2.54 com.google.errorprone:error_prone_annotations:2.26.0 com.google.firebase:firebase-abt:21.1.1 com.google.firebase:firebase-analytics:22.1.2 @@ -216,18 +216,18 @@ org.jetbrains.kotlin:kotlin-stdlib-common:2.1.0 org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0 org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0 org.jetbrains.kotlin:kotlin-stdlib:2.1.0 -org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.0 -org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.0 -org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.0 -org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.0 -org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.10.0 -org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.0 +org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.1 +org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.10.1 +org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.10.1 +org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.1 +org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.10.1 +org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.1 org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.6.1 org.jetbrains.kotlinx:kotlinx-datetime:0.6.1 -org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3 -org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3 -org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3 -org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.7.3 -org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3 +org.jetbrains.kotlinx:kotlinx-serialization-bom:1.8.0 +org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.8.0 +org.jetbrains.kotlinx:kotlinx-serialization-core:1.8.0 +org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.8.0 +org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.0 org.jetbrains:annotations:23.0.0 org.jspecify:jspecify:1.0.0 From b77f6f8da7c0a5e3f19120337bb69b5386e21fb3 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Mon, 6 Jan 2025 17:16:47 +0000 Subject: [PATCH 36/51] Refactor change to make it clearer when the deserialization workaround is required. --- .../network/demo/DemoNiaNetworkDataSource.kt | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt index 5d04ee4c8..328cc4e0f 100644 --- a/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt +++ b/core/network/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/demo/DemoNiaNetworkDataSource.kt @@ -18,7 +18,7 @@ package com.google.samples.apps.nowinandroid.core.network.demo import JvmUnitTestDemoAssetManager import android.os.Build.VERSION.SDK_INT -import android.os.Build.VERSION_CODES.N +import android.os.Build.VERSION_CODES.M import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO import com.google.samples.apps.nowinandroid.core.network.NiaNetworkDataSource @@ -43,10 +43,10 @@ class DemoNiaNetworkDataSource @Inject constructor( ) : NiaNetworkDataSource { override suspend fun getTopics(ids: List?): List = - getDemoDataFromJson(TOPICS_ASSET) + getDataFromJsonFile(TOPICS_ASSET) override suspend fun getNewsResources(ids: List?): List = - getDemoDataFromJson(NEWS_ASSET) + getDataFromJsonFile(NEWS_ASSET) override suspend fun getTopicChangeList(after: Int?): List = getTopics().mapToChangeList(NetworkTopic::id) @@ -55,18 +55,22 @@ class DemoNiaNetworkDataSource @Inject constructor( getNewsResources().mapToChangeList(NetworkNewsResource::id) /** - * Get Demo data form a [fileName] Json file. + * Get data from the given JSON [fileName]. */ @OptIn(ExperimentalSerializationApi::class) - private suspend inline fun getDemoDataFromJson(fileName: String): List = + private suspend inline fun getDataFromJsonFile(fileName: String): List = withContext(ioDispatcher) { assets.open(fileName).use { inputStream -> - if (SDK_INT >= N) { - networkJson.decodeFromStream(inputStream) - } // https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342 - else { + if (SDK_INT <= M) { + /** + * On API 23 (M) and below we must use a workaround to avoid an exception being + * thrown during deserialization. See: + * https://github.com/Kotlin/kotlinx.serialization/issues/2457#issuecomment-1786923342 + */ inputStream.bufferedReader().use(BufferedReader::readText) .let(networkJson::decodeFromString) + } else { + networkJson.decodeFromStream(inputStream) } } } From b651b2ed4d7d73edccb4e2b484606418adea8fec Mon Sep 17 00:00:00 2001 From: Pirate Cat Date: Tue, 7 Jan 2025 16:38:16 +1100 Subject: [PATCH 37/51] Update OfflineFirstTopicsRepositoryTest.kt Improve the unit test to do meaning comparisons instead of just comparing two empty lists. --- .../core/data/repository/OfflineFirstTopicsRepositoryTest.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt index d32f424d8..eb7ebbeec 100644 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt @@ -67,6 +67,10 @@ class OfflineFirstTopicsRepositoryTest { @Test fun offlineFirstTopicsRepository_topics_stream_is_backed_by_topics_dao() = testScope.runTest { + // After sync, topicDao.getTopicEntities().first() and subject.getTopics().first() + // will return non-empty lists. + subject.syncWith(synchronizer) + assertEquals( topicDao.getTopicEntities() .first() From 0ab0e539080b71a141e14150d032b04478fb3bcd Mon Sep 17 00:00:00 2001 From: Don Turner Date: Tue, 7 Jan 2025 12:35:12 +0000 Subject: [PATCH 38/51] Rename test methods and classes. --- .../DatabaseTest.kt} | 37 +++++++++++-------- .../core/database/dao/NewsResourceDaoTest.kt | 14 +++---- .../core/database/dao/TopicDaoTest.kt | 18 ++++----- 3 files changed, 38 insertions(+), 31 deletions(-) rename core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/{TestDatabaseSetup.kt => dao/DatabaseTest.kt} (54%) diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/TestDatabaseSetup.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt similarity index 54% rename from core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/TestDatabaseSetup.kt rename to core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt index 7c0d2f1e7..4bdc32606 100644 --- a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/TestDatabaseSetup.kt +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2024 The Android Open Source Project + * Copyright 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,32 +14,39 @@ * limitations under the License. */ -package com.google.samples.apps.nowinandroid.core.database +package com.google.samples.apps.nowinandroid.core.database.dao import android.content.Context import androidx.room.Room import androidx.test.core.app.ApplicationProvider -import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceDao -import com.google.samples.apps.nowinandroid.core.database.dao.TopicDao +import com.google.samples.apps.nowinandroid.core.database.NiaDatabase import org.junit.After import org.junit.Before -abstract class TestDatabaseSetup { - protected lateinit var newsResourceDao: NewsResourceDao - protected lateinit var topicDao: TopicDao - private lateinit var db: NiaDatabase + +internal abstract class DatabaseTest { + + private lateinit var db : NiaDatabase + protected lateinit var newsResourceDao : NewsResourceDao + protected lateinit var topicDao : TopicDao @Before - fun createDb() { - val context = ApplicationProvider.getApplicationContext() - db = Room.inMemoryDatabaseBuilder( - context, - NiaDatabase::class.java, - ).build() + fun setup() { + db = run { + val context = ApplicationProvider.getApplicationContext() + Room.inMemoryDatabaseBuilder( + context, + NiaDatabase::class.java, + ).build() + } newsResourceDao = db.newsResourceDao() topicDao = db.topicDao() } @After - fun closeDb() = db.close() + fun closeDb(){ + db.close() + } } + + diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt index 86af0fa21..3564e2eea 100644 --- a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt @@ -16,7 +16,6 @@ package com.google.samples.apps.nowinandroid.core.database.dao -import com.google.samples.apps.nowinandroid.core.database.TestDatabaseSetup import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceEntity import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceTopicCrossRef import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity @@ -27,9 +26,10 @@ import kotlinx.datetime.Instant import org.junit.Test import kotlin.test.assertEquals -class NewsResourceDaoTest : TestDatabaseSetup() { +internal class NewsResourceDaoTest : DatabaseTest() { + @Test - fun newsResourceDao_fetches_items_by_descending_publish_date() = runTest { + fun getNewsResources_allEntries_areOrderedByPublishDateDesc() = runTest { val newsResourceEntities = listOf( testNewsResource( id = "0", @@ -64,7 +64,7 @@ class NewsResourceDaoTest : TestDatabaseSetup() { } @Test - fun newsResourceDao_filters_items_by_news_ids_by_descending_publish_date() = runTest { + fun getNewsResources_filteredById_areOrderedByDescendingPublishDate() = runTest { val newsResourceEntities = listOf( testNewsResource( id = "0", @@ -102,7 +102,7 @@ class NewsResourceDaoTest : TestDatabaseSetup() { } @Test - fun newsResourceDao_filters_items_by_topic_ids_by_descending_publish_date() = runTest { + fun getNewsResources_filteredByTopicId_areOrderedByDescendingPublishDate() = runTest { val topicEntities = listOf( testTopicEntity( id = "1", @@ -162,7 +162,7 @@ class NewsResourceDaoTest : TestDatabaseSetup() { } @Test - fun newsResourceDao_filters_items_by_news_and_topic_ids_by_descending_publish_date() = runTest { + fun getNewsResources_filteredByIdAndTopicId_areOrderedByDescendingPublishDate() = runTest { val topicEntities = listOf( testTopicEntity( id = "1", @@ -224,7 +224,7 @@ class NewsResourceDaoTest : TestDatabaseSetup() { } @Test - fun newsResourceDao_deletes_items_by_ids() = + fun deleteNewsResources_byId() = runTest { val newsResourceEntities = listOf( testNewsResource( diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt index 4d78ade5d..5fdae3df3 100644 --- a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/TopicDaoTest.kt @@ -16,16 +16,16 @@ package com.google.samples.apps.nowinandroid.core.database.dao -import com.google.samples.apps.nowinandroid.core.database.TestDatabaseSetup import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import org.junit.Test import kotlin.test.assertEquals -class TopicDaoTest : TestDatabaseSetup() { +internal class TopicDaoTest : DatabaseTest() { + @Test - fun topicDao_fetchTopics() = runTest { + fun getTopics() = runTest { insertTopics() val savedTopics = topicDao.getTopicEntities().first() @@ -37,7 +37,7 @@ class TopicDaoTest : TestDatabaseSetup() { } @Test - fun topicDao_getSingleTopicEntity() = runTest { + fun getTopic() = runTest { insertTopics() val savedTopicEntity = topicDao.getTopicEntity("2").first() @@ -46,7 +46,7 @@ class TopicDaoTest : TestDatabaseSetup() { } @Test - fun topicDao_getOneOffTopicEntity() = runTest { + fun getTopics_oneOff() = runTest { insertTopics() val savedTopics = topicDao.getOneOffTopicEntities() @@ -58,7 +58,7 @@ class TopicDaoTest : TestDatabaseSetup() { } @Test - fun topicDao_getTopicEntities_ByIds() = runTest { + fun getTopics_byId() = runTest { insertTopics() val savedTopics = topicDao.getTopicEntities(setOf("1", "2")) @@ -68,7 +68,7 @@ class TopicDaoTest : TestDatabaseSetup() { } @Test - fun topicDao_IgnoreNewEntry_If_EntityExists() = runTest { + fun insertTopic_newEntryIsIgnoredIfAlreadyExists() = runTest { insertTopics() topicDao.insertOrIgnoreTopics( listOf(testTopicEntity("1", "compose")), @@ -80,7 +80,7 @@ class TopicDaoTest : TestDatabaseSetup() { } @Test - fun topicDao_Upsert_Entities() = runTest { + fun upsertTopic_existingEntryIsUpdated() = runTest { insertTopics() topicDao.upsertTopics( listOf(testTopicEntity("1", "newName")), @@ -93,7 +93,7 @@ class TopicDaoTest : TestDatabaseSetup() { } @Test - fun topicDao_Delete_Entities() = runTest { + fun deleteTopics_byId_existingEntriesAreDeleted() = runTest { insertTopics() topicDao.deleteTopics(listOf("1", "2")) From cdc4f002a1770a693e16850f128f5a5e4a80cb62 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Tue, 7 Jan 2025 12:38:49 +0000 Subject: [PATCH 39/51] Small refactor to DatabaseTest --- .../apps/nowinandroid/core/database/dao/DatabaseTest.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt index 4bdc32606..a6514f374 100644 --- a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt @@ -44,9 +44,7 @@ internal abstract class DatabaseTest { } @After - fun closeDb(){ - db.close() - } + fun teardown() = db.close() } From dfc55c94e3fa7950df0c7d26315d0e7f10bbc4d4 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Tue, 7 Jan 2025 12:42:57 +0000 Subject: [PATCH 40/51] Update core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt --- .../core/data/repository/OfflineFirstTopicsRepositoryTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt index eb7ebbeec..1ddf0d0d8 100644 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt @@ -67,7 +67,6 @@ class OfflineFirstTopicsRepositoryTest { @Test fun offlineFirstTopicsRepository_topics_stream_is_backed_by_topics_dao() = testScope.runTest { - // After sync, topicDao.getTopicEntities().first() and subject.getTopics().first() // will return non-empty lists. subject.syncWith(synchronizer) From 793317bfbd8cd18eea0395d8e0ec65da408d8c81 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Tue, 7 Jan 2025 12:43:02 +0000 Subject: [PATCH 41/51] Update core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt --- .../core/data/repository/OfflineFirstTopicsRepositoryTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt index 1ddf0d0d8..81bc28b16 100644 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt @@ -67,7 +67,6 @@ class OfflineFirstTopicsRepositoryTest { @Test fun offlineFirstTopicsRepository_topics_stream_is_backed_by_topics_dao() = testScope.runTest { - // will return non-empty lists. subject.syncWith(synchronizer) assertEquals( From b7973eeac9944da1e692ae91be2f00f9104bd6bd Mon Sep 17 00:00:00 2001 From: Don Turner Date: Tue, 7 Jan 2025 12:48:49 +0000 Subject: [PATCH 42/51] Fix spotless --- .../core/data/repository/OfflineFirstTopicsRepositoryTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt index 81bc28b16..4050a6a39 100644 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstTopicsRepositoryTest.kt @@ -68,7 +68,7 @@ class OfflineFirstTopicsRepositoryTest { fun offlineFirstTopicsRepository_topics_stream_is_backed_by_topics_dao() = testScope.runTest { subject.syncWith(synchronizer) - + assertEquals( topicDao.getTopicEntities() .first() From 249d336127b0d81399de03a508664e11002d3c50 Mon Sep 17 00:00:00 2001 From: Tobi Oyelekan Date: Tue, 7 Jan 2025 13:56:58 +0100 Subject: [PATCH 43/51] fix format --- .../apps/nowinandroid/core/database/dao/DatabaseTest.kt | 9 +++------ .../core/database/dao/NewsResourceDaoTest.kt | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt index a6514f374..89671ba84 100644 --- a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/DatabaseTest.kt @@ -23,12 +23,11 @@ import com.google.samples.apps.nowinandroid.core.database.NiaDatabase import org.junit.After import org.junit.Before - internal abstract class DatabaseTest { - private lateinit var db : NiaDatabase - protected lateinit var newsResourceDao : NewsResourceDao - protected lateinit var topicDao : TopicDao + private lateinit var db: NiaDatabase + protected lateinit var newsResourceDao: NewsResourceDao + protected lateinit var topicDao: TopicDao @Before fun setup() { @@ -46,5 +45,3 @@ internal abstract class DatabaseTest { @After fun teardown() = db.close() } - - diff --git a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt index 3564e2eea..8f74d42e8 100644 --- a/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt +++ b/core/database/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt @@ -26,7 +26,7 @@ import kotlinx.datetime.Instant import org.junit.Test import kotlin.test.assertEquals -internal class NewsResourceDaoTest : DatabaseTest() { +internal class NewsResourceDaoTest : DatabaseTest() { @Test fun getNewsResources_allEntries_areOrderedByPublishDateDesc() = runTest { From 31c4f05872d8fca4a343f720cf5fae84c46bd7a2 Mon Sep 17 00:00:00 2001 From: Rob Orgiu Date: Tue, 7 Jan 2025 17:36:21 +0100 Subject: [PATCH 44/51] Simplify Drag&Drop implementation --- .../dependencies/releaseRuntimeClasspath.txt | 100 +++++++++--------- .../prodReleaseRuntimeClasspath.txt | 68 ++++++------ .../nowinandroid/core/ui/NewsResourceCard.kt | 6 +- gradle/libs.versions.toml | 3 +- 4 files changed, 88 insertions(+), 89 deletions(-) diff --git a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt index f36981625..4e0b3ef48 100644 --- a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt +++ b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt @@ -2,24 +2,24 @@ androidx.activity:activity-compose:1.9.3 androidx.activity:activity-ktx:1.9.3 androidx.activity:activity:1.9.3 androidx.annotation:annotation-experimental:1.4.1 -androidx.annotation:annotation-jvm:1.8.1 -androidx.annotation:annotation:1.8.1 +androidx.annotation:annotation-jvm:1.9.1 +androidx.annotation:annotation:1.9.1 androidx.appcompat:appcompat-resources:1.6.1 androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 androidx.browser:browser:1.8.0 -androidx.collection:collection-jvm:1.4.4 -androidx.collection:collection-ktx:1.4.4 -androidx.collection:collection:1.4.4 -androidx.compose.animation:animation-android:1.7.6 -androidx.compose.animation:animation-core-android:1.7.6 -androidx.compose.animation:animation-core:1.7.6 -androidx.compose.animation:animation:1.7.6 -androidx.compose.foundation:foundation-android:1.7.6 -androidx.compose.foundation:foundation-layout-android:1.7.6 -androidx.compose.foundation:foundation-layout:1.7.6 -androidx.compose.foundation:foundation:1.7.6 +androidx.collection:collection-jvm:1.5.0-alpha06 +androidx.collection:collection-ktx:1.5.0-alpha06 +androidx.collection:collection:1.5.0-alpha06 +androidx.compose.animation:animation-android:1.8.0-alpha06 +androidx.compose.animation:animation-core-android:1.8.0-alpha06 +androidx.compose.animation:animation-core:1.8.0-alpha06 +androidx.compose.animation:animation:1.8.0-alpha06 +androidx.compose.foundation:foundation-android:1.8.0-alpha06 +androidx.compose.foundation:foundation-layout-android:1.8.0-alpha06 +androidx.compose.foundation:foundation-layout:1.8.0-alpha06 +androidx.compose.foundation:foundation:1.8.0-alpha06 androidx.compose.material3.adaptive:adaptive-android:1.0.0 androidx.compose.material3.adaptive:adaptive:1.0.0 androidx.compose.material3:material3-adaptive-navigation-suite-android:1.3.1 @@ -32,55 +32,55 @@ androidx.compose.material:material-icons-extended-android:1.7.6 androidx.compose.material:material-icons-extended:1.7.6 androidx.compose.material:material-ripple-android:1.7.6 androidx.compose.material:material-ripple:1.7.6 -androidx.compose.runtime:runtime-android:1.7.6 -androidx.compose.runtime:runtime-saveable-android:1.7.6 -androidx.compose.runtime:runtime-saveable:1.7.6 -androidx.compose.runtime:runtime:1.7.6 -androidx.compose.ui:ui-android:1.7.6 -androidx.compose.ui:ui-geometry-android:1.7.6 -androidx.compose.ui:ui-geometry:1.7.6 -androidx.compose.ui:ui-graphics-android:1.7.6 -androidx.compose.ui:ui-graphics:1.7.6 -androidx.compose.ui:ui-text-android:1.7.6 -androidx.compose.ui:ui-text:1.7.6 -androidx.compose.ui:ui-tooling-preview-android:1.7.6 -androidx.compose.ui:ui-tooling-preview:1.7.6 -androidx.compose.ui:ui-unit-android:1.7.6 -androidx.compose.ui:ui-unit:1.7.6 -androidx.compose.ui:ui-util-android:1.7.6 -androidx.compose.ui:ui-util:1.7.6 -androidx.compose.ui:ui:1.7.6 +androidx.compose.runtime:runtime-android:1.8.0-alpha06 +androidx.compose.runtime:runtime-saveable-android:1.8.0-alpha06 +androidx.compose.runtime:runtime-saveable:1.8.0-alpha06 +androidx.compose.runtime:runtime:1.8.0-alpha06 +androidx.compose.ui:ui-android:1.8.0-alpha06 +androidx.compose.ui:ui-geometry-android:1.8.0-alpha06 +androidx.compose.ui:ui-geometry:1.8.0-alpha06 +androidx.compose.ui:ui-graphics-android:1.8.0-alpha06 +androidx.compose.ui:ui-graphics:1.8.0-alpha06 +androidx.compose.ui:ui-text-android:1.8.0-alpha06 +androidx.compose.ui:ui-text:1.8.0-alpha06 +androidx.compose.ui:ui-tooling-preview-android:1.8.0-alpha06 +androidx.compose.ui:ui-tooling-preview:1.8.0-alpha06 +androidx.compose.ui:ui-unit-android:1.8.0-alpha06 +androidx.compose.ui:ui-unit:1.8.0-alpha06 +androidx.compose.ui:ui-util-android:1.8.0-alpha06 +androidx.compose.ui:ui-util:1.8.0-alpha06 +androidx.compose.ui:ui:1.8.0-alpha06 androidx.compose:compose-bom:2024.12.01 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.13.1 androidx.core:core:1.13.1 androidx.customview:customview-poolingcontainer:1.0.0 androidx.customview:customview:1.0.0 -androidx.emoji2:emoji2:1.3.0 +androidx.emoji2:emoji2:1.4.0 androidx.exifinterface:exifinterface:1.3.7 androidx.fragment:fragment:1.5.1 androidx.graphics:graphics-path:1.0.1 androidx.interpolator:interpolator:1.0.0 -androidx.lifecycle:lifecycle-common-java8:2.8.3 -androidx.lifecycle:lifecycle-common-jvm:2.8.3 -androidx.lifecycle:lifecycle-common:2.8.3 -androidx.lifecycle:lifecycle-livedata-core-ktx:2.8.3 -androidx.lifecycle:lifecycle-livedata-core:2.8.3 -androidx.lifecycle:lifecycle-livedata:2.8.3 -androidx.lifecycle:lifecycle-process:2.8.3 -androidx.lifecycle:lifecycle-runtime-android:2.8.3 -androidx.lifecycle:lifecycle-runtime-compose-android:2.8.3 -androidx.lifecycle:lifecycle-runtime-compose:2.8.3 -androidx.lifecycle:lifecycle-runtime-ktx-android:2.8.3 -androidx.lifecycle:lifecycle-runtime-ktx:2.8.3 -androidx.lifecycle:lifecycle-runtime:2.8.3 -androidx.lifecycle:lifecycle-viewmodel-android:2.8.3 -androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.8.3 -androidx.lifecycle:lifecycle-viewmodel:2.8.3 +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-viewmodel-android: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.metrics:metrics-performance:1.0.0-beta01 -androidx.profileinstaller:profileinstaller:1.3.1 +androidx.profileinstaller:profileinstaller:1.4.0 androidx.savedstate:savedstate-ktx:1.2.1 androidx.savedstate:savedstate:1.2.1 androidx.startup:startup-runtime:1.1.1 diff --git a/app/dependencies/prodReleaseRuntimeClasspath.txt b/app/dependencies/prodReleaseRuntimeClasspath.txt index e334aa676..f1cafaad0 100644 --- a/app/dependencies/prodReleaseRuntimeClasspath.txt +++ b/app/dependencies/prodReleaseRuntimeClasspath.txt @@ -2,25 +2,25 @@ androidx.activity:activity-compose:1.9.3 androidx.activity:activity-ktx:1.9.3 androidx.activity:activity:1.9.3 androidx.annotation:annotation-experimental:1.4.1 -androidx.annotation:annotation-jvm:1.8.1 -androidx.annotation:annotation:1.8.1 +androidx.annotation:annotation-jvm:1.9.1 +androidx.annotation:annotation:1.9.1 androidx.appcompat:appcompat-resources:1.7.0 androidx.appcompat:appcompat:1.7.0 androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 androidx.browser:browser:1.8.0 -androidx.collection:collection-jvm:1.4.4 -androidx.collection:collection-ktx:1.4.4 -androidx.collection:collection:1.4.4 -androidx.compose.animation:animation-android:1.7.6 -androidx.compose.animation:animation-core-android:1.7.6 -androidx.compose.animation:animation-core:1.7.6 -androidx.compose.animation:animation:1.7.6 -androidx.compose.foundation:foundation-android:1.7.6 -androidx.compose.foundation:foundation-layout-android:1.7.6 -androidx.compose.foundation:foundation-layout:1.7.6 -androidx.compose.foundation:foundation:1.7.6 +androidx.collection:collection-jvm:1.5.0-alpha06 +androidx.collection:collection-ktx:1.5.0-alpha06 +androidx.collection:collection:1.5.0-alpha06 +androidx.compose.animation:animation-android:1.8.0-alpha06 +androidx.compose.animation:animation-core-android:1.8.0-alpha06 +androidx.compose.animation:animation-core:1.8.0-alpha06 +androidx.compose.animation:animation:1.8.0-alpha06 +androidx.compose.foundation:foundation-android:1.8.0-alpha06 +androidx.compose.foundation:foundation-layout-android:1.8.0-alpha06 +androidx.compose.foundation:foundation-layout:1.8.0-alpha06 +androidx.compose.foundation:foundation:1.8.0-alpha06 androidx.compose.material3.adaptive:adaptive-android:1.0.0 androidx.compose.material3.adaptive:adaptive-layout-android:1.0.0 androidx.compose.material3.adaptive:adaptive-layout:1.0.0 @@ -39,25 +39,25 @@ androidx.compose.material:material-icons-extended-android:1.7.6 androidx.compose.material:material-icons-extended:1.7.6 androidx.compose.material:material-ripple-android:1.7.6 androidx.compose.material:material-ripple:1.7.6 -androidx.compose.runtime:runtime-android:1.7.6 -androidx.compose.runtime:runtime-saveable-android:1.7.6 -androidx.compose.runtime:runtime-saveable:1.7.6 -androidx.compose.runtime:runtime-tracing:1.7.6 -androidx.compose.runtime:runtime:1.7.6 -androidx.compose.ui:ui-android:1.7.6 -androidx.compose.ui:ui-geometry-android:1.7.6 -androidx.compose.ui:ui-geometry:1.7.6 -androidx.compose.ui:ui-graphics-android:1.7.6 -androidx.compose.ui:ui-graphics:1.7.6 -androidx.compose.ui:ui-text-android:1.7.6 -androidx.compose.ui:ui-text:1.7.6 -androidx.compose.ui:ui-tooling-preview-android:1.7.6 -androidx.compose.ui:ui-tooling-preview:1.7.6 -androidx.compose.ui:ui-unit-android:1.7.6 -androidx.compose.ui:ui-unit:1.7.6 -androidx.compose.ui:ui-util-android:1.7.6 -androidx.compose.ui:ui-util:1.7.6 -androidx.compose.ui:ui:1.7.6 +androidx.compose.runtime:runtime-android:1.8.0-alpha06 +androidx.compose.runtime:runtime-saveable-android:1.8.0-alpha06 +androidx.compose.runtime:runtime-saveable:1.8.0-alpha06 +androidx.compose.runtime:runtime-tracing:1.8.0-alpha06 +androidx.compose.runtime:runtime:1.8.0-alpha06 +androidx.compose.ui:ui-android:1.8.0-alpha06 +androidx.compose.ui:ui-geometry-android:1.8.0-alpha06 +androidx.compose.ui:ui-geometry:1.8.0-alpha06 +androidx.compose.ui:ui-graphics-android:1.8.0-alpha06 +androidx.compose.ui:ui-graphics:1.8.0-alpha06 +androidx.compose.ui:ui-text-android:1.8.0-alpha06 +androidx.compose.ui:ui-text:1.8.0-alpha06 +androidx.compose.ui:ui-tooling-preview-android:1.8.0-alpha06 +androidx.compose.ui:ui-tooling-preview:1.8.0-alpha06 +androidx.compose.ui:ui-unit-android:1.8.0-alpha06 +androidx.compose.ui:ui-unit:1.8.0-alpha06 +androidx.compose.ui:ui-util-android:1.8.0-alpha06 +androidx.compose.ui:ui-util:1.8.0-alpha06 +androidx.compose.ui:ui:1.8.0-alpha06 androidx.compose:compose-bom:2024.12.01 androidx.concurrent:concurrent-futures-ktx:1.1.0 androidx.concurrent:concurrent-futures:1.1.0 @@ -79,8 +79,8 @@ androidx.datastore:datastore-preferences:1.1.1 androidx.datastore:datastore:1.1.1 androidx.documentfile:documentfile:1.0.0 androidx.drawerlayout:drawerlayout:1.0.0 -androidx.emoji2:emoji2-views-helper:1.3.0 -androidx.emoji2:emoji2:1.3.0 +androidx.emoji2:emoji2-views-helper:1.4.0 +androidx.emoji2:emoji2:1.4.0 androidx.exifinterface:exifinterface:1.3.7 androidx.fragment:fragment:1.5.4 androidx.graphics:graphics-path:1.0.1 diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index ff10b8d38..f6e446be0 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -138,16 +138,14 @@ fun NewsResourceCardExpanded( userNewsResource.title, modifier = Modifier .fillMaxWidth((.8f)) - .dragAndDropSource { - startTransfer( + .dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( sharingLabel, sharingContent, ), flags = dragAndDropFlags, - ), - ) + ) }, ) Spacer(modifier = Modifier.weight(1f)) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ce4bd2c64..1936fe5c1 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -57,6 +57,7 @@ room = "2.6.1" secrets = "2.0.1" truth = "1.4.4" turbine = "1.2.0" +composeFoundation = "1.8.0-alpha06" [bundles] androidx-compose-ui-test = ["androidx-compose-ui-test", "androidx-compose-ui-testManifest"] @@ -69,7 +70,7 @@ androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version androidx-benchmark-macro = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "androidxMacroBenchmark" } androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "androidxBrowser" } androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" } -androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation" } +androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "composeFoundation" } androidx-compose-foundation-layout = { group = "androidx.compose.foundation", name = "foundation-layout" } androidx-compose-material-iconsExtended = { group = "androidx.compose.material", name = "material-icons-extended" } androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } From 4885e92ba5eac7886a81e0067bb2c70622b0d04e Mon Sep 17 00:00:00 2001 From: Rob Orgiu Date: Tue, 7 Jan 2025 17:44:54 +0100 Subject: [PATCH 45/51] Reformat NewsResourceCard --- .../apps/nowinandroid/core/ui/NewsResourceCard.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt index f6e446be0..862aec6b2 100644 --- a/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt +++ b/core/ui/src/main/kotlin/com/google/samples/apps/nowinandroid/core/ui/NewsResourceCard.kt @@ -139,13 +139,13 @@ fun NewsResourceCardExpanded( modifier = Modifier .fillMaxWidth((.8f)) .dragAndDropSource { _ -> - DragAndDropTransferData( - ClipData.newPlainText( - sharingLabel, - sharingContent, - ), - flags = dragAndDropFlags, - ) + DragAndDropTransferData( + ClipData.newPlainText( + sharingLabel, + sharingContent, + ), + flags = dragAndDropFlags, + ) }, ) Spacer(modifier = Modifier.weight(1f)) From 798b941b7537f430922bbebd30f9d563037eebec Mon Sep 17 00:00:00 2001 From: EYH GPT Date: Wed, 8 Jan 2025 11:02:02 +1100 Subject: [PATCH 46/51] Update OfflineFirstNewsRepositoryTest.kt Improve the unit test to perform meaningful comparisons instead of merely comparing two empty lists. --- .../core/data/repository/OfflineFirstNewsRepositoryTest.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt index 01111013f..ea0f07250 100644 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt @@ -89,6 +89,10 @@ class OfflineFirstNewsRepositoryTest { @Test fun offlineFirstNewsRepository_news_resources_stream_is_backed_by_news_resource_dao() = testScope.runTest { + // After sync, newsResourceDao.getNewsResources().first() and + // subject.getNewsResources().first() will return non-empty lists. + subject.syncWith(synchronizer) + assertEquals( newsResourceDao.getNewsResources() .first() From fa532089e2f8a26f00469d9312e72e375fb338a0 Mon Sep 17 00:00:00 2001 From: E Y H Date: Wed, 8 Jan 2025 12:33:11 +1100 Subject: [PATCH 47/51] Update OfflineFirstNewsRepositoryTest.kt Remove the comments. A similar comment wasn't accpeted in my last PR. --- .../core/data/repository/OfflineFirstNewsRepositoryTest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt index ea0f07250..e0ff97225 100644 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt @@ -89,8 +89,6 @@ class OfflineFirstNewsRepositoryTest { @Test fun offlineFirstNewsRepository_news_resources_stream_is_backed_by_news_resource_dao() = testScope.runTest { - // After sync, newsResourceDao.getNewsResources().first() and - // subject.getNewsResources().first() will return non-empty lists. subject.syncWith(synchronizer) assertEquals( From 82e4e7c65e2f85e98382d2c7986f3a6e000c33ee Mon Sep 17 00:00:00 2001 From: Rob Orgiu Date: Wed, 8 Jan 2025 09:20:03 +0100 Subject: [PATCH 48/51] Reformat androidxComposeFoundation in alphabetical order --- gradle/libs.versions.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1936fe5c1..9357809b0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,6 +8,7 @@ androidxActivity = "1.9.3" androidxAppCompat = "1.7.0" androidxBrowser = "1.8.0" androidxComposeBom = "2024.12.01" +androidxComposeFoundation = "1.8.0-alpha07" androidxComposeRuntimeTracing = "1.7.6" androidxCore = "1.15.0" androidxCoreSplashscreen = "1.0.1" @@ -57,7 +58,6 @@ room = "2.6.1" secrets = "2.0.1" truth = "1.4.4" turbine = "1.2.0" -composeFoundation = "1.8.0-alpha06" [bundles] androidx-compose-ui-test = ["androidx-compose-ui-test", "androidx-compose-ui-testManifest"] @@ -70,7 +70,7 @@ androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version androidx-benchmark-macro = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version.ref = "androidxMacroBenchmark" } androidx-browser = { group = "androidx.browser", name = "browser", version.ref = "androidxBrowser" } androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidxComposeBom" } -androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "composeFoundation" } +androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "androidxComposeFoundation" } androidx-compose-foundation-layout = { group = "androidx.compose.foundation", name = "foundation-layout" } androidx-compose-material-iconsExtended = { group = "androidx.compose.material", name = "material-icons-extended" } androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } From 7770f83fa5b6281a40daab37cc5d9172b237c11e Mon Sep 17 00:00:00 2001 From: Rob Orgiu Date: Wed, 8 Jan 2025 12:09:46 +0100 Subject: [PATCH 49/51] Updates dependencies baseline --- .../dependencies/releaseRuntimeClasspath.txt | 58 +++++++++--------- .../prodReleaseRuntimeClasspath.txt | 60 +++++++++---------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt index 4e0b3ef48..04a864e86 100644 --- a/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt +++ b/app-nia-catalog/dependencies/releaseRuntimeClasspath.txt @@ -9,17 +9,17 @@ androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 androidx.browser:browser:1.8.0 -androidx.collection:collection-jvm:1.5.0-alpha06 -androidx.collection:collection-ktx:1.5.0-alpha06 -androidx.collection:collection:1.5.0-alpha06 -androidx.compose.animation:animation-android:1.8.0-alpha06 -androidx.compose.animation:animation-core-android:1.8.0-alpha06 -androidx.compose.animation:animation-core:1.8.0-alpha06 -androidx.compose.animation:animation:1.8.0-alpha06 -androidx.compose.foundation:foundation-android:1.8.0-alpha06 -androidx.compose.foundation:foundation-layout-android:1.8.0-alpha06 -androidx.compose.foundation:foundation-layout:1.8.0-alpha06 -androidx.compose.foundation:foundation:1.8.0-alpha06 +androidx.collection:collection-jvm:1.5.0-beta01 +androidx.collection:collection-ktx:1.5.0-beta01 +androidx.collection:collection:1.5.0-beta01 +androidx.compose.animation:animation-android:1.8.0-alpha07 +androidx.compose.animation:animation-core-android:1.8.0-alpha07 +androidx.compose.animation:animation-core:1.8.0-alpha07 +androidx.compose.animation:animation:1.8.0-alpha07 +androidx.compose.foundation:foundation-android:1.8.0-alpha07 +androidx.compose.foundation:foundation-layout-android:1.8.0-alpha07 +androidx.compose.foundation:foundation-layout:1.8.0-alpha07 +androidx.compose.foundation:foundation:1.8.0-alpha07 androidx.compose.material3.adaptive:adaptive-android:1.0.0 androidx.compose.material3.adaptive:adaptive:1.0.0 androidx.compose.material3:material3-adaptive-navigation-suite-android:1.3.1 @@ -32,24 +32,24 @@ androidx.compose.material:material-icons-extended-android:1.7.6 androidx.compose.material:material-icons-extended:1.7.6 androidx.compose.material:material-ripple-android:1.7.6 androidx.compose.material:material-ripple:1.7.6 -androidx.compose.runtime:runtime-android:1.8.0-alpha06 -androidx.compose.runtime:runtime-saveable-android:1.8.0-alpha06 -androidx.compose.runtime:runtime-saveable:1.8.0-alpha06 -androidx.compose.runtime:runtime:1.8.0-alpha06 -androidx.compose.ui:ui-android:1.8.0-alpha06 -androidx.compose.ui:ui-geometry-android:1.8.0-alpha06 -androidx.compose.ui:ui-geometry:1.8.0-alpha06 -androidx.compose.ui:ui-graphics-android:1.8.0-alpha06 -androidx.compose.ui:ui-graphics:1.8.0-alpha06 -androidx.compose.ui:ui-text-android:1.8.0-alpha06 -androidx.compose.ui:ui-text:1.8.0-alpha06 -androidx.compose.ui:ui-tooling-preview-android:1.8.0-alpha06 -androidx.compose.ui:ui-tooling-preview:1.8.0-alpha06 -androidx.compose.ui:ui-unit-android:1.8.0-alpha06 -androidx.compose.ui:ui-unit:1.8.0-alpha06 -androidx.compose.ui:ui-util-android:1.8.0-alpha06 -androidx.compose.ui:ui-util:1.8.0-alpha06 -androidx.compose.ui:ui:1.8.0-alpha06 +androidx.compose.runtime:runtime-android:1.8.0-alpha07 +androidx.compose.runtime:runtime-saveable-android:1.8.0-alpha07 +androidx.compose.runtime:runtime-saveable:1.8.0-alpha07 +androidx.compose.runtime:runtime:1.8.0-alpha07 +androidx.compose.ui:ui-android:1.8.0-alpha07 +androidx.compose.ui:ui-geometry-android:1.8.0-alpha07 +androidx.compose.ui:ui-geometry:1.8.0-alpha07 +androidx.compose.ui:ui-graphics-android:1.8.0-alpha07 +androidx.compose.ui:ui-graphics:1.8.0-alpha07 +androidx.compose.ui:ui-text-android:1.8.0-alpha07 +androidx.compose.ui:ui-text:1.8.0-alpha07 +androidx.compose.ui:ui-tooling-preview-android:1.8.0-alpha07 +androidx.compose.ui:ui-tooling-preview:1.8.0-alpha07 +androidx.compose.ui:ui-unit-android:1.8.0-alpha07 +androidx.compose.ui:ui-unit:1.8.0-alpha07 +androidx.compose.ui:ui-util-android:1.8.0-alpha07 +androidx.compose.ui:ui-util:1.8.0-alpha07 +androidx.compose.ui:ui:1.8.0-alpha07 androidx.compose:compose-bom:2024.12.01 androidx.concurrent:concurrent-futures:1.1.0 androidx.core:core-ktx:1.13.1 diff --git a/app/dependencies/prodReleaseRuntimeClasspath.txt b/app/dependencies/prodReleaseRuntimeClasspath.txt index f1cafaad0..6fca688a1 100644 --- a/app/dependencies/prodReleaseRuntimeClasspath.txt +++ b/app/dependencies/prodReleaseRuntimeClasspath.txt @@ -10,17 +10,17 @@ androidx.arch.core:core-common:2.2.0 androidx.arch.core:core-runtime:2.2.0 androidx.autofill:autofill:1.0.0 androidx.browser:browser:1.8.0 -androidx.collection:collection-jvm:1.5.0-alpha06 -androidx.collection:collection-ktx:1.5.0-alpha06 -androidx.collection:collection:1.5.0-alpha06 -androidx.compose.animation:animation-android:1.8.0-alpha06 -androidx.compose.animation:animation-core-android:1.8.0-alpha06 -androidx.compose.animation:animation-core:1.8.0-alpha06 -androidx.compose.animation:animation:1.8.0-alpha06 -androidx.compose.foundation:foundation-android:1.8.0-alpha06 -androidx.compose.foundation:foundation-layout-android:1.8.0-alpha06 -androidx.compose.foundation:foundation-layout:1.8.0-alpha06 -androidx.compose.foundation:foundation:1.8.0-alpha06 +androidx.collection:collection-jvm:1.5.0-beta01 +androidx.collection:collection-ktx:1.5.0-beta01 +androidx.collection:collection:1.5.0-beta01 +androidx.compose.animation:animation-android:1.8.0-alpha07 +androidx.compose.animation:animation-core-android:1.8.0-alpha07 +androidx.compose.animation:animation-core:1.8.0-alpha07 +androidx.compose.animation:animation:1.8.0-alpha07 +androidx.compose.foundation:foundation-android:1.8.0-alpha07 +androidx.compose.foundation:foundation-layout-android:1.8.0-alpha07 +androidx.compose.foundation:foundation-layout:1.8.0-alpha07 +androidx.compose.foundation:foundation:1.8.0-alpha07 androidx.compose.material3.adaptive:adaptive-android:1.0.0 androidx.compose.material3.adaptive:adaptive-layout-android:1.0.0 androidx.compose.material3.adaptive:adaptive-layout:1.0.0 @@ -39,25 +39,25 @@ androidx.compose.material:material-icons-extended-android:1.7.6 androidx.compose.material:material-icons-extended:1.7.6 androidx.compose.material:material-ripple-android:1.7.6 androidx.compose.material:material-ripple:1.7.6 -androidx.compose.runtime:runtime-android:1.8.0-alpha06 -androidx.compose.runtime:runtime-saveable-android:1.8.0-alpha06 -androidx.compose.runtime:runtime-saveable:1.8.0-alpha06 -androidx.compose.runtime:runtime-tracing:1.8.0-alpha06 -androidx.compose.runtime:runtime:1.8.0-alpha06 -androidx.compose.ui:ui-android:1.8.0-alpha06 -androidx.compose.ui:ui-geometry-android:1.8.0-alpha06 -androidx.compose.ui:ui-geometry:1.8.0-alpha06 -androidx.compose.ui:ui-graphics-android:1.8.0-alpha06 -androidx.compose.ui:ui-graphics:1.8.0-alpha06 -androidx.compose.ui:ui-text-android:1.8.0-alpha06 -androidx.compose.ui:ui-text:1.8.0-alpha06 -androidx.compose.ui:ui-tooling-preview-android:1.8.0-alpha06 -androidx.compose.ui:ui-tooling-preview:1.8.0-alpha06 -androidx.compose.ui:ui-unit-android:1.8.0-alpha06 -androidx.compose.ui:ui-unit:1.8.0-alpha06 -androidx.compose.ui:ui-util-android:1.8.0-alpha06 -androidx.compose.ui:ui-util:1.8.0-alpha06 -androidx.compose.ui:ui:1.8.0-alpha06 +androidx.compose.runtime:runtime-android:1.8.0-alpha07 +androidx.compose.runtime:runtime-saveable-android:1.8.0-alpha07 +androidx.compose.runtime:runtime-saveable:1.8.0-alpha07 +androidx.compose.runtime:runtime-tracing:1.8.0-alpha07 +androidx.compose.runtime:runtime:1.8.0-alpha07 +androidx.compose.ui:ui-android:1.8.0-alpha07 +androidx.compose.ui:ui-geometry-android:1.8.0-alpha07 +androidx.compose.ui:ui-geometry:1.8.0-alpha07 +androidx.compose.ui:ui-graphics-android:1.8.0-alpha07 +androidx.compose.ui:ui-graphics:1.8.0-alpha07 +androidx.compose.ui:ui-text-android:1.8.0-alpha07 +androidx.compose.ui:ui-text:1.8.0-alpha07 +androidx.compose.ui:ui-tooling-preview-android:1.8.0-alpha07 +androidx.compose.ui:ui-tooling-preview:1.8.0-alpha07 +androidx.compose.ui:ui-unit-android:1.8.0-alpha07 +androidx.compose.ui:ui-unit:1.8.0-alpha07 +androidx.compose.ui:ui-util-android:1.8.0-alpha07 +androidx.compose.ui:ui-util:1.8.0-alpha07 +androidx.compose.ui:ui:1.8.0-alpha07 androidx.compose:compose-bom:2024.12.01 androidx.concurrent:concurrent-futures-ktx:1.1.0 androidx.concurrent:concurrent-futures:1.1.0 From ef0d89e9fbacb228855cf20e4901e6963f53964f Mon Sep 17 00:00:00 2001 From: Don Turner Date: Wed, 8 Jan 2025 14:09:38 +0000 Subject: [PATCH 50/51] Update core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt --- .../core/data/repository/OfflineFirstNewsRepositoryTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt index e0ff97225..7afcfb6df 100644 --- a/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt +++ b/core/data/src/test/kotlin/com/google/samples/apps/nowinandroid/core/data/repository/OfflineFirstNewsRepositoryTest.kt @@ -90,7 +90,6 @@ class OfflineFirstNewsRepositoryTest { fun offlineFirstNewsRepository_news_resources_stream_is_backed_by_news_resource_dao() = testScope.runTest { subject.syncWith(synchronizer) - assertEquals( newsResourceDao.getNewsResources() .first() From 6c931b1e11ffe9d627c904a586047b0c6c536f39 Mon Sep 17 00:00:00 2001 From: Ben Weiss Date: Fri, 20 Dec 2024 10:27:45 +0100 Subject: [PATCH 51/51] Revert "Feature / Added baseline and startup profile generation (#1752)" This reverts commit 8f196e18a71f7b65e2c8bb83074463fa10ea7b9b. --- .github/workflows/NightlyBaselineProfiles.yaml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/NightlyBaselineProfiles.yaml b/.github/workflows/NightlyBaselineProfiles.yaml index c8e2651c5..6e7354476 100644 --- a/.github/workflows/NightlyBaselineProfiles.yaml +++ b/.github/workflows/NightlyBaselineProfiles.yaml @@ -55,9 +55,8 @@ jobs: -Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true -Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect" - # This generates both baseline and startup profile and adds them into the generated folder - - name: Generate Baseline Profile - run: ./gradlew :app:generateReleaseBaselineProfile - -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=baselineprofile - -Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect" - --stacktrace + - name: Build all build type and flavor permutations including baseline profiles + run: ./gradlew :app:assemble + -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=baselineprofile + -Pandroid.testoptions.manageddevices.emulator.gpu="swiftshader_indirect" + -Pandroid.experimental.testOptions.managedDevices.emulator.showKernelLogging=true