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

commonMain.io.kotest.assertions.until.FibonacciInterval.kt Maven / Gradle / Ivy

package io.kotest.assertions.until

import kotlin.time.Duration
import kotlin.time.ExperimentalTime
import kotlin.time.milliseconds

/**
 * Fibonacci delay implements a delay where each duration is calculated as a multiplier
 * of the fibonacci sequence, 0, 1, 1, 2, 3, 5....
 *
 * Some people start fib at 0, some at 1.
 * This implementation starts with 0 as per https://en.wikipedia.org/wiki/Fibonacci_number
 *
 * @param offset   Added to the count, so if the offset is 4, then the first value will be the 4th fib number.
 * @param base The duration that is multiplied by the fibonacci value
 */
@OptIn(ExperimentalTime::class)
class FibonacciInterval(private val base: Duration, private val offset: Int) : Interval {

   init {
      require(offset >= 0) { "Offset must be greater than or equal to 0" }
   }

   override fun next(count: Int): Duration {
      val baseMs = base.toLongMilliseconds()
      val total = baseMs * fibonacci(offset + count)
      return total.milliseconds
   }
}

@OptIn(ExperimentalTime::class)
@Deprecated("use duration.fibonacci()")
fun fibonacciInterval(base: Duration) = FibonacciInterval(base, 0)

@OptIn(ExperimentalTime::class)
@Deprecated("use duration.fibonacci()")
fun fibonacciInterval(offset: Int, base: Duration) = FibonacciInterval(base, offset)

@OptIn(ExperimentalTime::class)
fun Duration.fibonacci() = FibonacciInterval(this, 0)

fun fibonacci(n: Int): Int {
   tailrec fun fib(k: Int, current: Int, previous: Int): Int = when (k) {
      0 -> previous
      1 -> current
      else -> fib(k - 1, current + previous, current)
   }
   return fib(n, 1, 0)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy