Let consumeItemsUntilPredicate fail if predicate is never true or if Complete occurs.

Do not fail on error for `consumeItemsUntilTimeout`
This commit is contained in:
Benoit Marty 2023-12-15 18:13:29 +01:00 committed by Benoit Marty
parent ff2fc7ff3a
commit b5a2c85e66

View file

@ -19,7 +19,7 @@ package io.element.android.tests.testutils
import app.cash.turbine.Event
import app.cash.turbine.ReceiveTurbine
import app.cash.turbine.withTurbineTimeout
import io.element.android.libraries.core.data.tryOrNull
import io.element.android.libraries.core.bool.orFalse
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
@ -29,7 +29,7 @@ import kotlin.time.Duration.Companion.milliseconds
* @return the list of consumed items.
*/
suspend fun <T : Any> ReceiveTurbine<T>.consumeItemsUntilTimeout(timeout: Duration = 100.milliseconds): List<T> {
return consumeItemsUntilPredicate(timeout) { false }
return consumeItemsUntilPredicate(timeout, ignoreTimeoutError = true) { false }
}
/**
@ -49,22 +49,29 @@ suspend fun <T : Any> ReceiveTurbine<T>.awaitLastSequentialItem(): T {
*/
suspend fun <T : Any> ReceiveTurbine<T>.consumeItemsUntilPredicate(
timeout: Duration = 100.milliseconds,
ignoreTimeoutError: Boolean = false,
predicate: (T) -> Boolean,
): List<T> {
val items = ArrayList<T>()
tryOrNull {
var foundItemOrFinished = false
while (!foundItemOrFinished) {
var exitLoop = false
try {
while (!exitLoop) {
when (val event = withTurbineTimeout(timeout) { awaitEvent() }) {
is Event.Item<T> -> {
items.add(event.value)
if (predicate(event.value)) {
foundItemOrFinished = true
}
exitLoop = predicate(event.value)
}
Event.Complete, is Event.Error -> foundItemOrFinished = true
Event.Complete -> error("Unexpected complete")
is Event.Error -> throw event.throwable
}
}
} catch (assertionError: AssertionError) {
// TurbineAssertionError is internal :/, so rely on the message
if (assertionError.message?.startsWith("No value produced in").orFalse() && ignoreTimeoutError) {
// Timeout, ignore
} else {
throw assertionError
}
}
return items
}