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

commonMain.io.kotest.property.arrow.optics.TraversalLaws.kt Maven / Gradle / Ivy

@file:Suppress("MemberVisibilityCanBePrivate", "unused")

package io.kotest.property.arrow.optics

import arrow.core.compose
import arrow.core.identity
import arrow.optics.Traversal
import io.kotest.property.Arb
import io.kotest.property.PropertyContext
import io.kotest.property.arrow.laws.Law
import io.kotest.property.arrow.laws.equalUnderTheLaw
import io.kotest.property.checkAll
import kotlin.math.max

public object TraversalLaws {

  public fun  laws(
    traversal: Traversal,
    aGen: Arb,
    bGen: Arb,
    funcGen: Arb<(B) -> B>,
    eq: (A, A) -> Boolean = { a, b -> a == b }
  ): List = listOf(
    Law("Traversal law: set is idempotent") { traversal.setIdempotent(aGen, bGen, eq) },
    Law("Traversal law: modify identity") { traversal.modifyIdentity(aGen, eq) },
    Law("Traversal law: compose modify") { traversal.composeModify(aGen, funcGen, eq) }
  )

  public suspend fun  Traversal.setIdempotent(aGen: Arb, bGen: Arb, eq: (A, A) -> Boolean): PropertyContext =
    checkAll(max(aGen.minIterations(), bGen.minIterations()), aGen, bGen) { a, b ->
      set(set(a, b), b)
        .equalUnderTheLaw(set(a, b), eq)
    }

  public suspend fun  Traversal.modifyIdentity(aGen: Arb, eq: (A, A) -> Boolean): PropertyContext =
    checkAll(aGen.minIterations(), aGen) { a ->
      modify(a, ::identity).equalUnderTheLaw(a, eq)
    }

  public suspend fun  Traversal.composeModify(
    aGen: Arb,
    funcGen: Arb<(B) -> B>,
    eq: (A, A) -> Boolean
  ): PropertyContext =
    checkAll(
      max(max(aGen.minIterations(), funcGen.minIterations()), funcGen.minIterations()),
      aGen,
      funcGen,
      funcGen
    ) { a, f, g ->
      modify(modify(a, f), g)
        .equalUnderTheLaw(modify(a, g compose f), eq)
    }
}