All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.specs2.matcher.EventuallyMatchers.scala Maven / Gradle / Ivy

There is a newer version: 5.5.8
Show newest version
package org.specs2
package matcher

import execute.*
import execute.ResultExecution.execute
import scala.concurrent.duration.*

/** This trait adds the possibility to retry a given matcher until it succeeds.
  *
  * This was contributed by @robey (http://robey.lag.net)
  */
trait EventuallyMatchers extends EventuallyResults:
  /** @param sleep
    *   the function applied on the retry number (first is 1)
    * @return
    *   a matcher that will retry the nested matcher a given number of times
    */
  def eventually[T](nested: =>Matcher[T], retries: Int, sleep: Int => Duration): Matcher[T] =
    new Matcher[T]:
      def apply[S <: T](a: Expectable[S]) = retry(0, a)

      @annotation.tailrec
      def retry[S <: T](retried: Int, a: Expectable[S]): Result =
        lazy val matchResult = nested(a.evaluateOnce)
        val result = matchResult.execute

        if result.isSuccess || retries <= 1 || retried == retries then result
        else
          val pause = sleep(retried).toMillis
          Thread.sleep(pause)
          retry(retried + 1, a)

  /** @return
    *   a matcher that will retry the nested matcher a given number of times
    */
  def eventually[T](nested: =>Matcher[T], retries: Int, sleep: Duration): Matcher[T] =
    eventually[T](nested, retries, (_: Int) => sleep)

  /** @return a matcher that will retry the nested matcher 40 times */
  def eventually[T](nested: =>Matcher[T]): Matcher[T] =
    eventually(nested, 40, (_: Int) => 100.millis)

object EventuallyMatchers extends EventuallyMatchers




© 2015 - 2024 Weber Informatics LLC | Privacy Policy