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

commonMain.io.kotest.matchers.maps.MapMatchers.kt Maven / Gradle / Ivy

package io.kotest.matchers.maps

import io.kotest.fp.getOrElse
import io.kotest.fp.toOption
import io.kotest.matchers.Matcher
import io.kotest.matchers.MatcherResult
import io.kotest.matchers.string.Diff
import io.kotest.matchers.string.stringify

fun  haveKey(key: K): Matcher> = object : Matcher> {
  override fun test(value: Map) = MatcherResult(value.containsKey(key),
    "Map should contain key $key",
    "Map should not contain key $key")
}

fun  haveKeys(vararg keys: K): Matcher> = object : Matcher> {
  override fun test(value: Map): MatcherResult {
    val passed = keys.all { value.containsKey(it) }
    return MatcherResult(passed,
      "Map did not contain the keys ${keys.joinToString(", ")}",
      "Map should not contain the keys ${keys.joinToString(", ")}")
  }
}

fun  haveValue(v: V): Matcher> = object : Matcher> {
  override fun test(value: Map<*, V>) = MatcherResult(value.containsValue(v),
    "Map should contain value $v",
    "Map should not contain value $v")
}

fun  haveValues(vararg values: V): Matcher> = object : Matcher> {
  override fun test(value: Map<*, V>): MatcherResult {
    val passed = values.all { value.containsValue(it) }
    return MatcherResult(passed,
      "Map did not contain the values ${values.joinToString(", ")}",
      "Map should not contain the values ${values.joinToString(", ")}")
  }
}

fun  contain(key: K, v: V): Matcher> = object : Matcher> {
  override fun test(value: Map) = MatcherResult(value[key] == v,
    "Map should contain mapping $key=$v but was ${buildActualValue(value)}",
    "Map should not contain mapping $key=$v but was $value")

   private fun buildActualValue(map: Map) = map[key].toOption().map { "$key=$it" }.getOrElse(map)
}

fun  containAll(expected: Map): Matcher> =
  MapContainsMatcher(expected, ignoreExtraKeys = true)

fun  containExactly(expected: Map): Matcher> =
  MapContainsMatcher(expected)

fun  haveSize(size: Int): Matcher> = object : Matcher> {
   override fun test(value: Map) =
      MatcherResult(
         value.size == size,
         { "Map should have size $size but has size ${value.size}" },
         { "Map should not have size $size" }
      )
}

class MapContainsMatcher(
  private val expected: Map,
  private val ignoreExtraKeys: Boolean = false
) : Matcher> {
  override fun test(value: Map): MatcherResult {
    val diff = Diff.create(value, expected, ignoreExtraMapKeys = ignoreExtraKeys)
    val (expectMsg, negatedExpectMsg) = if (ignoreExtraKeys) {
      "should contain all of" to "should not contain all of"
    } else {
      "should be equal to" to "should not be equal to"
    }
    val (butMsg, negatedButMsg) = if (ignoreExtraKeys) {
      "but differs by" to "but contains"
    } else {
      "but differs by" to "but equals"
    }
    val failureMsg = """
      |
      |Expected:
      |  ${stringify(value)}
      |$expectMsg:
      |  ${stringify(expected)}
      |$butMsg:
      |${diff.toString(1)}
      |
      """.trimMargin()
    val negatedFailureMsg = """
      |
      |Expected:
      |  ${stringify(value)}
      |$negatedExpectMsg:
      |  ${stringify(expected)}
      |$negatedButMsg
      |
    """.trimMargin()
    return MatcherResult(
      diff.isEmpty(), failureMsg, negatedFailureMsg
    )
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy