Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 13:56:56 +01:00
parent 75dc487a7a
commit 39c29d175b
6317 changed files with 388324 additions and 2 deletions

View file

@ -0,0 +1,20 @@
plugins {
id(ThunderbirdPlugins.Library.android)
}
android {
namespace = "net.thunderbird.core.android.testing"
}
dependencies {
api(libs.junit)
api(libs.robolectric)
implementation(projects.core.logging.api)
implementation(projects.core.preference.api)
implementation(projects.core.preference.impl)
api(libs.koin.core)
api(libs.mockito.core)
api(libs.mockito.kotlin)
}

View file

@ -0,0 +1,78 @@
package net.thunderbird.core.android.preferences
import net.thunderbird.core.logging.Logger
import net.thunderbird.core.preference.storage.InMemoryStorage
import net.thunderbird.core.preference.storage.Storage
import net.thunderbird.core.preference.storage.StorageEditor
import net.thunderbird.core.preference.storage.StoragePersister
import net.thunderbird.core.preference.storage.StorageUpdater
class TestStoragePersister(
private val logger: Logger,
) : StoragePersister {
private val values = mutableMapOf<String, Any?>()
override fun loadValues(): Storage {
return InMemoryStorage(
values = values.mapValues { (_, value) ->
value?.toString() ?: ""
},
logger,
)
}
override fun createStorageEditor(storageUpdater: StorageUpdater): StorageEditor {
return InMemoryStorageEditor(storageUpdater)
}
private inner class InMemoryStorageEditor(private val storageUpdater: StorageUpdater) : StorageEditor {
private val removals = mutableSetOf<String>()
private val changes = mutableMapOf<String, String>()
private var alreadyCommitted = false
override fun putBoolean(key: String, value: Boolean) = apply {
changes[key] = value.toString()
removals.remove(key)
}
override fun putInt(key: String, value: Int) = apply {
changes[key] = value.toString()
removals.remove(key)
}
override fun putLong(key: String, value: Long) = apply {
changes[key] = value.toString()
removals.remove(key)
}
override fun putString(key: String, value: String?) = apply {
if (value == null) {
remove(key)
} else {
changes[key] = value
removals.remove(key)
}
}
override fun remove(key: String) = apply {
removals.add(key)
changes.remove(key)
}
override fun commit(): Boolean {
if (alreadyCommitted) throw AssertionError("StorageEditor.commit() called more than once")
alreadyCommitted = true
storageUpdater.updateStorage(::writeValues)
return true
}
private fun writeValues(currentStorage: Storage): Storage {
val updatedValues = currentStorage.getAll() - removals + changes
values.clear()
values.putAll(updatedValues.mapValues { (_, value) -> value })
return InMemoryStorage(updatedValues, logger)
}
}
}

View file

@ -0,0 +1,23 @@
package net.thunderbird.core.android.testing
import org.mockito.Mockito
import org.mockito.Mockito.mock
import org.mockito.kotlin.KStubbing
object MockHelper {
@JvmStatic
fun <T> mockBuilder(classToMock: Class<T>): T {
return mock(classToMock) { invocation ->
val mock = invocation.mock
if (invocation.method.returnType.isInstance(mock)) {
mock
} else {
Mockito.RETURNS_DEFAULTS.answer(invocation)
}
}
}
inline fun <reified T : Any> mockBuilder(stubbing: KStubbing<T>.(T) -> Unit = {}): T {
return mockBuilder(T::class.java).apply { KStubbing(this).stubbing(this) }
}
}

View file

@ -0,0 +1,15 @@
package net.thunderbird.core.android.testing
import android.app.Application
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
/**
* A Robolectric test that does not create an instance of our [Application].
*/
@RunWith(RobolectricTestRunner::class)
@Config(application = EmptyApplication::class)
abstract class RobolectricTest
class EmptyApplication : Application()

View file

@ -0,0 +1,3 @@
package net.thunderbird.core.android.testing
fun String.removeNewlines(): String = replace("([\\r\\n])".toRegex(), "")