Skip to content

Commit

Permalink
fix EventuallyPredicate, add a producerless version, and inform user … (
Browse files Browse the repository at this point in the history
#2046)

* fix EventuallyPredicate, add a producerless version, and inform user about predicate failures for #2044

* remove eventuallypredicate

* remove eventuallyPredicate from tests
  • Loading branch information
jschneidereit committed Feb 9, 2021
1 parent 5640de8 commit 3d5a15a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
Expand Up @@ -20,7 +20,10 @@ import java.io.FileNotFoundException
import java.io.IOException
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import kotlin.time.*
import kotlin.time.TimeSource
import kotlin.time.days
import kotlin.time.milliseconds
import kotlin.time.seconds

class EventuallyTest : WordSpec() {

Expand Down
Expand Up @@ -70,7 +70,7 @@ suspend fun <T> eventually(duration: Duration, exceptionClass: KClass<out Throwa
suspend fun <T> eventually(
duration: Duration = Duration.INFINITE,
interval: Interval = 25.milliseconds.fixed(),
predicate: EventuallyPredicate<T> = EventuallyPredicate { true },
predicate: EventuallyPredicate<T> = { true },
listener: EventuallyListener<T> = EventuallyListener { },
retries: Int = Int.MAX_VALUE,
exceptionClass: KClass<out Throwable>? = null,
Expand All @@ -83,7 +83,7 @@ suspend fun <T> eventually(
*/
suspend fun <T> eventually(
config: EventuallyConfig,
predicate: EventuallyPredicate<T> = EventuallyPredicate { true },
predicate: EventuallyPredicate<T> = { true },
listener: EventuallyListener<T> = EventuallyListener { },
f: SuspendingProducer<T>,
): T {
Expand All @@ -92,13 +92,16 @@ suspend fun <T> eventually(
var times = 0
var firstError: Throwable? = null
var lastError: Throwable? = null
var predicateFailedTimes = 0

while (end.hasNotPassedNow() && times < config.retries) {
try {
val result = f()
listener.onEval(EventuallyState(result, start, end, times, firstError, lastError))
if (predicate.test(result)) {
if (predicate(result)) {
return result
} else {
predicateFailedTimes++
}
} catch (e: Throwable) {
if (AssertionError::class.isInstance(e) || config.exceptionClass?.isInstance(e) == true) {
Expand All @@ -118,6 +121,10 @@ suspend fun <T> eventually(
val message = StringBuilder().apply {
appendLine("Eventually block failed after ${config.duration}; attempted $times time(s); ${config.interval} delay between attempts")

if (predicateFailedTimes > 0) {
appendLine("The provided predicate failed $predicateFailedTimes times")
}

if (firstError != null) {
appendLine("The first error was caused by: ${firstError.message}")
appendLine(firstError.stackTraceToString())
Expand Down Expand Up @@ -153,9 +160,7 @@ data class EventuallyState<T>(
val thisError: Throwable?,
)

fun interface EventuallyPredicate<T> {
fun test(result: T): Boolean
}
typealias EventuallyPredicate<T> = (T) -> Boolean

fun interface EventuallyListener<T> {
fun onEval(state: EventuallyState<T>)
Expand Down

0 comments on commit 3d5a15a

Please sign in to comment.