From 999ad8e3c056d69043d1093d94deb15e8dacf2bc Mon Sep 17 00:00:00 2001 From: Aayush Gupta Date: Fri, 16 Oct 2026 19:03:27 +0800 Subject: [PATCH] Migrate tests to use new room v3.x APIs Signed-off-by: Aayush Gupta --- app/build.gradle.kts | 2 + .../newpipe/database/DatabaseMigrationTest.kt | 308 +++++++++--------- .../schabi/newpipe/database/FeedDAOTest.kt | 11 +- .../playlist/LocalPlaylistManagerTest.kt | 2 +- .../schabi/newpipe/testUtil/TestDatabase.kt | 2 +- .../org/schabi/newpipe/database/Migrations.kt | 38 +-- .../local/history/HistoryRecordManager.kt | 16 +- gradle/libs.versions.toml | 5 +- 8 files changed, 192 insertions(+), 192 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d6d09fe46..e99452079 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -326,6 +326,8 @@ dependencies { androidTestImplementation(libs.androidx.runner) androidTestImplementation(libs.androidx.room.testing) androidTestImplementation(libs.assertj.core) + androidTestImplementation(libs.androidx.sqlite.bundled) + androidTestImplementation(libs.jetbrains.coroutines.test) } aboutLibraries { diff --git a/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt b/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt index fd551b7b8..70e47afa0 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/database/DatabaseMigrationTest.kt @@ -1,12 +1,13 @@ package org.schabi.newpipe.database -import android.content.ContentValues -import android.database.sqlite.SQLiteDatabase -import androidx.room.Room -import androidx.room.testing.MigrationTestHelper +import androidx.room3.Room +import androidx.room3.testing.MigrationTestHelper +import androidx.sqlite.driver.bundled.BundledSQLiteDriver +import androidx.sqlite.execSQL import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry +import kotlinx.coroutines.test.runTest import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNull @@ -37,95 +38,84 @@ class DatabaseMigrationTest { private const val DEFAULT_THIRD_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" } + private val instrumentation = InstrumentationRegistry.getInstrumentation() + @get:Rule val testHelper = MigrationTestHelper( - InstrumentationRegistry.getInstrumentation(), - AppDatabase::class.java + instrumentation = instrumentation, + databaseClass = AppDatabase::class, + driver = BundledSQLiteDriver(), + file = instrumentation.targetContext.getDatabasePath(AppDatabase.DATABASE_NAME) ) @Test - fun migrateDatabaseFrom2to3() { - val databaseInV2 = testHelper.createDatabase(AppDatabase.DATABASE_NAME, Migrations.DB_VER_2) + fun migrateDatabaseFrom2to3() = runTest { + val databaseInV2 = testHelper.createDatabase(version = Migrations.DB_VER_2) databaseInV2.run { - insert( - "streams", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("service_id", DEFAULT_SERVICE_ID) - put("url", DEFAULT_URL) - put("title", DEFAULT_TITLE) - put("stream_type", DEFAULT_TYPE.name) - put("duration", DEFAULT_DURATION) - put("uploader", DEFAULT_UPLOADER_NAME) - put("thumbnail_url", DEFAULT_THUMBNAIL) - } - ) - insert( - "streams", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("service_id", DEFAULT_SECOND_SERVICE_ID) - put("url", DEFAULT_SECOND_URL) - } - ) - insert( - "streams", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("service_id", DEFAULT_SERVICE_ID) - } - ) + val sql = """ + INSERT OR FAIL INTO streams + (service_id, url, title, stream_type, duration, uploader, thumbnail_url) + VALUES (?, ?, ?, ?, ?, ?, ?) + """.trimIndent() + + prepare(sql).use { statement -> + statement.bindInt(1, DEFAULT_SERVICE_ID) + statement.bindText(2, DEFAULT_URL) + statement.bindText(3, DEFAULT_TITLE) + statement.bindText(4, DEFAULT_TYPE.name) + statement.bindLong(5, DEFAULT_DURATION) + statement.bindText(6, DEFAULT_UPLOADER_NAME) + statement.bindText(7, DEFAULT_THUMBNAIL) + statement.step() + } + + prepare(sql).use { statement -> + statement.bindInt(1, DEFAULT_SECOND_SERVICE_ID) + statement.bindText(2, DEFAULT_SECOND_URL) + statement.step() + } + + prepare(sql).use { statement -> + statement.bindInt(1, DEFAULT_SERVICE_ID) + statement.step() + } close() } testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, - Migrations.DB_VER_3, - true, - Migrations.MIGRATION_2_3 + version = Migrations.DB_VER_3, + migrations = listOf(Migrations.MIGRATION_2_3) ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, - Migrations.DB_VER_4, - true, - Migrations.MIGRATION_3_4 + version = Migrations.DB_VER_4, + migrations = listOf(Migrations.MIGRATION_3_4) ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, - Migrations.DB_VER_5, - true, - Migrations.MIGRATION_4_5 + version = Migrations.DB_VER_5, + migrations = listOf(Migrations.MIGRATION_4_5) ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, - Migrations.DB_VER_6, - true, - Migrations.MIGRATION_5_6 + version = Migrations.DB_VER_6, + migrations = listOf(Migrations.MIGRATION_5_6) ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, - Migrations.DB_VER_7, - true, - Migrations.MIGRATION_6_7 + version = Migrations.DB_VER_7, + migrations = listOf(Migrations.MIGRATION_6_7) ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, - Migrations.DB_VER_8, - true, - Migrations.MIGRATION_7_8 + version = Migrations.DB_VER_8, + migrations = listOf(Migrations.MIGRATION_7_8) ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, - Migrations.DB_VER_9, - true, - Migrations.MIGRATION_8_9 + version = Migrations.DB_VER_9, + migrations = listOf(Migrations.MIGRATION_8_9) ) val migratedDatabaseV3 = getMigratedDatabase() @@ -163,8 +153,8 @@ class DatabaseMigrationTest { } @Test - fun migrateDatabaseFrom7to8() { - val databaseInV7 = testHelper.createDatabase(AppDatabase.DATABASE_NAME, Migrations.DB_VER_7) + fun migrateDatabaseFrom7to8() = runTest { + val databaseInV7 = testHelper.createDatabase(version = Migrations.DB_VER_7) val defaultSearch1 = " abc " val defaultSearch2 = " abc" @@ -175,53 +165,43 @@ class DatabaseMigrationTest { val otherServiceId = ServiceList.SoundCloud.serviceId databaseInV7.run { - insert( - "search_history", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("service_id", serviceId) - put("search", defaultSearch1) - } - ) - insert( - "search_history", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("service_id", serviceId) - put("search", defaultSearch2) - } - ) - insert( - "search_history", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("service_id", otherServiceId) - put("search", defaultSearch1) - } - ) - insert( - "search_history", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("service_id", otherServiceId) - put("search", defaultSearch2) - } - ) + val sql = "INSERT OR FAIL INTO search_history (service_id, search) VALUES (?, ?)" + + prepare(sql).use { statement -> + statement.bindInt(1, serviceId) + statement.bindText(2, defaultSearch1) + statement.step() + } + + prepare(sql).use { statement -> + statement.bindInt(1, serviceId) + statement.bindText(2, defaultSearch2) + statement.step() + } + + prepare(sql).use { statement -> + statement.bindInt(1, otherServiceId) + statement.bindText(2, defaultSearch1) + statement.step() + } + + prepare(sql).use { statement -> + statement.bindInt(1, otherServiceId) + statement.bindText(2, defaultSearch2) + statement.step() + } + close() } testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, - Migrations.DB_VER_8, - true, - Migrations.MIGRATION_7_8 + version = Migrations.DB_VER_8, + migrations = listOf(Migrations.MIGRATION_7_8) ) testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, - Migrations.DB_VER_9, - true, - Migrations.MIGRATION_8_9 + version = Migrations.DB_VER_9, + migrations = listOf(Migrations.MIGRATION_8_9) ) val migratedDatabaseV8 = getMigratedDatabase() @@ -234,66 +214,82 @@ class DatabaseMigrationTest { } @Test - fun migrateDatabaseFrom8to9() { - val databaseInV8 = testHelper.createDatabase(AppDatabase.DATABASE_NAME, Migrations.DB_VER_8) + fun migrateDatabaseFrom8to9() = runTest { + val databaseInV8 = testHelper.createDatabase(version = Migrations.DB_VER_8) val localUid1: Long val localUid2: Long val remoteUid1: Long val remoteUid2: Long + databaseInV8.run { - localUid1 = insert( - "playlists", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("name", DEFAULT_NAME + "1") - put("is_thumbnail_permanent", false) - put("thumbnail_stream_id", -1) - } - ) - localUid2 = insert( - "playlists", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("name", DEFAULT_NAME + "2") - put("is_thumbnail_permanent", false) - put("thumbnail_stream_id", -1) - } - ) - delete( - "playlists", - "uid = ?", - Array(1) { localUid1 } - ) - remoteUid1 = insert( - "remote_playlists", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("service_id", DEFAULT_SERVICE_ID) - put("url", DEFAULT_URL) - } - ) - remoteUid2 = insert( - "remote_playlists", - SQLiteDatabase.CONFLICT_FAIL, - ContentValues().apply { - put("service_id", DEFAULT_SECOND_SERVICE_ID) - put("url", DEFAULT_SECOND_URL) - } - ) - delete( - "remote_playlists", - "uid = ?", - Array(1) { remoteUid2 } - ) + val remotePlaylistsSQL = """ + INSERT OR FAIL INTO remote_playlists + (service_id, url) + VALUES (?, ?) + """.trimIndent() + val playlistsSQL = """ + INSERT OR FAIL INTO playlists + (name, is_thumbnail_permanent, thumbnail_stream_id) + VALUES (?, ?, ?) + """.trimIndent() + + prepare(playlistsSQL).use { statement -> + statement.bindText(1, DEFAULT_NAME + "1") + statement.bindBoolean(2, false) + statement.bindInt(3, -1) + statement.step() + } + + prepare("SELECT MAX(uid) FROM playlists").use { statement -> + statement.step() + localUid1 = statement.getLong(0) + } + + prepare(playlistsSQL).use { statement -> + statement.bindText(1, DEFAULT_NAME + "2") + statement.bindBoolean(2, false) + statement.bindInt(3, -1) + statement.step() + } + + prepare("SELECT MAX(uid) FROM playlists").use { statement -> + statement.step() + localUid2 = statement.getLong(0) + } + + execSQL("DELETE FROM playlists WHERE uid = $localUid1") + + prepare(remotePlaylistsSQL).use { statement -> + statement.bindInt(1, DEFAULT_SERVICE_ID) + statement.bindText(2, DEFAULT_URL) + statement.step() + } + + prepare("SELECT MAX(uid) FROM remote_playlists").use { statement -> + statement.step() + remoteUid1 = statement.getLong(0) + } + + prepare(remotePlaylistsSQL).use { statement -> + statement.bindInt(1, DEFAULT_SECOND_SERVICE_ID) + statement.bindText(2, DEFAULT_SECOND_URL) + statement.step() + } + + prepare("SELECT MAX(uid) FROM remote_playlists").use { statement -> + statement.step() + remoteUid2 = statement.getLong(0) + } + + execSQL("DELETE FROM remote_playlists WHERE uid = $remoteUid2") + close() } testHelper.runMigrationsAndValidate( - AppDatabase.DATABASE_NAME, - Migrations.DB_VER_9, - true, - Migrations.MIGRATION_8_9 + version = Migrations.DB_VER_9, + migrations = listOf(Migrations.MIGRATION_8_9) ) val migratedDatabaseV9 = getMigratedDatabase() diff --git a/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt b/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt index a61caad06..0347dcbba 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/database/FeedDAOTest.kt @@ -1,11 +1,12 @@ package org.schabi.newpipe.database import android.content.Context -import androidx.room.Room +import androidx.room3.Room import androidx.test.core.app.ApplicationProvider import io.reactivex.rxjava3.core.Single import java.io.IOException import java.time.OffsetDateTime +import kotlinx.coroutines.test.runTest import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertNotNull @@ -68,7 +69,7 @@ class FeedDAOTest { } @Test - fun testUnlinkStreamsOlderThan_KeepOne() { + fun testUnlinkStreamsOlderThan_KeepOne() = runTest { setupUnlinkDelete("2023-08-15T00:00:00Z") val streams = feedDAO.getStreams( FeedGroupEntity.GROUP_ALL_ID, @@ -82,7 +83,7 @@ class FeedDAOTest { } @Test - fun testUnlinkStreamsOlderThan_KeepMultiple() { + fun testUnlinkStreamsOlderThan_KeepMultiple() = runTest { setupUnlinkDelete("2023-08-01T00:00:00Z") val streams = feedDAO.getStreams( FeedGroupEntity.GROUP_ALL_ID, @@ -106,7 +107,7 @@ class FeedDAOTest { ) } - private fun setupUnlinkDelete(time: String) { + private suspend fun setupUnlinkDelete(time: String) { clearAndFillTables() Single.fromCallable { feedDAO.unlinkStreamsOlderThan(OffsetDateTime.parse(time)) @@ -116,7 +117,7 @@ class FeedDAOTest { }.blockingSubscribe() } - private fun clearAndFillTables() { + private suspend fun clearAndFillTables() { db.clearAllTables() streamDAO.insertAll(allStreams) subscriptionDAO.insertAll( diff --git a/app/src/androidTest/java/org/schabi/newpipe/local/playlist/LocalPlaylistManagerTest.kt b/app/src/androidTest/java/org/schabi/newpipe/local/playlist/LocalPlaylistManagerTest.kt index ac9e84228..71be85c88 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/local/playlist/LocalPlaylistManagerTest.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/local/playlist/LocalPlaylistManagerTest.kt @@ -56,7 +56,7 @@ class LocalPlaylistManagerTest { // This should not behave like this. // It should throw an error because currently the result is null result.test().await().assertComplete() - manager.playlists.test().awaitCount(1).assertValue(emptyList()) + manager.getPlaylists().test().awaitCount(1).assertValue(mutableListOf()) } @Test() diff --git a/app/src/androidTest/java/org/schabi/newpipe/testUtil/TestDatabase.kt b/app/src/androidTest/java/org/schabi/newpipe/testUtil/TestDatabase.kt index 8b1a261be..9c0ec196e 100644 --- a/app/src/androidTest/java/org/schabi/newpipe/testUtil/TestDatabase.kt +++ b/app/src/androidTest/java/org/schabi/newpipe/testUtil/TestDatabase.kt @@ -1,6 +1,6 @@ package org.schabi.newpipe.testUtil -import androidx.room.Room +import androidx.room3.Room import androidx.test.core.app.ApplicationProvider import org.junit.Assert.assertSame import org.schabi.newpipe.NewPipeDatabase diff --git a/app/src/main/java/org/schabi/newpipe/database/Migrations.kt b/app/src/main/java/org/schabi/newpipe/database/Migrations.kt index 0aa608264..62908f0bd 100644 --- a/app/src/main/java/org/schabi/newpipe/database/Migrations.kt +++ b/app/src/main/java/org/schabi/newpipe/database/Migrations.kt @@ -293,18 +293,18 @@ object Migrations { // Create a temp table to initialize display_index. connection.execSQL( "CREATE TABLE `playlists_tmp` " + - "(`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " + - "`name` TEXT, `is_thumbnail_permanent` INTEGER NOT NULL, " + - "`thumbnail_stream_id` INTEGER NOT NULL, " + - "`display_index` INTEGER NOT NULL)" + "(`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " + + "`name` TEXT, `is_thumbnail_permanent` INTEGER NOT NULL, " + + "`thumbnail_stream_id` INTEGER NOT NULL, " + + "`display_index` INTEGER NOT NULL)" ) connection.execSQL( "INSERT INTO `playlists_tmp` " + - "(`uid`, `name`, `is_thumbnail_permanent`, `thumbnail_stream_id`, " + - "`display_index`) " + - "SELECT `uid`, `name`, `is_thumbnail_permanent`, `thumbnail_stream_id`, " + - "-1 " + - "FROM `playlists`" + "(`uid`, `name`, `is_thumbnail_permanent`, `thumbnail_stream_id`, " + + "`display_index`) " + + "SELECT `uid`, `name`, `is_thumbnail_permanent`, `thumbnail_stream_id`, " + + "-1 " + + "FROM `playlists`" ) // Replace the old table, note that this also removes the index on the name which @@ -316,18 +316,18 @@ object Migrations { // Create a temp table to initialize display_index. connection.execSQL( "CREATE TABLE `remote_playlists_tmp` " + - "(`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " + - "`service_id` INTEGER NOT NULL, `name` TEXT, `url` TEXT, " + - "`thumbnail_url` TEXT, `uploader` TEXT, " + - "`display_index` INTEGER NOT NULL," + - "`stream_count` INTEGER)" + "(`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " + + "`service_id` INTEGER NOT NULL, `name` TEXT, `url` TEXT, " + + "`thumbnail_url` TEXT, `uploader` TEXT, " + + "`display_index` INTEGER NOT NULL," + + "`stream_count` INTEGER)" ) connection.execSQL( "INSERT INTO `remote_playlists_tmp` (`uid`, `service_id`, " + - "`name`, `url`, `thumbnail_url`, `uploader`, `display_index`, " + - "`stream_count`)" + - "SELECT `uid`, `service_id`, `name`, `url`, `thumbnail_url`, `uploader`, " + - "-1, `stream_count` FROM `remote_playlists`" + "`name`, `url`, `thumbnail_url`, `uploader`, `display_index`, " + + "`stream_count`)" + + "SELECT `uid`, `service_id`, `name`, `url`, `thumbnail_url`, `uploader`, " + + "-1, `stream_count` FROM `remote_playlists`" ) // Replace the old table, note that this also removes the index on the name which @@ -338,7 +338,7 @@ object Migrations { // Create index on the new table. connection.execSQL( "CREATE UNIQUE INDEX `index_remote_playlists_service_id_url` " + - "ON `remote_playlists` (`service_id`, `url`)" + "ON `remote_playlists` (`service_id`, `url`)" ) } } diff --git a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.kt b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.kt index 5976ec148..886437a21 100644 --- a/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.kt +++ b/app/src/main/java/org/schabi/newpipe/local/history/HistoryRecordManager.kt @@ -53,9 +53,9 @@ class HistoryRecordManager(context: Context) { private val isStreamHistoryEnabled: Boolean get() = sharedPreferences.getBoolean(streamHistoryKey, false) - ///////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////// // Watch History - ///////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////// /** * Marks a stream item as watched such that it is hidden from the feed if watched videos are @@ -165,9 +165,9 @@ class HistoryRecordManager(context: Context) { return streamHistoryTable.getStatistics().subscribeOn(Schedulers.io()) } - ///////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////// // Search History - ///////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////// fun onSearched(serviceId: Int, search: String): Maybe { if (!isSearchHistoryEnabled) { @@ -214,9 +214,9 @@ class HistoryRecordManager(context: Context) { } } - ///////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////// // Stream State History - ///////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////// fun loadStreamState(queueItem: PlayQueueItem): Maybe { return queueItem.stream @@ -281,9 +281,9 @@ class HistoryRecordManager(context: Context) { }.subscribeOn(Schedulers.io()) } - ///////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////// // Utility - ///////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////// fun removeOrphanedRecords(): Single { return Single.fromCallable { streamTable.deleteOrphans() } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 53f6ce309..7fd9c7f89 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -60,9 +60,9 @@ rxbinding = "4.0.0" rxjava = "3.1.12" settings = "1.3.0" sonarqube = "7.5.0.8588" +sqlite = "2.7.1" statesaver = "1.4.1" # TODO: Drop because it is deprecated and incompatible with KSP2 stetho = "1.6.0" -sqlite = "2.7.1" swiperefreshlayout = "1.2.0" # You can use a local version by uncommenting a few lines in settings.gradle # Or you can use a commit you pushed to GitHub by just replacing TeamNewPipe with your GitHub @@ -104,8 +104,8 @@ androidx-room-runtime = { module = "androidx.room3:room3-runtime", version.ref = androidx-room-rxjava3 = { module = "androidx.room3:room3-rxjava3", version.ref = "room" } androidx-room-testing = { module = "androidx.room3:room3-testing", version.ref = "room" } androidx-runner = { module = "androidx.test:runner", version.ref = "runner" } -androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version.ref = "swiperefreshlayout" } androidx-sqlite-bundled = { module = "androidx.sqlite:sqlite-bundled", version.ref = "sqlite" } +androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version.ref = "swiperefreshlayout" } androidx-test-espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" } androidx-viewpager2 = { module = "androidx.viewpager2:viewpager2", version.ref = "viewpager2" } androidx-webkit = { module = "androidx.webkit:webkit", version.ref = "webkit" } @@ -139,6 +139,7 @@ jetbrains-compose-test-ui = { module = "org.jetbrains.compose.ui:ui-test", versi jetbrains-compose-tooling = { module = "org.jetbrains.compose.ui:ui-tooling", version.ref = "multiplatform" } jetbrains-compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "multiplatform" } jetbrains-coroutines-swing = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-swing", version.ref = "coroutines" } +jetbrains-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } jetbrains-lifecycle-navigation3 = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-navigation3", version.ref = "lifecycle" } jetbrains-lifecycle-viewmodel = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" } jetbrains-navigation3-ui = { module = "org.jetbrains.androidx.navigation3:navigation3-ui", version.ref = "navigation3" }