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

jvmMain.io.kotest.assertions.arrow.either.matchers.kt Maven / Gradle / Ivy

package io.kotest.assertions.arrow.either

import arrow.core.Either
import io.kotest.matchers.Matcher
import io.kotest.matchers.MatcherResult
import io.kotest.matchers.types.beInstanceOf2
import io.kotest.matchers.should
import io.kotest.matchers.shouldNot
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract

@OptIn(ExperimentalContracts::class)
fun  Either<*, T>.shouldBeRight() {
  contract {
    returns() implies (this@shouldBeRight is Either.Right<*>)
  }
  this should beRight()
}

fun  Either.shouldNotBeRight() = this shouldNot beRight()
fun  beRight() =   beInstanceOf2, Either.Right>()

inline infix fun  Either<*, B>.shouldBeRight(fn: (B) -> Unit) {
  this should beRight()
  fn((this as Either.Right).b)
}

infix fun  Either.shouldBeRight(b: B) = this should beRight(b)
infix fun  Either.shouldNotBeRight(b: B) = this shouldNot beRight(b)
fun  beRight(b: B) = object : Matcher> {
  override fun test(value: Either): MatcherResult {
    return when (value) {
      is Either.Left -> {
        MatcherResult(false, "Either should be Right($b) but was Left(${value.a})", "Either should not be Right($b)")
      }
      is Either.Right -> {
        if (value.b == b)
          MatcherResult(true, "Either should be Right($b)", "Either should not be Right($b)")
        else
          MatcherResult(false, "Either should be Right($b) but was Right(${value.b})", "Either should not be Right($b)")
      }
    }
  }
}

@OptIn(ExperimentalContracts::class)
fun  Either.shouldBeLeft() {
  contract {
    returns() implies (this@shouldBeLeft is Either.Left<*>)
  }
  this should beLeft()
}

fun  Either.shouldNotBeLeft() = this shouldNot beLeft()
fun  beLeft() = beInstanceOf2, Either.Left>()

inline infix fun  Either.shouldBeLeft(fn: (A) -> Unit) {
  this should beLeft()
  fn((this as Either.Left).a)
}


infix fun  Either.shouldBeLeft(a: A) = this should beLeft(a)
infix fun  Either.shouldNotBeLeft(a: A) = this shouldNot beLeft(a)
fun  beLeft(a: A) = object : Matcher> {
  override fun test(value: Either): MatcherResult {
    return when (value) {
      is Either.Right -> {
        MatcherResult(false, "Either should be Left($a) but was Right(${value.b})", "Either should not be Right($a)")
      }
      is Either.Left -> {
        if (value.a == a)
          MatcherResult(true, "Either should be Left($a)", "Either should not be Left($a)")
        else
          MatcherResult(false, "Either should be Left($a) but was Left(${value.a})", "Either should not be Right($a)")
      }
    }
  }
}

inline fun  Either.shouldBeLeftOfType() = this should beLeftOfType()
inline fun  Either.shouldNotBeLeftOfType() = this shouldNot beLeftOfType()
inline fun  beLeftOfType() = object : Matcher> {
  override fun test(value: Either): MatcherResult {
    return when (value) {
      is Either.Right -> {
        MatcherResult(false, "Either should be Left<${A::class.qualifiedName}> but was Right(${value.b})", "")
      }
      is Either.Left -> {
        val valueA = value.a
        if (valueA is A)
          MatcherResult(true, "Either should be Left<${A::class.qualifiedName}>", "Either should not be Left")
        else
          MatcherResult(false,
              "Either should be Left<${A::class.qualifiedName}> but was Left<${if (valueA == null) "Null" else valueA::class.qualifiedName}>",
              "Either should not be Left")
      }
    }
  }
}