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 bc4da250e1
commit 06c9da277b

View file

@ -19,7 +19,7 @@ package io.element.android.tests.testutils
import app.cash.turbine.Event import app.cash.turbine.Event
import app.cash.turbine.ReceiveTurbine import app.cash.turbine.ReceiveTurbine
import app.cash.turbine.withTurbineTimeout 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
import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.milliseconds
@ -29,7 +29,7 @@ import kotlin.time.Duration.Companion.milliseconds
* @return the list of consumed items. * @return the list of consumed items.
*/ */
suspend fun <T : Any> ReceiveTurbine<T>.consumeItemsUntilTimeout(timeout: Duration = 100.milliseconds): List<T> { 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( suspend fun <T : Any> ReceiveTurbine<T>.consumeItemsUntilPredicate(
timeout: Duration = 100.milliseconds, timeout: Duration = 100.milliseconds,
ignoreTimeoutError: Boolean = false,
predicate: (T) -> Boolean, predicate: (T) -> Boolean,
): List<T> { ): List<T> {
val items = ArrayList<T>() val items = ArrayList<T>()
tryOrNull { var exitLoop = false
var foundItemOrFinished = false try {
while (!foundItemOrFinished) { while (!exitLoop) {
when (val event = withTurbineTimeout(timeout) { awaitEvent() }) { when (val event = withTurbineTimeout(timeout) { awaitEvent() }) {
is Event.Item<T> -> { is Event.Item<T> -> {
items.add(event.value) items.add(event.value)
if (predicate(event.value)) { exitLoop = predicate(event.value)
foundItemOrFinished = true
}
} }
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 return items
} }