* Fix test setup

* Fix tests

* Disable broken CloudflareTest

* Add a basic test for Android's Looper
This commit is contained in:
Constantin Piber
2026-05-18 20:04:39 +02:00
committed by GitHub
parent 762d5bdbe6
commit 779229a48a
11 changed files with 149 additions and 31 deletions

View File

@@ -0,0 +1,56 @@
package suwayomi.tachidesk
import android.os.Handler
import android.os.Looper
import android.os.Message
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
import kotlin.text.StringBuilder
class LooperThread : Thread() {
var mHandler: Handler? = null
val latch = CountDownLatch(1)
override fun run() {
Looper.prepare()
mHandler = Handler(Looper.myLooper())
latch.countDown()
Looper.loop()
}
}
class LooperTest {
@Test
fun multiplePostWork() {
val thread = LooperThread()
thread.start()
val sb = StringBuilder()
val latch = CountDownLatch(1)
assertTrue(thread.latch.await(5, TimeUnit.SECONDS))
thread.mHandler!!.post {
Thread.sleep(100)
sb.append("a_b_c")
}
thread.mHandler!!.post {
Thread.sleep(100)
sb.append("_d_e_f")
}
thread.mHandler!!.post {
Thread.sleep(100)
sb.append("_g_h_i")
latch.countDown()
}
assertNotEquals("a_b_c_d_e_f_g_h_i", sb.toString())
assertTrue(latch.await(5, TimeUnit.SECONDS))
assertEquals("a_b_c_d_e_f_g_h_i", sb.toString())
thread.mHandler!!.looper.quit()
// thread.join()
}
}

View File

@@ -18,19 +18,22 @@ import suwayomi.tachidesk.test.clearTables
class CategoryControllerTest : ApplicationTest() {
@Test
fun categoryReorder() {
clearTables(
CategoryTable,
)
Category.createCategory("foo")
Category.createCategory("bar")
val cats = Category.getCategoryList()
val foo = cats.asSequence().filter { it.name == "foo" }.first()
val bar = cats.asSequence().filter { it.name == "bar" }.first()
assertEquals(1, foo.order)
assertEquals(2, bar.order)
assertEquals(0, foo.order)
assertEquals(1, bar.order)
Category.reorderCategory(1, 2)
val catsReordered = Category.getCategoryList()
val fooReordered = catsReordered.asSequence().filter { it.name == "foo" }.first()
val barReordered = catsReordered.asSequence().filter { it.name == "bar" }.first()
assertEquals(2, fooReordered.order)
assertEquals(1, barReordered.order)
assertEquals(1, fooReordered.order)
assertEquals(0, barReordered.order)
}
@AfterEach

View File

@@ -35,7 +35,7 @@ class CategoryMangaTest : ApplicationTest() {
CategoryManga.getCategoryMangaList(DEFAULT_CATEGORY_ID)[0].unreadCount,
"Manga should not have any unread chapters",
)
createChapters(mangaId, 10, false)
createChapters(mangaId, 10, false, start = 11)
assertEquals(
10,
CategoryManga.getCategoryMangaList(DEFAULT_CATEGORY_ID)[0].unreadCount,

View File

@@ -12,9 +12,12 @@ import eu.kanade.tachiyomi.createAppModule
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.source.local.LocalSource
import io.github.oshai.kotlinlogging.KotlinLogging
import org.jetbrains.exposed.v1.core.DatabaseConfig
import org.jetbrains.exposed.v1.core.ExperimentalKeywordApi
import org.jetbrains.exposed.v1.jdbc.Database
import org.junit.jupiter.api.BeforeAll
import org.koin.core.context.startKoin
import org.koin.core.context.stopKoin
import suwayomi.tachidesk.server.ApplicationDirs
import suwayomi.tachidesk.server.JavalinSetup
import suwayomi.tachidesk.server.ServerConfig
@@ -22,7 +25,9 @@ import suwayomi.tachidesk.server.androidCompat
import suwayomi.tachidesk.server.database.databaseUp
import suwayomi.tachidesk.server.serverConfig
import suwayomi.tachidesk.server.serverModule
import suwayomi.tachidesk.server.settings.SettingsRegistry
import suwayomi.tachidesk.server.util.AppMutex.handleAppMutex
import suwayomi.tachidesk.server.util.ConfigTypeRegistration
import suwayomi.tachidesk.server.util.SystemTray
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -55,6 +60,13 @@ open class ApplicationTest {
private var initializedTheApp = false
fun testingSetup() {
// register Tachidesk's config which is dubbed "ServerConfig"
SettingsRegistry.clear()
ConfigTypeRegistration.registerCustomTypes()
GlobalConfigManager.registerModule(
ServerConfig.register { GlobalConfigManager.config },
)
// Application dirs
val applicationDirs = ApplicationDirs()
@@ -72,13 +84,9 @@ open class ApplicationTest {
File(it).mkdirs()
}
// register Tachidesk's config which is dubbed "ServerConfig"
GlobalConfigManager.registerModule(
ServerConfig.register { GlobalConfigManager.config },
)
// initialize Koin modules
val app = App()
stopKoin()
startKoin {
modules(
createAppModule(app),
@@ -128,14 +136,14 @@ open class ApplicationTest {
}
// create system tray
if (serverConfig.systemTrayEnabled.value) {
try {
SystemTray.create()
} catch (e: Throwable) {
// cover both java.lang.Exception and java.lang.Error
e.printStackTrace()
}
}
// if (serverConfig.systemTrayEnabled.value) {
// try {
// SystemTray.create()
// } catch (e: Throwable) {
// // cover both java.lang.Exception and java.lang.Error
// e.printStackTrace()
// }
// }
// Disable jetty's logging
System.setProperty("org.eclipse.jetty.util.log.announce", "false")
@@ -154,8 +162,16 @@ open class ApplicationTest {
// fixes #119 , ref: https://github.com/Suwayomi/Suwayomi-Server/issues/119#issuecomment-894681292 , source Id calculation depends on String.lowercase()
Locale.setDefault(Locale.ENGLISH)
val dbConfig =
DatabaseConfig {
useNestedTransactions = true
@OptIn(ExperimentalKeywordApi::class)
preserveKeywordCasing = false
defaultSchema = null
}
// in-memory database, don't discard database between connections/transactions
val db = Database.connect("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;", "org.h2.Driver")
val db = Database.connect("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;", "org.h2.Driver", databaseConfig = dbConfig)
databaseUp(db)

View File

@@ -55,8 +55,9 @@ fun createChapters(
mangaId: Int,
amount: Int,
read: Boolean,
start: Int = 1,
) {
val list = listOf((0 until amount)).flatten().map { 1 }
val list = listOf((0 until amount)).flatten().map { it + start }
transaction {
ChapterTable
.batchInsert(list) {