From 06c9da277b05ea906b6b8d5d6faeba1ed1c180e9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 15 Dec 2023 18:13:29 +0100 Subject: [PATCH] Let `consumeItemsUntilPredicate` fail if predicate is never true or if Complete occurs. Do not fail on error for `consumeItemsUntilTimeout` --- .../android/tests/testutils/ReceiveTurbine.kt | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/ReceiveTurbine.kt b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/ReceiveTurbine.kt index 3e47dd63ce..0c8bd89951 100644 --- a/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/ReceiveTurbine.kt +++ b/tests/testutils/src/main/kotlin/io/element/android/tests/testutils/ReceiveTurbine.kt @@ -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 ReceiveTurbine.consumeItemsUntilTimeout(timeout: Duration = 100.milliseconds): List { - return consumeItemsUntilPredicate(timeout) { false } + return consumeItemsUntilPredicate(timeout, ignoreTimeoutError = true) { false } } /** @@ -49,22 +49,29 @@ suspend fun ReceiveTurbine.awaitLastSequentialItem(): T { */ suspend fun ReceiveTurbine.consumeItemsUntilPredicate( timeout: Duration = 100.milliseconds, + ignoreTimeoutError: Boolean = false, predicate: (T) -> Boolean, ): List { val items = ArrayList() - tryOrNull { - var foundItemOrFinished = false - while (!foundItemOrFinished) { + var exitLoop = false + try { + while (!exitLoop) { when (val event = withTurbineTimeout(timeout) { awaitEvent() }) { is Event.Item -> { 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 }