Remove runBlocking from common source sets and update coroutines for KMP
This commit is contained in:
parent
9cf4ec417c
commit
36fad2491e
@ -17,7 +17,6 @@ junitJupiter = "5.10.1"
|
||||
junitVersion = "4.13.2"
|
||||
konfetti-xml = "2.0.2"
|
||||
kotlin = "2.1.10"
|
||||
kotlinxCoroutinesCoreCommon = "1.3.8"
|
||||
ksp = "2.1.10-1.0.30"
|
||||
ktlint-plugin = "11.6.1"
|
||||
ktor = "1.6.8"
|
||||
@ -54,8 +53,8 @@ konfetti-xml = { group = "nl.dionsegijn", name = "konfetti-xml", version.ref = "
|
||||
kotlin-stdlib-jdk8 = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-jdk8", version.ref = "kotlin" }
|
||||
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "ktxCoroutine" }
|
||||
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "ktxCoroutine" }
|
||||
kotlinx-coroutines-core-common = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core-common", version.ref = "kotlinxCoroutinesCoreCommon" }
|
||||
kotlinx-coroutines-core-jvm = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm", version.ref = "ktxCoroutine" }
|
||||
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "ktxCoroutine" }
|
||||
ktor-client-android = { group = "io.ktor", name = "ktor-client-android", version.ref = "ktor" }
|
||||
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor" }
|
||||
ktor-client-jackson = { group = "io.ktor", name = "ktor-client-jackson", version.ref = "ktor" }
|
||||
|
||||
@ -31,7 +31,8 @@ kotlin {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib-common"))
|
||||
implementation(libs.kotlinx.coroutines.core.common)
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
compileOnly(libs.kotlin.inject.runtime)
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,13 +40,13 @@ kotlin {
|
||||
dependencies {
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
implementation(libs.kotlinx.coroutines.test)
|
||||
}
|
||||
}
|
||||
|
||||
val jvmMain by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib-jdk8"))
|
||||
compileOnly(libs.kotlin.inject.runtime)
|
||||
implementation(libs.guava)
|
||||
implementation(libs.kotlinx.coroutines.core.jvm)
|
||||
implementation(libs.annotation)
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2025 Álinson Santos Xavier <git@axavier.org>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.isoron.platform
|
||||
|
||||
expect fun <T> runSuspend(block: suspend () -> T): T
|
||||
@ -18,8 +18,8 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.tasks
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.isoron.platform.io.UserFile
|
||||
import org.isoron.platform.runSuspend
|
||||
import org.isoron.platform.time.getToday
|
||||
import org.isoron.uhabits.core.io.HabitsCSVExporter
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
@ -35,10 +35,10 @@ class ExportCSVTask(
|
||||
override fun doInBackground() {
|
||||
try {
|
||||
val exporter = HabitsCSVExporter(habitList, selectedHabits)
|
||||
val bytes = runBlocking { exporter.writeArchive() }
|
||||
val bytes = runSuspend { exporter.writeArchive() }
|
||||
val date = getToday().toCSVString()
|
||||
val zipFile = outputDir.resolve("Loop Habits CSV $date.zip")
|
||||
runBlocking { zipFile.writeBytes(bytes) }
|
||||
runSuspend { zipFile.writeBytes(bytes) }
|
||||
archiveFilename = zipFile.pathString
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package org.isoron.platform.io
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -32,7 +32,7 @@ class MigrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMigrateIdempotent() = runBlocking {
|
||||
fun testMigrateIdempotent() = runTest {
|
||||
val db = TestDatabaseHelper.createEmptyDatabase()
|
||||
val version = db.getVersion()
|
||||
db.migrateTo(version) { v -> TestDatabaseHelper.loadMigrationSQL(v) }
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.isoron.platform.io.Database
|
||||
import org.isoron.platform.io.DatabaseOpener
|
||||
import org.isoron.platform.io.FileOpener
|
||||
@ -26,6 +25,7 @@ import org.isoron.platform.io.TestDatabaseHelper
|
||||
import org.isoron.platform.io.UserFile
|
||||
import org.isoron.platform.io.createTestDatabaseOpener
|
||||
import org.isoron.platform.io.createTestFileOpener
|
||||
import org.isoron.platform.runSuspend
|
||||
import org.isoron.platform.time.LocalDate
|
||||
import org.isoron.platform.time.setToday
|
||||
import org.isoron.uhabits.core.commands.CommandRunner
|
||||
@ -56,20 +56,20 @@ open class BaseUnitTest {
|
||||
commandRunner = CommandRunner(taskRunner)
|
||||
}
|
||||
|
||||
protected fun createTempDir(): UserFile = runBlocking {
|
||||
protected fun createTempDir(): UserFile = runSuspend {
|
||||
val dir = fileOpener.openUserFile("test-temp-dir-${tempFileCounter++}")
|
||||
dir.mkdirs()
|
||||
dir
|
||||
}
|
||||
|
||||
protected fun copyResourceToTempFile(resourcePath: String): UserFile = runBlocking {
|
||||
protected fun copyResourceToTempFile(resourcePath: String): UserFile = runSuspend {
|
||||
val cleanPath = resourcePath.removePrefix("/")
|
||||
val tempFile = fileOpener.openUserFile("test-temp-${tempFileCounter++}")
|
||||
fileOpener.openResourceFile(cleanPath).copyTo(tempFile)
|
||||
tempFile
|
||||
}
|
||||
|
||||
protected fun openDatabaseResource(resourcePath: String): Database = runBlocking {
|
||||
protected fun openDatabaseResource(resourcePath: String): Database = runSuspend {
|
||||
val tempFile = copyResourceToTempFile(resourcePath)
|
||||
databaseOpener.open(tempFile.pathString)
|
||||
}
|
||||
|
||||
@ -18,11 +18,11 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.database.migrations
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.isoron.platform.io.Database
|
||||
import org.isoron.platform.io.migrateTo
|
||||
import org.isoron.platform.io.querySingle
|
||||
import org.isoron.platform.io.run
|
||||
import org.isoron.platform.runSuspend
|
||||
import org.isoron.uhabits.core.BaseUnitTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContains
|
||||
@ -37,7 +37,7 @@ class Version22Test : BaseUnitTest() {
|
||||
db = openDatabaseResource("/databases/021.db")
|
||||
}
|
||||
|
||||
private fun migrateTo(version: Int) = runBlocking {
|
||||
private fun migrateTo(version: Int) = runSuspend {
|
||||
db.migrateTo(version) { v ->
|
||||
val path = "migrations/%02d.sql".format(v)
|
||||
fileOpener.openResourceFile(path).lines().joinToString("\n")
|
||||
|
||||
@ -19,10 +19,10 @@
|
||||
|
||||
package org.isoron.uhabits.core.database.migrations
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.isoron.platform.io.Database
|
||||
import org.isoron.platform.io.migrateTo
|
||||
import org.isoron.platform.io.query
|
||||
import org.isoron.platform.runSuspend
|
||||
import org.isoron.uhabits.core.BaseUnitTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
@ -36,7 +36,7 @@ class Version23Test : BaseUnitTest() {
|
||||
db = openDatabaseResource("/databases/022.db")
|
||||
}
|
||||
|
||||
private fun migrateTo(version: Int) = runBlocking {
|
||||
private fun migrateTo(version: Int) = runSuspend {
|
||||
db.migrateTo(version) { v ->
|
||||
val path = "migrations/%02d.sql".format(v)
|
||||
fileOpener.openResourceFile(path).lines().joinToString("\n")
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.io
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.isoron.platform.io.ZipReader
|
||||
import org.isoron.uhabits.core.BaseUnitTest
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
@ -36,7 +36,7 @@ class HabitsCSVExporterTest : BaseUnitTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testExportCSV() = runBlocking {
|
||||
fun testExportCSV() = runTest {
|
||||
val selected: MutableList<Habit> = mutableListOf()
|
||||
for (h in habitList) selected.add(h)
|
||||
val exporter = HabitsCSVExporter(habitList, selected)
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
*/
|
||||
package org.isoron.uhabits.core.io
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.isoron.platform.runSuspend
|
||||
import org.isoron.platform.time.LocalDate
|
||||
import org.isoron.uhabits.core.BaseUnitTest
|
||||
import org.isoron.uhabits.core.models.Entry
|
||||
@ -157,7 +157,7 @@ class ImportTest : BaseUnitTest() {
|
||||
return h.originalEntries.get(LocalDate(year, month, day)).notes == notes
|
||||
}
|
||||
|
||||
private fun importFromFile(assetFilename: String) = runBlocking {
|
||||
private fun importFromFile(assetFilename: String) = runSuspend {
|
||||
val userFile = copyResourceToTempFile(assetFilename)
|
||||
assertTrue(userFile.exists())
|
||||
val importer = GenericImporter(
|
||||
|
||||
@ -26,8 +26,8 @@ import dev.mokkery.matcher.any
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.spy
|
||||
import dev.mokkery.verify
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.isoron.platform.io.UserFile
|
||||
import org.isoron.platform.runSuspend
|
||||
import org.isoron.platform.time.getToday
|
||||
import org.isoron.uhabits.core.BaseUnitTest
|
||||
import org.isoron.uhabits.core.models.Entry
|
||||
@ -94,7 +94,7 @@ class ListHabitsBehaviorTest : BaseUnitTest() {
|
||||
every { dirFinder.getCSVOutputDir() } returns outputDir
|
||||
behavior.onExportCSV()
|
||||
verify { screen.showSendFileScreen(any()) }
|
||||
val files = runBlocking { outputDir.listFiles() }
|
||||
val files = runSuspend { outputDir.listFiles() }
|
||||
assertEquals(1, files!!.size)
|
||||
}
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@ import dev.mokkery.answering.returns
|
||||
import dev.mokkery.every
|
||||
import dev.mokkery.mock
|
||||
import dev.mokkery.verify
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.isoron.platform.runSuspend
|
||||
import org.isoron.uhabits.core.BaseUnitTest
|
||||
import org.isoron.uhabits.core.models.Habit
|
||||
import kotlin.test.Test
|
||||
@ -60,7 +60,7 @@ class ShowHabitMenuPresenterTest : BaseUnitTest() {
|
||||
val outputDir = createTempDir()
|
||||
every { system.getCSVOutputDir() } returns outputDir
|
||||
menu.onExportCSV()
|
||||
val files = runBlocking { outputDir.listFiles() }
|
||||
val files = runSuspend { outputDir.listFiles() }
|
||||
assertEquals(1, files!!.size)
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
package org.isoron.uhabits.core.ui.views
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.isoron.platform.gui.assertRenders
|
||||
import org.isoron.platform.io.createTestDateFormatter
|
||||
import org.isoron.platform.time.LocalDate
|
||||
@ -41,24 +41,24 @@ class BarChartTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDraw() = runBlocking {
|
||||
fun testDraw() = runTest {
|
||||
assertRenders(300, 200, "$base/base.png", component)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDrawDarkTheme() = runBlocking {
|
||||
fun testDrawDarkTheme() = runTest {
|
||||
component.theme = DarkTheme()
|
||||
assertRenders(300, 200, "$base/themeDark.png", component)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDrawWidgetTheme() = runBlocking {
|
||||
fun testDrawWidgetTheme() = runTest {
|
||||
component.theme = WidgetTheme()
|
||||
assertRenders(300, 200, "$base/themeWidget.png", component)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDrawWithOffset() = runBlocking {
|
||||
fun testDrawWithOffset() = runTest {
|
||||
component.dataOffset = 5
|
||||
assertRenders(300, 200, "$base/offset.png", component)
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ import dev.mokkery.mock
|
||||
import dev.mokkery.resetCalls
|
||||
import dev.mokkery.verify
|
||||
import dev.mokkery.verifyNoMoreCalls
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.isoron.platform.gui.assertRenders
|
||||
import org.isoron.platform.io.createTestDateFormatter
|
||||
import org.isoron.platform.time.DayOfWeek
|
||||
@ -78,12 +78,12 @@ class HistoryChartTest {
|
||||
)
|
||||
|
||||
@Test
|
||||
fun testDraw() = runBlocking {
|
||||
fun testDraw() = runTest {
|
||||
assertRenders(400, 200, "$base/base.png", view)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testClick() = runBlocking {
|
||||
fun testClick() = runTest {
|
||||
assertRenders(400, 200, "$base/base.png", view)
|
||||
|
||||
// Click top left date
|
||||
@ -114,7 +114,7 @@ class HistoryChartTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLongClick() = runBlocking {
|
||||
fun testLongClick() = runTest {
|
||||
assertRenders(400, 200, "$base/base.png", view)
|
||||
|
||||
// Click top left date
|
||||
@ -145,30 +145,30 @@ class HistoryChartTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDrawWeekDay() = runBlocking {
|
||||
fun testDrawWeekDay() = runTest {
|
||||
view.firstWeekday = DayOfWeek.MONDAY
|
||||
assertRenders(400, 200, "$base/weekday.png", view)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDrawDifferentSize() = runBlocking {
|
||||
fun testDrawDifferentSize() = runTest {
|
||||
assertRenders(200, 200, "$base/small.png", view)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDrawDarkTheme() = runBlocking {
|
||||
fun testDrawDarkTheme() = runTest {
|
||||
view.theme = DarkTheme()
|
||||
assertRenders(400, 200, "$base/themeDark.png", view)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDrawWidgetTheme() = runBlocking {
|
||||
fun testDrawWidgetTheme() = runTest {
|
||||
view.theme = WidgetTheme()
|
||||
assertRenders(400, 200, "$base/themeWidget.png", view)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDrawOffset() = runBlocking {
|
||||
fun testDrawOffset() = runTest {
|
||||
view.dataOffset = 2
|
||||
assertRenders(400, 200, "$base/scroll.png", view)
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package org.isoron.uhabits.core.utils
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.isoron.uhabits.core.BaseUnitTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
@ -8,7 +8,7 @@ import kotlin.test.assertTrue
|
||||
class FileExtensionsTest : BaseUnitTest() {
|
||||
|
||||
@Test
|
||||
fun testIsSQLite3File() = runBlocking {
|
||||
fun testIsSQLite3File() = runTest {
|
||||
val userFile = copyResourceToTempFile("loop.db")
|
||||
val isSqlite3File = isSQLite3File(userFile)
|
||||
assertTrue(isSqlite3File)
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2016-2025 Álinson Santos Xavier <git@axavier.org>
|
||||
*
|
||||
* This file is part of Loop Habit Tracker.
|
||||
*
|
||||
* Loop Habit Tracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Loop Habit Tracker is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.isoron.platform
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
actual fun <T> runSuspend(block: suspend () -> T): T = runBlocking { block() }
|
||||
@ -57,5 +57,4 @@ class MidnightTimerTest : BaseUnitTest() {
|
||||
assertEquals(true, suspendedListener)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user