From cbc8b6169e5dc1eceffbbd118879d848a0a6fa48 Mon Sep 17 00:00:00 2001 From: lihenggui <350699171@qq.com> Date: Sat, 2 Dec 2023 08:34:42 -0800 Subject: [PATCH 01/22] Bump org.jetbrains.kotlinx:kotlinx-datetime from 0.4.1 to 0.5.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 529029bb24..33b7e56299 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -44,7 +44,7 @@ jacoco = "0.8.7" junit4 = "4.13.2" kotlin = "1.9.10" kotlinxCoroutines = "1.7.3" -kotlinxDatetime = "0.4.1" +kotlinxDatetime = "0.5.0" kotlinxSerializationJson = "1.6.0" ksp = "1.9.10-1.0.13" lint = "31.1.3" From 5a1258232fa3498c79f62c7e2535f4de41201d46 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Thu, 16 Nov 2023 22:48:12 +0100 Subject: [PATCH 02/22] Fix `emptyResultIsReturned_withNotMatchingQuery` unit test `searchResultUiState` transitively relied on `getSearchContentsCount` updates and on `userDataRepository` to emit something. --- .../TestSearchContentsRepository.kt | 45 +++++++++---------- .../feature/search/SearchViewModelTest.kt | 5 ++- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt index 9b6151449d..94ef2e384a 100644 --- a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt @@ -21,42 +21,39 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.SearchResult import com.google.samples.apps.nowinandroid.core.model.data.Topic import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.update class TestSearchContentsRepository : SearchContentsRepository { - private val cachedTopics: MutableList = mutableListOf() - private val cachedNewsResources: MutableList = mutableListOf() + private val cachedTopics = MutableStateFlow(emptyList()) + private val cachedNewsResources = MutableStateFlow(emptyList()) override suspend fun populateFtsData() = Unit - override fun searchContents(searchQuery: String): Flow = flowOf( - SearchResult( - topics = cachedTopics.filter { - searchQuery in it.name || searchQuery in it.shortDescription || searchQuery in it.longDescription - }, - newsResources = cachedNewsResources.filter { - searchQuery in it.content || searchQuery in it.title - }, - ), - ) - - override fun getSearchContentsCount(): Flow = flow { - emit(cachedTopics.size + cachedNewsResources.size) - } + override fun searchContents(searchQuery: String): Flow = + combine(cachedTopics, cachedNewsResources) { topics, news -> + SearchResult( + topics = topics.filter { + searchQuery in it.name || searchQuery in it.shortDescription || searchQuery in it.longDescription + }, + newsResources = news.filter { + searchQuery in it.content || searchQuery in it.title + }, + ) + } + + override fun getSearchContentsCount(): Flow = combine(cachedTopics, cachedNewsResources) { topics, news -> topics.size + news.size } /** * Test only method to add the topics to the stored list in memory */ - fun addTopics(topics: List) { - cachedTopics.addAll(topics) - } + fun addTopics(topics: List) = cachedTopics.update { it + topics } /** * Test only method to add the news resources to the stored list in memory */ - fun addNewsResources(newsResources: List) { - cachedNewsResources.addAll(newsResources) - } + fun addNewsResources(newsResources: List) = + cachedNewsResources.update { newsResources } } diff --git a/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt b/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt index fc9c20549c..da0d5654e8 100644 --- a/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt +++ b/feature/search/src/test/kotlin/com/google/samples/apps/nowinandroid/feature/search/SearchViewModelTest.kt @@ -26,6 +26,7 @@ import com.google.samples.apps.nowinandroid.core.testing.data.topicsTestData import com.google.samples.apps.nowinandroid.core.testing.repository.TestRecentSearchRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestSearchContentsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository +import com.google.samples.apps.nowinandroid.core.testing.repository.emptyUserData import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule import com.google.samples.apps.nowinandroid.feature.search.RecentSearchQueriesUiState.Success import com.google.samples.apps.nowinandroid.feature.search.SearchResultUiState.EmptyQuery @@ -71,6 +72,7 @@ class SearchViewModelTest { recentSearchRepository = recentSearchRepository, analyticsHelper = NoOpAnalyticsHelper(), ) + userDataRepository.setUserData(emptyUserData) } @Test @@ -100,8 +102,7 @@ class SearchViewModelTest { searchContentsRepository.addTopics(topicsTestData) val result = viewModel.searchResultUiState.value - // TODO: Figure out to get the latest emitted ui State? The result is emitted as EmptyQuery - // assertIs(result) + assertIs(result) collectJob.cancel() } From a83f6691c4726c19384cfbbc94694bbd42aded47 Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Wed, 31 Jan 2024 10:44:18 +0100 Subject: [PATCH 03/22] Fix addNewsResources issue --- .../core/testing/repository/TestSearchContentsRepository.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt index 94ef2e384a..4a3baba443 100644 --- a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt @@ -55,5 +55,5 @@ class TestSearchContentsRepository : SearchContentsRepository { * Test only method to add the news resources to the stored list in memory */ fun addNewsResources(newsResources: List) = - cachedNewsResources.update { newsResources } + cachedNewsResources.update { it + newsResources } } From b687328567688e928726fbb8e522cf92a16aaecd Mon Sep 17 00:00:00 2001 From: Simon Marquis Date: Wed, 31 Jan 2024 10:45:45 +0100 Subject: [PATCH 04/22] Replace comments with proper `@TestOnly` annotations --- .../testing/repository/TestSearchContentsRepository.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt index 4a3baba443..5436cd10f7 100644 --- a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/repository/TestSearchContentsRepository.kt @@ -24,6 +24,7 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.update +import org.jetbrains.annotations.TestOnly class TestSearchContentsRepository : SearchContentsRepository { @@ -46,14 +47,10 @@ class TestSearchContentsRepository : SearchContentsRepository { override fun getSearchContentsCount(): Flow = combine(cachedTopics, cachedNewsResources) { topics, news -> topics.size + news.size } - /** - * Test only method to add the topics to the stored list in memory - */ + @TestOnly fun addTopics(topics: List) = cachedTopics.update { it + topics } - /** - * Test only method to add the news resources to the stored list in memory - */ + @TestOnly fun addNewsResources(newsResources: List) = cachedNewsResources.update { it + newsResources } } From 254b4642592319538d3f290a058b244f6bb7c708 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Thu, 8 Feb 2024 18:38:51 +0000 Subject: [PATCH 05/22] Update Lifecycle to 2.7.0. Use new LifecycleEventEffect. Change-Id: I71e7aa521f22499fd3f3e9f3ac7c81658f3abc3a --- .../kotlin/AndroidFeatureConventionPlugin.kt | 2 ++ .../feature/bookmarks/BookmarksScreenTest.kt | 31 +++++++++++++++++++ .../feature/bookmarks/BookmarksScreen.kt | 15 ++------- gradle/libs.versions.toml | 3 +- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt index 7a334beb37..6def4e6308 100644 --- a/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidFeatureConventionPlugin.kt @@ -44,6 +44,8 @@ class AndroidFeatureConventionPlugin : Plugin { add("implementation", libs.findLibrary("androidx.hilt.navigation.compose").get()) add("implementation", libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) add("implementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get()) + + add("androidTestImplementation", libs.findLibrary("androidx.lifecycle.runtimeTesting").get()) } } } diff --git a/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt index 3d684f9d1a..197a447fe6 100644 --- a/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt +++ b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt @@ -17,6 +17,8 @@ package com.google.samples.apps.nowinandroid.feature.bookmarks import androidx.activity.ComponentActivity +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.test.assertCountEquals import androidx.compose.ui.test.assertHasClickAction import androidx.compose.ui.test.filter @@ -30,8 +32,11 @@ import androidx.compose.ui.test.onNodeWithContentDescription import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.compose.ui.test.performScrollToNode +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.testing.TestLifecycleOwner import com.google.samples.apps.nowinandroid.core.testing.data.userNewsResourcesTestData import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState +import kotlinx.coroutines.test.runTest import org.junit.Rule import org.junit.Test import kotlin.test.assertEquals @@ -166,4 +171,30 @@ class BookmarksScreenTest { ) .assertExists() } + + @Test + fun feed_whenLifecycleStops_undoBookmarkedStateIsCleared() = runTest { + + var undoStateCleared = false + val testLifecycleOwner = TestLifecycleOwner(initialState = Lifecycle.State.STARTED) + + composeTestRule.setContent { + CompositionLocalProvider(LocalLifecycleOwner provides testLifecycleOwner){ + BookmarksScreen( + feedState = NewsFeedUiState.Success(emptyList()), + onShowSnackbar = { _, _ -> false }, + removeFromBookmarks = {}, + onTopicClick = {}, + onNewsResourceViewed = {}, + clearUndoState = { + undoStateCleared = true + } + ) + } + } + + assertEquals(false, undoStateCleared) + testLifecycleOwner.handleLifecycleEvent(event = Lifecycle.Event.ON_STOP) + assertEquals(true, undoStateCleared) + } } diff --git a/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt b/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt index 5b54db7cdd..7c229c5ea5 100644 --- a/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt +++ b/feature/bookmarks/src/main/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreen.kt @@ -42,14 +42,12 @@ import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridS import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -60,7 +58,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.Lifecycle -import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.compose.LifecycleEventEffect import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.DraggableScrollbar @@ -128,15 +126,8 @@ internal fun BookmarksScreen( } } - val lifecycleOwner = LocalLifecycleOwner.current - DisposableEffect(lifecycleOwner) { - val observer = LifecycleEventObserver { _, event -> - if (event == Lifecycle.Event.ON_STOP) { - clearUndoState() - } - } - lifecycleOwner.lifecycle.addObserver(observer) - onDispose { lifecycleOwner.lifecycle.removeObserver(observer) } + LifecycleEventEffect(Lifecycle.Event.ON_STOP) { + clearUndoState() } when (feedState) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 795510bcea..f0b5aa6422 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ androidxCoreSplashscreen = "1.0.1" androidxDataStore = "1.0.0" androidxEspresso = "3.5.1" androidxHiltNavigationCompose = "1.0.0" -androidxLifecycle = "2.6.2" +androidxLifecycle = "2.7.0" androidxMacroBenchmark = "1.2.2" androidxMetrics = "1.0.0-alpha04" androidxNavigation = "2.7.4" @@ -82,6 +82,7 @@ androidx-core-splashscreen = { group = "androidx.core", name = "core-splashscree androidx-dataStore-core = { group = "androidx.datastore", name = "datastore", version.ref = "androidxDataStore" } androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "androidxHiltNavigationCompose" } androidx-lifecycle-runtimeCompose = { group = "androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidxLifecycle" } +androidx-lifecycle-runtimeTesting = { group = "androidx.lifecycle", name = "lifecycle-runtime-testing", version.ref = "androidxLifecycle" } androidx-lifecycle-viewModelCompose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidxLifecycle" } androidx-metrics = { group = "androidx.metrics", name = "metrics-performance", version.ref = "androidxMetrics" } androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "androidxNavigation" } From 2ad48843f6dbb5eee54c60b1a5600597dc7f23a0 Mon Sep 17 00:00:00 2001 From: Don Turner Date: Mon, 19 Feb 2024 11:46:22 +0000 Subject: [PATCH 06/22] Fix formatting Change-Id: I674d32bc0f1921c431717dbf0f41a74f632322b3 --- .../nowinandroid/feature/bookmarks/BookmarksScreenTest.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt index 197a447fe6..40f54e4a77 100644 --- a/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt +++ b/feature/bookmarks/src/androidTest/kotlin/com/google/samples/apps/nowinandroid/feature/bookmarks/BookmarksScreenTest.kt @@ -174,12 +174,11 @@ class BookmarksScreenTest { @Test fun feed_whenLifecycleStops_undoBookmarkedStateIsCleared() = runTest { - var undoStateCleared = false val testLifecycleOwner = TestLifecycleOwner(initialState = Lifecycle.State.STARTED) composeTestRule.setContent { - CompositionLocalProvider(LocalLifecycleOwner provides testLifecycleOwner){ + CompositionLocalProvider(LocalLifecycleOwner provides testLifecycleOwner) { BookmarksScreen( feedState = NewsFeedUiState.Success(emptyList()), onShowSnackbar = { _, _ -> false }, @@ -188,7 +187,7 @@ class BookmarksScreenTest { onNewsResourceViewed = {}, clearUndoState = { undoStateCleared = true - } + }, ) } } From 08d8f1393a5df2b320d3bfe886dcf6c5bec2a9dc Mon Sep 17 00:00:00 2001 From: dturner Date: Mon, 19 Feb 2024 12:00:16 +0000 Subject: [PATCH 07/22] =?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 --- .../prodReleaseRuntimeClasspath.txt | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/app/dependencies/prodReleaseRuntimeClasspath.txt b/app/dependencies/prodReleaseRuntimeClasspath.txt index 759fba4a60..eaeff771ac 100644 --- a/app/dependencies/prodReleaseRuntimeClasspath.txt +++ b/app/dependencies/prodReleaseRuntimeClasspath.txt @@ -71,19 +71,20 @@ androidx.hilt:hilt-navigation:1.0.0 androidx.hilt:hilt-work:1.1.0 androidx.interpolator:interpolator:1.0.0 androidx.legacy:legacy-support-core-utils:1.0.0 -androidx.lifecycle:lifecycle-common-java8:2.6.2 -androidx.lifecycle:lifecycle-common:2.6.2 -androidx.lifecycle:lifecycle-livedata-core:2.6.2 -androidx.lifecycle:lifecycle-livedata:2.6.2 -androidx.lifecycle:lifecycle-process:2.6.2 -androidx.lifecycle:lifecycle-runtime-compose:2.6.2 -androidx.lifecycle:lifecycle-runtime-ktx:2.6.2 -androidx.lifecycle:lifecycle-runtime:2.6.2 -androidx.lifecycle:lifecycle-service:2.6.2 -androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2 -androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2 -androidx.lifecycle:lifecycle-viewmodel-savedstate:2.6.2 -androidx.lifecycle:lifecycle-viewmodel:2.6.2 +androidx.lifecycle:lifecycle-common-java8:2.7.0 +androidx.lifecycle:lifecycle-common:2.7.0 +androidx.lifecycle:lifecycle-livedata-core-ktx:2.7.0 +androidx.lifecycle:lifecycle-livedata-core:2.7.0 +androidx.lifecycle:lifecycle-livedata:2.7.0 +androidx.lifecycle:lifecycle-process:2.7.0 +androidx.lifecycle:lifecycle-runtime-compose:2.7.0 +androidx.lifecycle:lifecycle-runtime-ktx:2.7.0 +androidx.lifecycle:lifecycle-runtime:2.7.0 +androidx.lifecycle:lifecycle-service:2.7.0 +androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0 +androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0 +androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0 +androidx.lifecycle:lifecycle-viewmodel:2.7.0 androidx.loader:loader:1.0.0 androidx.localbroadcastmanager:localbroadcastmanager:1.0.0 androidx.metrics:metrics-performance:1.0.0-alpha04 From dba36d694fbd9fd974793a69f6f3e59669b99a21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jose=20Alc=C3=A9rreca?= Date: Mon, 19 Feb 2024 19:18:50 +0100 Subject: [PATCH 08/22] [CI] Adds free-disk-space action to fix CI (#1219) * [CI] Adds free-disk-space action to fix CI --- .github/workflows/Build.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/Build.yaml b/.github/workflows/Build.yaml index f8595f221c..5f501b6c0a 100644 --- a/.github/workflows/Build.yaml +++ b/.github/workflows/Build.yaml @@ -147,6 +147,17 @@ jobs: api-level: [26, 30] steps: + - name: Delete unnecessary tools 🔧 + uses: jlumbroso/free-disk-space@v1.3.1 + with: + android: false # Don't remove Android tools + tool-cache: true # Remove image tool cache - rm -rf "$AGENT_TOOLSDIRECTORY" + dotnet: true # rm -rf /usr/share/dotnet + haskell: true # rm -rf /opt/ghc... + swap-storage: true # rm -f /mnt/swapfile (4GiB) + docker-images: false # Takes 16s, enable if needed in the future + large-packages: false # includes google-cloud-sdk and it's slow + - name: Enable KVM group perms run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules From 63835eb5c57bff0e29ea911416097e207e08189b Mon Sep 17 00:00:00 2001 From: lihenggui Date: Tue, 20 Feb 2024 16:57:26 -0800 Subject: [PATCH 09/22] Fix typos in sq file --- .../nowinandroid/core/database/dao/NewsResourceDao.kt | 8 ++++++-- .../apps/nowinandroid/core/database/NewsResource.sq | 2 +- .../core/database/NewsResourceTopicCrossRef.sq | 4 ++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt index a49e44ca35..73e27ef387 100644 --- a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt +++ b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDao.kt @@ -126,8 +126,12 @@ class NewsResourceDao(db: NiaDatabase, private val dispatcher: CoroutineDispatch suspend fun insertOrIgnoreTopicCrossRefEntities( newsResourceTopicCrossReferences: List, ) { - // TODO Consider removing cross references -// query.insertOrIgnoreNewsResourceTopicCrossRefs(newsResourceTopicCrossReferences) + newsResourceTopicCrossReferences.forEach { + query.insertOrIgnoreTopicCrossRefEntitiy( + news_resource_id = it.newsResourceId, + topic_id = it.topicId, + ) + } } /** diff --git a/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResource.sq b/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResource.sq index 85cef42ccf..73c687c297 100644 --- a/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResource.sq +++ b/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResource.sq @@ -59,7 +59,7 @@ header_image_url = excluded.header_image_url, publish_date = excluded.publish_date, type = excluded.type; -insertOrIgnoreTopicCrossRefEntities: +insertOrIgnoreTopicCrossRefEntitiy: INSERT OR IGNORE INTO news_resources_topics (news_resource_id, topic_id) VALUES (?, ?); diff --git a/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResourceTopicCrossRef.sq b/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResourceTopicCrossRef.sq index 2100a8a3c3..d8f900b9e9 100644 --- a/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResourceTopicCrossRef.sq +++ b/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResourceTopicCrossRef.sq @@ -6,6 +6,6 @@ CREATE TABLE IF NOT EXISTS news_resources_topics ( FOREIGN KEY (topic_id) REFERENCES topic(id) ON DELETE CASCADE ); -CREATE INDEX idx_news_resource_id ON news_resource_topic(news_resource_id); +CREATE INDEX idx_news_resource_id ON news_resources_topics(news_resource_id); -CREATE INDEX idx_topic_id ON news_resource_topic(topic_id); +CREATE INDEX idx_topic_id ON news_resources_topics(topic_id); From cdc9336d8bd40bdc36979564f93c80a68f0cbb91 Mon Sep 17 00:00:00 2001 From: lihenggui Date: Tue, 20 Feb 2024 17:26:17 -0800 Subject: [PATCH 10/22] Allow foreign keys --- .../apps/nowinandroid/core/database/DriverModule.kt | 12 +++++++++++- .../nowinandroid/core/database/BaseTest.android.kt | 6 +++++- .../apps/nowinandroid/core/database/DriverModule.kt | 6 +++++- .../apps/nowinandroid/core/database/BaseTest.jvm.kt | 6 +++++- .../apps/nowinandroid/core/database/DriverModule.kt | 12 +++++++++++- .../nowinandroid/core/database/BaseTest.native.kt | 11 ++++++++++- 6 files changed, 47 insertions(+), 6 deletions(-) diff --git a/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt b/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt index 4e703461da..932de70c68 100644 --- a/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt +++ b/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt @@ -17,6 +17,7 @@ package com.google.samples.apps.nowinandroid.core.database import android.content.Context +import androidx.sqlite.db.SupportSQLiteDatabase import app.cash.sqldelight.async.coroutines.synchronous import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlDriver @@ -32,6 +33,15 @@ actual class DriverModule(private val context: Context) { actual suspend fun provideDbDriver( schema: SqlSchema>, ): SqlDriver { - return AndroidSqliteDriver(schema.synchronous(), context, "nia-database.db") + val synchronousSchema = schema.synchronous() + return AndroidSqliteDriver(schema = synchronousSchema, + context = context, + name = "nia-database.db", + callback = object : AndroidSqliteDriver.Callback(synchronousSchema) { + override fun onOpen(db: SupportSQLiteDatabase) { + db.setForeignKeyConstraintsEnabled(true) + } + } + ) } } diff --git a/core/database/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.android.kt b/core/database/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.android.kt index 56e63a063f..14e1788774 100644 --- a/core/database/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.android.kt +++ b/core/database/src/androidUnitTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.android.kt @@ -18,8 +18,12 @@ package com.google.samples.apps.nowinandroid.core.database import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver +import java.util.Properties actual suspend fun createDriver(): SqlDriver { - return JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY) + return JdbcSqliteDriver( + url = JdbcSqliteDriver.IN_MEMORY, + properties = Properties().apply { put("foreign_keys", "true") }, + ) .also { NiaDatabase.Schema.create(it).await() } } diff --git a/core/database/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt b/core/database/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt index 8b8e797dc0..d69966a127 100644 --- a/core/database/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt +++ b/core/database/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt @@ -21,13 +21,17 @@ import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.db.SqlSchema import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver import me.tatarka.inject.annotations.Provides +import java.util.Properties actual class DriverModule { @Provides actual suspend fun provideDbDriver( schema: SqlSchema>, ): SqlDriver { - return JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY) + return JdbcSqliteDriver( + url = JdbcSqliteDriver.IN_MEMORY, + properties = Properties().apply { put("foreign_keys", "true") }, + ) .also { schema.create(it).await() } } } diff --git a/core/database/src/jvmTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.jvm.kt b/core/database/src/jvmTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.jvm.kt index a77aa23498..d650bbf6f8 100644 --- a/core/database/src/jvmTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.jvm.kt +++ b/core/database/src/jvmTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.jvm.kt @@ -19,8 +19,12 @@ package com.google.samples.apps.nowinandroid.core.database import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver import com.google.samples.apps.nowinandroid.core.database.NiaDatabase.Companion.Schema +import java.util.Properties actual suspend fun createDriver(): SqlDriver { - return JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY) + return JdbcSqliteDriver( + url = JdbcSqliteDriver.IN_MEMORY, + properties = Properties().apply { put("foreign_keys", "true") }, + ) .also { Schema.create(it).await() } } diff --git a/core/database/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt b/core/database/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt index cd54d58d2f..311c0e4707 100644 --- a/core/database/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt +++ b/core/database/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt @@ -21,6 +21,7 @@ import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.db.SqlSchema import app.cash.sqldelight.driver.native.NativeSqliteDriver +import co.touchlab.sqliter.DatabaseConfiguration import me.tatarka.inject.annotations.Provides actual class DriverModule { @@ -29,6 +30,15 @@ actual class DriverModule { actual suspend fun provideDbDriver( schema: SqlSchema>, ): SqlDriver { - return NativeSqliteDriver(schema.synchronous(), "nia-database.db") + val synchronousSchema = schema.synchronous() + return NativeSqliteDriver( + schema = synchronousSchema, + name = "nia-database.db", + onConfiguration = { config: DatabaseConfiguration -> + config.copy( + extendedConfig = DatabaseConfiguration.Extended(foreignKeyConstraints = true), + ) + }, + ) } } diff --git a/core/database/src/nativeTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.native.kt b/core/database/src/nativeTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.native.kt index d7b6b1c9db..ae6d56d817 100644 --- a/core/database/src/nativeTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.native.kt +++ b/core/database/src/nativeTest/kotlin/com/google/samples/apps/nowinandroid/core/database/BaseTest.native.kt @@ -19,8 +19,17 @@ package com.google.samples.apps.nowinandroid.core.database import app.cash.sqldelight.async.coroutines.synchronous import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.driver.native.NativeSqliteDriver +import co.touchlab.sqliter.DatabaseConfiguration import com.google.samples.apps.nowinandroid.core.database.NiaDatabase.Companion.Schema actual suspend fun createDriver(): SqlDriver { - return NativeSqliteDriver(Schema.synchronous(), "nia-database-test.db") + return NativeSqliteDriver( + schema = Schema.synchronous(), + name = "nia-database-test.db", + onConfiguration = { config: DatabaseConfiguration -> + config.copy( + extendedConfig = DatabaseConfiguration.Extended(foreignKeyConstraints = true), + ) + }, + ) } From 6b0a2a38ee2a229eff484c447f0998a4a72f22bd Mon Sep 17 00:00:00 2001 From: lihenggui Date: Tue, 20 Feb 2024 17:43:52 -0800 Subject: [PATCH 11/22] Add sqljs-config.js --- core/database/build.gradle.kts | 3 +- core/database/karma.config.d/sqljs-config.js | 30 +++++++++++++++++++ .../database/webpack.config.d/sqljs-config.js | 16 ++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 core/database/karma.config.d/sqljs-config.js create mode 100644 core/database/webpack.config.d/sqljs-config.js diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index 27cf0206bc..c231016a5e 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -50,7 +50,8 @@ kotlin { } jsMain.dependencies { implementation(libs.sqldelight.webworker.driver) - implementation(npm("sql.js", "1.6.2")) + implementation(npm("@cashapp/sqldelight-sqljs-worker", "2.0.1")) + implementation(npm("sql.js", "1.8.0")) implementation(devNpm("copy-webpack-plugin", "9.1.0")) } commonTest.dependencies { diff --git a/core/database/karma.config.d/sqljs-config.js b/core/database/karma.config.d/sqljs-config.js new file mode 100644 index 0000000000..ef2be34dfb --- /dev/null +++ b/core/database/karma.config.d/sqljs-config.js @@ -0,0 +1,30 @@ +const path = require("path"); +const os = require("os"); +const dist = path.resolve("../../node_modules/sql.js/dist/") +const wasm = path.join(dist, "sql-wasm.wasm") + +config.files.push({ + pattern: wasm, + served: true, + watched: false, + included: false, + nocache: false, +}); + +config.proxies["/sql-wasm.wasm"] = `/absolute${wasm}` + +// Adapted from: https://github.com/ryanclark/karma-webpack/issues/498#issuecomment-790040818 +const output = { + path: path.join(os.tmpdir(), '_karma_webpack_') + Math.floor(Math.random() * 1000000), +} +config.set({ + webpack: {...config.webpack, output} +}); +config.files.push({ + pattern: `${output.path}/**/*`, + watched: false, + included: false, +}); + +// TODO: Figure out why on earth this is necessary. Presumably a karma-webpack bug??? +delete config.webpack.optimization; diff --git a/core/database/webpack.config.d/sqljs-config.js b/core/database/webpack.config.d/sqljs-config.js new file mode 100644 index 0000000000..03f7010735 --- /dev/null +++ b/core/database/webpack.config.d/sqljs-config.js @@ -0,0 +1,16 @@ +config.resolve = { + fallback: { + fs: false, + path: false, + crypto: false, + } +}; + +const CopyWebpackPlugin = require('copy-webpack-plugin'); +config.plugins.push( + new CopyWebpackPlugin({ + patterns: [ + '../../node_modules/sql.js/dist/sql-wasm.wasm' + ] + }) +); From b480d6052029d5c55ba7b5253f5180ffc1632cee Mon Sep 17 00:00:00 2001 From: lihenggui Date: Tue, 20 Feb 2024 18:18:38 -0800 Subject: [PATCH 12/22] Fix SQL grammar errors --- .../apps/nowinandroid/core/database/NewsResourceFts.sq | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResourceFts.sq b/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResourceFts.sq index 59795c2e40..d951d917ba 100644 --- a/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResourceFts.sq +++ b/core/database/src/commonMain/sqldelight/com/google/samples/apps/nowinandroid/core/database/NewsResourceFts.sq @@ -2,18 +2,18 @@ CREATE VIRTUAL TABLE news_resource_fts USING FTS4( news_resource_id TEXT NOT NULL, title TEXT NOT NULL, - content TEXT NOT NULL, + content TEXT NOT NULL ); -- Triggers to keep the FTS index up to date. CREATE TRIGGER news_resource_ai AFTER INSERT ON news_resource BEGIN INSERT INTO news_resource_fts (rowid, news_resource_id, title, content) VALUES (new.rowid, new.id, new.title, new.content); END; CREATE TRIGGER news_resource_ad AFTER DELETE ON news_resource BEGIN - INSERT INTO news_resource_fts (news_resource_fts, rowid, news_resource_id, title, content) VALUES ('delete', old.rowid, old.id, old.title, old.content); + DELETE FROM news_resource_fts WHERE news_resource_id = old.id; END; CREATE TRIGGER news_resource_au AFTER UPDATE ON news_resource BEGIN - INSERT INTO news_resource_fts (news_resource_fts, rowid, news_resource_id, title, content) VALUES ('delete', old.rowid, old.id, old.title, old.content); - INSERT INTO news_resource_fts (rowid, news_resource_id, title, content) VALUES (new.rowid, new.id, new.title, new.content); + DELETE FROM news_resource_fts WHERE news_resource_id = old.id; + INSERT INTO news_resource_fts (news_resource_id, title, content) VALUES (new.id, new.title, new.content); END; insert: From 9812871847fd6278e2297b6684a2deb255267ff3 Mon Sep 17 00:00:00 2001 From: lihenggui Date: Tue, 20 Feb 2024 18:19:22 -0800 Subject: [PATCH 13/22] kotlinUpgradeYarnLock --- kotlin-js-store/yarn.lock | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 366040fcd9..94c5abfdb1 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@cashapp/sqldelight-sqljs-worker@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@cashapp/sqldelight-sqljs-worker/-/sqldelight-sqljs-worker-2.0.1.tgz#81964d4954fb24ba4e5019343ea20fba27a8cac4" + integrity sha512-wzOjAverdz1F8eiAI4fP3WObu1+geXbLSpX03WIXoDzmJ2XS2AByW4x1CpGnGZutX3AfjyqpcXL4wv9ZOH1aKQ== + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -1789,10 +1794,10 @@ source-map@^0.6.0, source-map@^0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -sql.js@1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/sql.js/-/sql.js-1.6.2.tgz#7fb70ff68089434826a39b8f5afb2170d682eb3f" - integrity sha512-9iucI5fXQa+Gspeqf/BNB20PxJIn5LhXDt4mjXoFPqXdR+NqtFs15SdKpSIJ6s529aGL9zFR9p2eSCIEiMsNGA== +sql.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/sql.js/-/sql.js-1.8.0.tgz#cb45d957e17a2239662fe2f614c9b678990867a6" + integrity sha512-3HD8pSkZL+5YvYUI8nlvNILs61ALqq34xgmF+BHpqxe68yZIJ1H+sIVIODvni25+CcxHUxDyrTJUL0lE/m7afw== statuses@2.0.1: version "2.0.1" From 8bc97082fb122430a65e48d3715b7632652184f5 Mon Sep 17 00:00:00 2001 From: lihenggui Date: Tue, 20 Feb 2024 19:35:06 -0800 Subject: [PATCH 14/22] Remove js support --- .../apps/nowinandroid/KotlinMultiplatform.kt | 29 ++++++++++--------- core/database/build.gradle.kts | 11 +++++++ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt index cc99af1f74..e37a3b5679 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt @@ -37,20 +37,21 @@ internal fun Project.configureKotlinMultiplatform() { jvm() androidTarget() - js { - browser { - testTask { - useKarma { - useChromeHeadless() - } - } - } - compilations.configureEach { - kotlinOptions { - moduleKind = "umd" - } - } - } +// UninitializedPropertyAccessException: lateinit property newsResourceDao has not been initialized +// js { +// browser { +// testTask { +// useKarma { +// useChromeHeadless() +// } +// } +// } +// compilations.configureEach { +// kotlinOptions { +// moduleKind = "umd" +// } +// } +// } // tier 1 linuxX64() diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index c231016a5e..e10ac7c309 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -70,3 +70,14 @@ sqldelight { } } } + +// Workaround yarn concurrency issue - https://youtrack.jetbrains.com/issue/KT-43320 +tasks.withType() + .configureEach { + args.addAll( + listOf( + "--mutex", + "file:${file("../build/.yarn-mutex")}", + ), + ) + } From 4dc3fa965397b45c1987a2486e465b72d53499d1 Mon Sep 17 00:00:00 2001 From: lihenggui Date: Tue, 20 Feb 2024 20:30:26 -0800 Subject: [PATCH 15/22] Make JS target work --- .../apps/nowinandroid/KotlinMultiplatform.kt | 29 +++--- .../core/database/dao/NewsResourceDaoTest.kt | 92 +++++++++++-------- 2 files changed, 66 insertions(+), 55 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt index e37a3b5679..cc99af1f74 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt @@ -37,21 +37,20 @@ internal fun Project.configureKotlinMultiplatform() { jvm() androidTarget() -// UninitializedPropertyAccessException: lateinit property newsResourceDao has not been initialized -// js { -// browser { -// testTask { -// useKarma { -// useChromeHeadless() -// } -// } -// } -// compilations.configureEach { -// kotlinOptions { -// moduleKind = "umd" -// } -// } -// } + js { + browser { + testTask { + useKarma { + useChromeHeadless() + } + } + } + compilations.configureEach { + kotlinOptions { + moduleKind = "umd" + } + } + } // tier 1 linuxX64() diff --git a/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt b/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt index 8b873e8cb0..3e09495ed5 100644 --- a/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt +++ b/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt @@ -31,19 +31,22 @@ import kotlin.test.Test import kotlin.test.assertEquals class NewsResourceDaoTest { - private lateinit var newsResourceDao: NewsResourceDao private lateinit var topicDao: TopicDao - @BeforeTest - fun setup() = runTest { - val db = NiaDatabase(createDriver()) - newsResourceDao = NewsResourceDao(db, Dispatchers.Unconfined) - topicDao = TopicDao(db, Dispatchers.Unconfined) - } + // BeforeTest seems not working properly in Kotlin JS + // UninitializedPropertyAccessException: lateinit property newsResourceDao has not been initialized +// @BeforeTest +// fun setup() = runTest { +// val db = NiaDatabase(createDriver()) +// newsResourceDao = NewsResourceDao(db, Dispatchers.Unconfined) +// topicDao = TopicDao(db, Dispatchers.Unconfined) +// } @Test fun newsResourceDao_fetches_items_by_descending_publish_date() = runTest { + val db = NiaDatabase(createDriver()) + val newsResourceDao = NewsResourceDao(db, Dispatchers.Unconfined) val newsResourceEntities = listOf( testNewsResource( id = "0", @@ -79,6 +82,8 @@ class NewsResourceDaoTest { @Test fun newsResourceDao_filters_items_by_news_ids_by_descending_publish_date() = runTest { + val db = NiaDatabase(createDriver()) + val newsResourceDao = NewsResourceDao(db, Dispatchers.Unconfined) val newsResourceEntities = listOf( testNewsResource( id = "0", @@ -117,6 +122,9 @@ class NewsResourceDaoTest { @Test fun newsResourceDao_filters_items_by_topic_ids_by_descending_publish_date() = runTest { + val db = NiaDatabase(createDriver()) + val newsResourceDao = NewsResourceDao(db, Dispatchers.Unconfined) + val topicDao = TopicDao(db, Dispatchers.Unconfined) val topicEntities = listOf( testTopicEntity( id = "1", @@ -177,6 +185,9 @@ class NewsResourceDaoTest { @Test fun newsResourceDao_filters_items_by_news_and_topic_ids_by_descending_publish_date() = runTest { + val db = NiaDatabase(createDriver()) + val newsResourceDao = NewsResourceDao(db, Dispatchers.Unconfined) + val topicDao = TopicDao(db, Dispatchers.Unconfined) val topicEntities = listOf( testTopicEntity( id = "1", @@ -238,42 +249,43 @@ class NewsResourceDaoTest { } @Test - fun newsResourceDao_deletes_items_by_ids() = - runTest { - val newsResourceEntities = listOf( - testNewsResource( - id = "0", - millisSinceEpoch = 0, - ), - testNewsResource( - id = "1", - millisSinceEpoch = 3, - ), - testNewsResource( - id = "2", - millisSinceEpoch = 1, - ), - testNewsResource( - id = "3", - millisSinceEpoch = 2, - ), - ) - newsResourceDao.upsertNewsResources(newsResourceEntities) + fun newsResourceDao_deletes_items_by_ids() = runTest { + val db = NiaDatabase(createDriver()) + val newsResourceDao = NewsResourceDao(db, Dispatchers.Unconfined) + val newsResourceEntities = listOf( + testNewsResource( + id = "0", + millisSinceEpoch = 0, + ), + testNewsResource( + id = "1", + millisSinceEpoch = 3, + ), + testNewsResource( + id = "2", + millisSinceEpoch = 1, + ), + testNewsResource( + id = "3", + millisSinceEpoch = 2, + ), + ) + newsResourceDao.upsertNewsResources(newsResourceEntities) - val (toDelete, toKeep) = newsResourceEntities.partition { it.id.toInt() % 2 == 0 } + val (toDelete, toKeep) = newsResourceEntities.partition { it.id.toInt() % 2 == 0 } - newsResourceDao.deleteNewsResources( - toDelete.map(NewsResourceEntity::id), - ) + newsResourceDao.deleteNewsResources( + toDelete.map(NewsResourceEntity::id), + ) - assertEquals( - toKeep.map(NewsResourceEntity::id) - .toSet(), - newsResourceDao.getNewsResources().first() - .map { it.entity.id } - .toSet(), - ) - } + assertEquals( + toKeep.map(NewsResourceEntity::id) + .toSet(), + newsResourceDao.getNewsResources().first() + .map { it.entity.id } + .toSet(), + ) + } } private fun testTopicEntity( From 29c3038e7058ba7cf8a1eb49873334096842df31 Mon Sep 17 00:00:00 2001 From: lihenggui Date: Wed, 21 Feb 2024 16:12:40 -0800 Subject: [PATCH 16/22] Add coroutine dependency --- core/database/build.gradle.kts | 4 ++++ gradle/libs.versions.toml | 1 + 2 files changed, 5 insertions(+) diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index e10ac7c309..236891533d 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -33,6 +33,7 @@ kotlin { commonMain.dependencies { api(projects.core.model) implementation(libs.kotlinx.datetime) + implementation(libs.kotlinx.coroutines.core) implementation(libs.sqldelight.coroutines.extensions) implementation(libs.sqldelight.primitive.adapters) } @@ -45,6 +46,9 @@ kotlin { nativeMain.dependencies { implementation(libs.sqldelight.native.driver) } + nativeTest.dependencies { + implementation(libs.sqldelight.sqlite.driver) + } jvmMain.dependencies { implementation(libs.sqldelight.sqlite.driver) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fedf183428..8fff6645de 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -130,6 +130,7 @@ hilt-ext-compiler = { group = "androidx.hilt", name = "hilt-compiler", version.r hilt-ext-work = { group = "androidx.hilt", name = "hilt-work", version.ref = "hiltExt" } javax-inject = { module = "javax.inject:javax.inject", version = "1" } kotlin-stdlib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" } +kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinxCoroutines" } kotlinx-coroutines-guava = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-guava", version.ref = "kotlinxCoroutines" } kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" } kotlinx-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version.ref = "kotlinxDatetime" } From c5521ce89b1774bf532c071be6e158fcda8c0ad2 Mon Sep 17 00:00:00 2001 From: lihenggui Date: Wed, 21 Feb 2024 17:09:46 -0800 Subject: [PATCH 17/22] Make :core:common as a multiplatform library --- core/common/build.gradle.kts | 21 ++++++--- .../{main => androidMain}/AndroidManifest.xml | 0 .../core_common_ic_nia_notification.xml | 0 .../core_common_ic_nia_notification.png | Bin .../core_common_ic_nia_notification.png | Bin .../core_common_ic_nia_notification.png | Bin .../core_common_ic_nia_notification.png | Bin .../network/di/CoroutineScopeComponent.kt} | 23 +++++---- .../core/network/di/DispatchersComponent.kt} | 22 ++++----- .../apps/nowinandroid/core/result/Result.kt | 0 .../nowinandroid/core/result/ResultKtTest.kt | 4 +- .../core/network/di/CoroutineScopesModule.kt | 44 ------------------ core/database/build.gradle.kts | 3 -- .../core/testing/di/TestDispatchersModule.kt | 4 +- 14 files changed, 39 insertions(+), 82 deletions(-) rename core/common/src/{main => androidMain}/AndroidManifest.xml (100%) rename core/common/src/{main => androidMain}/res/drawable-anydpi-v24/core_common_ic_nia_notification.xml (100%) rename core/common/src/{main => androidMain}/res/drawable-hdpi/core_common_ic_nia_notification.png (100%) rename core/common/src/{main => androidMain}/res/drawable-mdpi/core_common_ic_nia_notification.png (100%) rename core/common/src/{main => androidMain}/res/drawable-xhdpi/core_common_ic_nia_notification.png (100%) rename core/common/src/{main => androidMain}/res/drawable-xxhdpi/core_common_ic_nia_notification.png (100%) rename core/common/src/{main/kotlin/com/google/samples/apps/nowinandroid/core/network/NiaDispatchers.kt => commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopeComponent.kt} (51%) rename core/common/src/{main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersModule.kt => commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersComponent.kt} (56%) rename core/common/src/{main => commonMain}/kotlin/com/google/samples/apps/nowinandroid/core/result/Result.kt (100%) rename core/common/src/{test => commonTest}/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt (95%) delete mode 100644 core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 51ae627dc0..14eadc7036 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -14,16 +14,23 @@ * limitations under the License. */ plugins { - alias(libs.plugins.nowinandroid.android.library) + alias(libs.plugins.nowinandroid.kmp.library) + alias(libs.plugins.nowinandroid.kotlin.inject) alias(libs.plugins.nowinandroid.android.library.jacoco) - alias(libs.plugins.nowinandroid.android.hilt) } android { namespace = "com.google.samples.apps.nowinandroid.core.common" } - -dependencies { - testImplementation(libs.kotlinx.coroutines.test) - testImplementation(libs.turbine) -} \ No newline at end of file +kotlin { + sourceSets { + commonMain.dependencies { + implementation(libs.kotlinx.coroutines.core) + } + commonTest.dependencies { + implementation(libs.kotlin.test) + implementation(libs.turbine) + implementation(libs.kotlinx.coroutines.test) + } + } +} diff --git a/core/common/src/main/AndroidManifest.xml b/core/common/src/androidMain/AndroidManifest.xml similarity index 100% rename from core/common/src/main/AndroidManifest.xml rename to core/common/src/androidMain/AndroidManifest.xml diff --git a/core/common/src/main/res/drawable-anydpi-v24/core_common_ic_nia_notification.xml b/core/common/src/androidMain/res/drawable-anydpi-v24/core_common_ic_nia_notification.xml similarity index 100% rename from core/common/src/main/res/drawable-anydpi-v24/core_common_ic_nia_notification.xml rename to core/common/src/androidMain/res/drawable-anydpi-v24/core_common_ic_nia_notification.xml diff --git a/core/common/src/main/res/drawable-hdpi/core_common_ic_nia_notification.png b/core/common/src/androidMain/res/drawable-hdpi/core_common_ic_nia_notification.png similarity index 100% rename from core/common/src/main/res/drawable-hdpi/core_common_ic_nia_notification.png rename to core/common/src/androidMain/res/drawable-hdpi/core_common_ic_nia_notification.png diff --git a/core/common/src/main/res/drawable-mdpi/core_common_ic_nia_notification.png b/core/common/src/androidMain/res/drawable-mdpi/core_common_ic_nia_notification.png similarity index 100% rename from core/common/src/main/res/drawable-mdpi/core_common_ic_nia_notification.png rename to core/common/src/androidMain/res/drawable-mdpi/core_common_ic_nia_notification.png diff --git a/core/common/src/main/res/drawable-xhdpi/core_common_ic_nia_notification.png b/core/common/src/androidMain/res/drawable-xhdpi/core_common_ic_nia_notification.png similarity index 100% rename from core/common/src/main/res/drawable-xhdpi/core_common_ic_nia_notification.png rename to core/common/src/androidMain/res/drawable-xhdpi/core_common_ic_nia_notification.png diff --git a/core/common/src/main/res/drawable-xxhdpi/core_common_ic_nia_notification.png b/core/common/src/androidMain/res/drawable-xxhdpi/core_common_ic_nia_notification.png similarity index 100% rename from core/common/src/main/res/drawable-xxhdpi/core_common_ic_nia_notification.png rename to core/common/src/androidMain/res/drawable-xxhdpi/core_common_ic_nia_notification.png diff --git a/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/NiaDispatchers.kt b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopeComponent.kt similarity index 51% rename from core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/NiaDispatchers.kt rename to core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopeComponent.kt index 9c21dd69a5..8bbab228cc 100644 --- a/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/NiaDispatchers.kt +++ b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopeComponent.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Android Open Source Project + * 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. @@ -14,16 +14,19 @@ * limitations under the License. */ -package com.google.samples.apps.nowinandroid.core.network +package com.google.samples.apps.nowinandroid.core.network.di -import javax.inject.Qualifier -import kotlin.annotation.AnnotationRetention.RUNTIME +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.SupervisorJob +import me.tatarka.inject.annotations.Component +import me.tatarka.inject.annotations.Provides -@Qualifier -@Retention(RUNTIME) -annotation class Dispatcher(val niaDispatcher: NiaDispatchers) +typealias ApplicationScope = CoroutineScope -enum class NiaDispatchers { - Default, - IO, +@Component +abstract class CoroutineScopeComponent { + @Provides + fun providesCoroutineScope( + dispatcher: DefaultDispatcher, + ): ApplicationScope = CoroutineScope(SupervisorJob() + dispatcher) } diff --git a/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersModule.kt b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersComponent.kt similarity index 56% rename from core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersModule.kt rename to core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersComponent.kt index 95ec070497..cf3b1583b1 100644 --- a/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersModule.kt +++ b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersComponent.kt @@ -16,24 +16,18 @@ package com.google.samples.apps.nowinandroid.core.network.di -import com.google.samples.apps.nowinandroid.core.network.Dispatcher -import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.Default -import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers +import me.tatarka.inject.annotations.Component +import me.tatarka.inject.annotations.Provides -@Module -@InstallIn(SingletonComponent::class) -object DispatchersModule { +typealias DefaultDispatcher = CoroutineDispatcher +typealias IODispatcher = CoroutineDispatcher +@Component +abstract class DispatchersComponent { @Provides - @Dispatcher(IO) - fun providesIODispatcher(): CoroutineDispatcher = Dispatchers.IO + fun providesIODispatcher(): IODispatcher = Dispatchers.Unconfined @Provides - @Dispatcher(Default) - fun providesDefaultDispatcher(): CoroutineDispatcher = Dispatchers.Default + fun providesDefaultDispatcher(): DefaultDispatcher = Dispatchers.Default } diff --git a/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/result/Result.kt b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/result/Result.kt similarity index 100% rename from core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/result/Result.kt rename to core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/result/Result.kt diff --git a/core/common/src/test/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt b/core/common/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt similarity index 95% rename from core/common/src/test/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt rename to core/common/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt index 4f1229e9db..5cd23a9732 100644 --- a/core/common/src/test/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt +++ b/core/common/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/result/ResultKtTest.kt @@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.core.result import app.cash.turbine.test import kotlinx.coroutines.flow.flow import kotlinx.coroutines.test.runTest -import org.junit.Test +import kotlin.test.Test import kotlin.test.assertEquals class ResultKtTest { @@ -38,7 +38,7 @@ class ResultKtTest { when (val errorResult = awaitItem()) { is Result.Error -> assertEquals( "Test Done", - errorResult.exception?.message, + errorResult.exception.message, ) Result.Loading, is Result.Success, diff --git a/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt b/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt deleted file mode 100644 index 6e7ca6bb3d..0000000000 --- a/core/common/src/main/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopesModule.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2023 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.network.di - -import com.google.samples.apps.nowinandroid.core.network.Dispatcher -import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.Default -import dagger.Module -import dagger.Provides -import dagger.hilt.InstallIn -import dagger.hilt.components.SingletonComponent -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.SupervisorJob -import javax.inject.Qualifier -import javax.inject.Singleton - -@Retention(AnnotationRetention.RUNTIME) -@Qualifier -annotation class ApplicationScope - -@Module -@InstallIn(SingletonComponent::class) -internal object CoroutineScopesModule { - @Provides - @Singleton - @ApplicationScope - fun providesCoroutineScope( - @Dispatcher(Default) dispatcher: CoroutineDispatcher, - ): CoroutineScope = CoroutineScope(SupervisorJob() + dispatcher) -} diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index 236891533d..9dad3e0cdc 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -46,9 +46,6 @@ kotlin { nativeMain.dependencies { implementation(libs.sqldelight.native.driver) } - nativeTest.dependencies { - implementation(libs.sqldelight.sqlite.driver) - } jvmMain.dependencies { implementation(libs.sqldelight.sqlite.driver) } diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt index 4f5d15be1d..d4f08d0a22 100644 --- a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt @@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.core.testing.di import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.Default import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO -import com.google.samples.apps.nowinandroid.core.network.di.DispatchersModule +import com.google.samples.apps.nowinandroid.core.network.di.DispatchersComponent import dagger.Module import dagger.Provides import dagger.hilt.components.SingletonComponent @@ -30,7 +30,7 @@ import kotlinx.coroutines.test.TestDispatcher @Module @TestInstallIn( components = [SingletonComponent::class], - replaces = [DispatchersModule::class], + replaces = [DispatchersComponent::class], ) internal object TestDispatchersModule { @Provides From 2f412db367d4c682323a282f1935b1454240e33a Mon Sep 17 00:00:00 2001 From: lihenggui Date: Wed, 21 Feb 2024 17:49:49 -0800 Subject: [PATCH 18/22] Use object to provide implementations --- .../util/ProfileVerifierLogger.kt | 2 +- core/common/build.gradle.kts | 3 +- .../core/di/DispatchersComponent.kt | 28 +++++++++++++++++ .../di/CoroutineScopeComponent.kt | 2 +- .../{network => }/di/DispatchersComponent.kt | 14 ++++----- .../core/di/DispatchersComponent.kt | 30 +++++++++++++++++++ .../core/di/DispatchersComponent.kt | 28 +++++++++++++++++ .../core/di/DispatchersComponent.kt | 30 +++++++++++++++++++ .../core/database/DriverModule.kt | 5 ++-- .../core/database/dao/NewsResourceDaoTest.kt | 1 - .../datastore/test/TestDataStoreModule.kt | 2 +- .../core/datastore/di/DataStoreModule.kt | 2 +- .../core/testing/di/TestDispatchersModule.kt | 2 +- 13 files changed, 132 insertions(+), 17 deletions(-) create mode 100644 core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt rename core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/{network => }/di/CoroutineScopeComponent.kt (94%) rename core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/{network => }/di/DispatchersComponent.kt (66%) create mode 100644 core/common/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt create mode 100644 core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt create mode 100644 core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt diff --git a/app/src/main/java/com/google/samples/apps/nowinandroid/util/ProfileVerifierLogger.kt b/app/src/main/java/com/google/samples/apps/nowinandroid/util/ProfileVerifierLogger.kt index 595166f034..9ca4b33738 100644 --- a/app/src/main/java/com/google/samples/apps/nowinandroid/util/ProfileVerifierLogger.kt +++ b/app/src/main/java/com/google/samples/apps/nowinandroid/util/ProfileVerifierLogger.kt @@ -18,7 +18,7 @@ package com.google.samples.apps.nowinandroid.util import android.util.Log import androidx.profileinstaller.ProfileVerifier -import com.google.samples.apps.nowinandroid.core.network.di.ApplicationScope +import com.google.samples.apps.nowinandroid.core.di.ApplicationScope import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.guava.await import kotlinx.coroutines.launch diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 14eadc7036..cd2b1fbceb 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Android Open Source Project + * 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. @@ -22,6 +22,7 @@ plugins { android { namespace = "com.google.samples.apps.nowinandroid.core.common" } + kotlin { sourceSets { commonMain.dependencies { diff --git a/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt b/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt new file mode 100644 index 0000000000..283f06e50e --- /dev/null +++ b/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -0,0 +1,28 @@ +/* + * 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.di + +import kotlinx.coroutines.Dispatchers +import me.tatarka.inject.annotations.Provides + +actual object DispatchersComponent { + @Provides + actual fun providesIODispatcher(): IODispatcher = Dispatchers.IO + + @Provides + actual fun providesDefaultDispatcher(): DefaultDispatcher = Dispatchers.Default +} diff --git a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopeComponent.kt b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/CoroutineScopeComponent.kt similarity index 94% rename from core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopeComponent.kt rename to core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/CoroutineScopeComponent.kt index 8bbab228cc..c23890dd0c 100644 --- a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/CoroutineScopeComponent.kt +++ b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/CoroutineScopeComponent.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.samples.apps.nowinandroid.core.network.di +package com.google.samples.apps.nowinandroid.core.di import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.SupervisorJob diff --git a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersComponent.kt b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt similarity index 66% rename from core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersComponent.kt rename to core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt index cf3b1583b1..336dc2cc7f 100644 --- a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/network/di/DispatchersComponent.kt +++ b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022 The Android Open Source Project + * 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. @@ -14,20 +14,18 @@ * limitations under the License. */ -package com.google.samples.apps.nowinandroid.core.network.di +package com.google.samples.apps.nowinandroid.core.di import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers -import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Provides typealias DefaultDispatcher = CoroutineDispatcher typealias IODispatcher = CoroutineDispatcher -@Component -abstract class DispatchersComponent { + +expect object DispatchersComponent { @Provides - fun providesIODispatcher(): IODispatcher = Dispatchers.Unconfined + fun providesIODispatcher(): IODispatcher @Provides - fun providesDefaultDispatcher(): DefaultDispatcher = Dispatchers.Default + fun providesDefaultDispatcher(): DefaultDispatcher } diff --git a/core/common/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt b/core/common/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt new file mode 100644 index 0000000000..24bfee6a14 --- /dev/null +++ b/core/common/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -0,0 +1,30 @@ +/* + * 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.di + +import kotlinx.coroutines.Dispatchers +import me.tatarka.inject.annotations.Provides + +actual object DispatchersComponent { + + // TODO Provides an actual IODispatcher + @Provides + actual fun providesIODispatcher(): IODispatcher = Dispatchers.Default + + @Provides + actual fun providesDefaultDispatcher(): DefaultDispatcher = Dispatchers.Default +} diff --git a/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt b/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt new file mode 100644 index 0000000000..283f06e50e --- /dev/null +++ b/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -0,0 +1,28 @@ +/* + * 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.di + +import kotlinx.coroutines.Dispatchers +import me.tatarka.inject.annotations.Provides + +actual object DispatchersComponent { + @Provides + actual fun providesIODispatcher(): IODispatcher = Dispatchers.IO + + @Provides + actual fun providesDefaultDispatcher(): DefaultDispatcher = Dispatchers.Default +} diff --git a/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt b/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt new file mode 100644 index 0000000000..24bfee6a14 --- /dev/null +++ b/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -0,0 +1,30 @@ +/* + * 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.di + +import kotlinx.coroutines.Dispatchers +import me.tatarka.inject.annotations.Provides + +actual object DispatchersComponent { + + // TODO Provides an actual IODispatcher + @Provides + actual fun providesIODispatcher(): IODispatcher = Dispatchers.Default + + @Provides + actual fun providesDefaultDispatcher(): DefaultDispatcher = Dispatchers.Default +} diff --git a/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt b/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt index 932de70c68..0a6a5c34b8 100644 --- a/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt +++ b/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt @@ -34,14 +34,15 @@ actual class DriverModule(private val context: Context) { schema: SqlSchema>, ): SqlDriver { val synchronousSchema = schema.synchronous() - return AndroidSqliteDriver(schema = synchronousSchema, + return AndroidSqliteDriver( + schema = synchronousSchema, context = context, name = "nia-database.db", callback = object : AndroidSqliteDriver.Callback(synchronousSchema) { override fun onOpen(db: SupportSQLiteDatabase) { db.setForeignKeyConstraintsEnabled(true) } - } + }, ) } } diff --git a/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt b/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt index 3e09495ed5..998e0d628a 100644 --- a/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt +++ b/core/database/src/commonTest/kotlin/com/google/samples/apps/nowinandroid/core/database/dao/NewsResourceDaoTest.kt @@ -26,7 +26,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.first import kotlinx.coroutines.test.runTest import kotlinx.datetime.Instant -import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals diff --git a/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt b/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt index 295b2978a3..b4a5cb1828 100644 --- a/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt +++ b/core/datastore-test/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/test/TestDataStoreModule.kt @@ -21,7 +21,7 @@ import androidx.datastore.core.DataStoreFactory import com.google.samples.apps.nowinandroid.core.datastore.UserPreferences import com.google.samples.apps.nowinandroid.core.datastore.UserPreferencesSerializer import com.google.samples.apps.nowinandroid.core.datastore.di.DataStoreModule -import com.google.samples.apps.nowinandroid.core.network.di.ApplicationScope +import com.google.samples.apps.nowinandroid.core.di.ApplicationScope import dagger.Module import dagger.Provides import dagger.hilt.components.SingletonComponent diff --git a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt index 8e0d7d4d89..e54760eada 100644 --- a/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt +++ b/core/datastore/src/main/kotlin/com/google/samples/apps/nowinandroid/core/datastore/di/DataStoreModule.kt @@ -23,9 +23,9 @@ import androidx.datastore.dataStoreFile import com.google.samples.apps.nowinandroid.core.datastore.IntToStringIdsMigration import com.google.samples.apps.nowinandroid.core.datastore.UserPreferences import com.google.samples.apps.nowinandroid.core.datastore.UserPreferencesSerializer +import com.google.samples.apps.nowinandroid.core.di.ApplicationScope 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.di.ApplicationScope import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt index d4f08d0a22..a664d5538f 100644 --- a/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt +++ b/core/testing/src/main/kotlin/com/google/samples/apps/nowinandroid/core/testing/di/TestDispatchersModule.kt @@ -16,10 +16,10 @@ package com.google.samples.apps.nowinandroid.core.testing.di +import com.google.samples.apps.nowinandroid.core.di.DispatchersComponent import com.google.samples.apps.nowinandroid.core.network.Dispatcher import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.Default import com.google.samples.apps.nowinandroid.core.network.NiaDispatchers.IO -import com.google.samples.apps.nowinandroid.core.network.di.DispatchersComponent import dagger.Module import dagger.Provides import dagger.hilt.components.SingletonComponent From db8e99efdcfa768c05054edfe356fd5395737a37 Mon Sep 17 00:00:00 2001 From: lihenggui Date: Wed, 21 Feb 2024 19:28:27 -0800 Subject: [PATCH 19/22] Add platform specific implementation for dispatchers --- .../samples/apps/nowinandroid/core/di/DispatchersComponent.kt | 4 +++- .../samples/apps/nowinandroid/core/di/DispatchersComponent.kt | 2 +- .../samples/apps/nowinandroid/core/di/DispatchersComponent.kt | 4 +++- .../samples/apps/nowinandroid/core/di/DispatchersComponent.kt | 4 +++- .../samples/apps/nowinandroid/core/di/DispatchersComponent.kt | 4 +++- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt b/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt index 283f06e50e..6ae0c863db 100644 --- a/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt +++ b/core/common/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -17,9 +17,11 @@ package com.google.samples.apps.nowinandroid.core.di import kotlinx.coroutines.Dispatchers +import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Provides -actual object DispatchersComponent { +@Component +actual abstract class DispatchersComponent { @Provides actual fun providesIODispatcher(): IODispatcher = Dispatchers.IO diff --git a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt index 336dc2cc7f..3de8179394 100644 --- a/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt +++ b/core/common/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -22,7 +22,7 @@ import me.tatarka.inject.annotations.Provides typealias DefaultDispatcher = CoroutineDispatcher typealias IODispatcher = CoroutineDispatcher -expect object DispatchersComponent { +expect abstract class DispatchersComponent { @Provides fun providesIODispatcher(): IODispatcher diff --git a/core/common/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt b/core/common/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt index 24bfee6a14..e4edc24a7e 100644 --- a/core/common/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt +++ b/core/common/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -17,9 +17,11 @@ package com.google.samples.apps.nowinandroid.core.di import kotlinx.coroutines.Dispatchers +import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Provides -actual object DispatchersComponent { +@Component +actual abstract class DispatchersComponent { // TODO Provides an actual IODispatcher @Provides diff --git a/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt b/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt index 283f06e50e..6ae0c863db 100644 --- a/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt +++ b/core/common/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -17,9 +17,11 @@ package com.google.samples.apps.nowinandroid.core.di import kotlinx.coroutines.Dispatchers +import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Provides -actual object DispatchersComponent { +@Component +actual abstract class DispatchersComponent { @Provides actual fun providesIODispatcher(): IODispatcher = Dispatchers.IO diff --git a/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt b/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt index 24bfee6a14..e4edc24a7e 100644 --- a/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt +++ b/core/common/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/di/DispatchersComponent.kt @@ -17,9 +17,11 @@ package com.google.samples.apps.nowinandroid.core.di import kotlinx.coroutines.Dispatchers +import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Provides -actual object DispatchersComponent { +@Component +actual abstract class DispatchersComponent { // TODO Provides an actual IODispatcher @Provides From 40a9f097868f3d4aa35085101f46636d84f1d95e Mon Sep 17 00:00:00 2001 From: lihenggui Date: Wed, 21 Feb 2024 20:03:48 -0800 Subject: [PATCH 20/22] Use @Component in the database module --- core/database/build.gradle.kts | 1 + .../core/database/DriverModule.kt | 5 +++-- .../core/database/DatabaseModule.kt | 20 +++++++++++++------ .../core/database/DriverModule.kt | 2 +- .../core/database/DriverModule.kt | 4 +++- .../core/database/DriverModule.kt | 4 +++- .../core/database/DriverModule.kt | 4 +++- 7 files changed, 28 insertions(+), 12 deletions(-) diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index 9dad3e0cdc..ac81f18d75 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -32,6 +32,7 @@ kotlin { sourceSets { commonMain.dependencies { api(projects.core.model) + implementation(projects.core.common) implementation(libs.kotlinx.datetime) implementation(libs.kotlinx.coroutines.core) implementation(libs.sqldelight.coroutines.extensions) diff --git a/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt b/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt index 0a6a5c34b8..e5eb5090b0 100644 --- a/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt +++ b/core/database/src/androidMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt @@ -23,11 +23,12 @@ import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.db.SqlSchema import app.cash.sqldelight.driver.android.AndroidSqliteDriver +import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Inject import me.tatarka.inject.annotations.Provides -@Inject -actual class DriverModule(private val context: Context) { +@Component +internal actual abstract class DriverModule(private val context: Context) { @Provides actual suspend fun provideDbDriver( diff --git a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DatabaseModule.kt b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DatabaseModule.kt index d5bddadc4b..7fec4df6f0 100644 --- a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DatabaseModule.kt +++ b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DatabaseModule.kt @@ -22,35 +22,43 @@ import com.google.samples.apps.nowinandroid.core.database.dao.NewsResourceFtsDao import com.google.samples.apps.nowinandroid.core.database.dao.RecentSearchQueryDao import com.google.samples.apps.nowinandroid.core.database.dao.TopicDao import com.google.samples.apps.nowinandroid.core.database.dao.TopicFtsDao +import com.google.samples.apps.nowinandroid.core.di.IODispatcher import kotlinx.coroutines.Dispatchers +import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Provides -internal object DatabaseModule { +@Component +internal abstract class DatabaseModule { @Provides fun providesNiaDatabase(driver: SqlDriver): NiaDatabase = NiaDatabase(driver) @Provides fun providesTopicsDao( database: NiaDatabase, - ): TopicDao = TopicDao(database, Dispatchers.Default) + dispatcher: IODispatcher, + ): TopicDao = TopicDao(database, dispatcher) @Provides fun providesNewsResourceDao( database: NiaDatabase, - ): NewsResourceDao = NewsResourceDao(database, Dispatchers.Default) + dispatcher: IODispatcher, + ): NewsResourceDao = NewsResourceDao(database, dispatcher) @Provides fun providesTopicFtsDao( database: NiaDatabase, - ): TopicFtsDao = TopicFtsDao(database, Dispatchers.Default) + dispatcher: IODispatcher, + ): TopicFtsDao = TopicFtsDao(database, dispatcher) @Provides fun providesNewsResourceFtsDao( database: NiaDatabase, - ): NewsResourceFtsDao = NewsResourceFtsDao(database, Dispatchers.Default) + dispatcher: IODispatcher, + ): NewsResourceFtsDao = NewsResourceFtsDao(database, dispatcher) @Provides fun providesRecentSearchQueryDao( database: NiaDatabase, - ): RecentSearchQueryDao = RecentSearchQueryDao(database, Dispatchers.Default) + dispatcher: IODispatcher, + ): RecentSearchQueryDao = RecentSearchQueryDao(database, dispatcher) } diff --git a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt index aaeaf9b15e..4d79ddaf15 100644 --- a/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt +++ b/core/database/src/commonMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt @@ -21,7 +21,7 @@ import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.db.SqlSchema import me.tatarka.inject.annotations.Provides -expect class DriverModule { +internal expect abstract class DriverModule { @Provides suspend fun provideDbDriver( schema: SqlSchema>, diff --git a/core/database/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt b/core/database/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt index 4a34bc105d..5f1a9c9773 100644 --- a/core/database/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt +++ b/core/database/src/jsMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt @@ -20,10 +20,12 @@ import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.db.SqlSchema import app.cash.sqldelight.driver.worker.WebWorkerDriver +import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Provides import org.w3c.dom.Worker -actual class DriverModule { +@Component +internal actual abstract class DriverModule { @Provides actual suspend fun provideDbDriver( schema: SqlSchema>, diff --git a/core/database/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt b/core/database/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt index d69966a127..220e575d56 100644 --- a/core/database/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt +++ b/core/database/src/jvmMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt @@ -20,10 +20,12 @@ import app.cash.sqldelight.db.QueryResult import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.db.SqlSchema import app.cash.sqldelight.driver.jdbc.sqlite.JdbcSqliteDriver +import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Provides import java.util.Properties -actual class DriverModule { +@Component +internal actual abstract class DriverModule { @Provides actual suspend fun provideDbDriver( schema: SqlSchema>, diff --git a/core/database/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt b/core/database/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt index 311c0e4707..3c4fce8bac 100644 --- a/core/database/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt +++ b/core/database/src/nativeMain/kotlin/com/google/samples/apps/nowinandroid/core/database/DriverModule.kt @@ -22,9 +22,11 @@ import app.cash.sqldelight.db.SqlDriver import app.cash.sqldelight.db.SqlSchema import app.cash.sqldelight.driver.native.NativeSqliteDriver import co.touchlab.sqliter.DatabaseConfiguration +import me.tatarka.inject.annotations.Component import me.tatarka.inject.annotations.Provides -actual class DriverModule { +@Component +internal actual abstract class DriverModule { @Provides actual suspend fun provideDbDriver( From 7099fd47b7094e47b723ed7fef51cf7864be4d5a Mon Sep 17 00:00:00 2001 From: lihenggui Date: Wed, 21 Feb 2024 20:15:47 -0800 Subject: [PATCH 21/22] Add -Xexpect-actual-classes for multiplatform projects --- .../apps/nowinandroid/KotlinMultiplatform.kt | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt index cc99af1f74..5f3fb97c06 100644 --- a/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt +++ b/build-logic/convention/src/main/kotlin/com/google/samples/apps/nowinandroid/KotlinMultiplatform.kt @@ -85,13 +85,12 @@ internal fun Project.configureKotlinMultiplatform() { project.tasks.named("linuxX64Test") { enabled = HostManager.hostIsLinux } project.tasks.named("linkDebugTestLinuxX64") { enabled = HostManager.hostIsLinux } - tasks.withType().configureEach { - kotlinOptions { - freeCompilerArgs = freeCompilerArgs + listOf( - // Suppress warning:'expect'/'actual' classes (including interfaces, objects, - // annotations, enums, and 'actual' typealiases) are in Beta. - "-Xexpect-actual-classes", - ) + // Suppress 'expect'/'actual' classes are in Beta. + targets.configureEach { + compilations.configureEach { + compilerOptions.configure { + freeCompilerArgs.addAll("-Xexpect-actual-classes") + } } } From aea04c31730442f378711b20d1bc892f485ed291 Mon Sep 17 00:00:00 2001 From: lihenggui Date: Wed, 21 Feb 2024 20:16:03 -0800 Subject: [PATCH 22/22] Suppress build target warnings --- gradle.properties | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gradle.properties b/gradle.properties index c0acfeb024..82b326eabd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -39,3 +39,6 @@ kotlin.code.style=official # https://developer.android.com/build/releases/gradle-plugin#default-changes android.defaults.buildfeatures.resvalues=false android.defaults.buildfeatures.shaders=false + +# Suppress: The following Kotlin/Native targets cannot be built on this machine and are disabled +kotlin.native.ignoreDisabledTargets=true \ No newline at end of file