org.specs2.matcher.MapMatchers.scala Maven / Gradle / Ivy
package org.specs2
package matcher
import text.Quote._
import text.Plural._
import MatchResult._
import internal.scalaz._
import Scalaz._
/**
* Matchers for Maps
*/
trait MapMatchers extends MapBaseMatchers with MapBeHaveMatchers
object MapMatchers extends MapMatchers
private[specs2]
trait MapBaseMatchers {
/** matches if map.contains(k) */
def haveKey[K](k: K) = new Matcher[Iterable[(K, Any)]] {
def apply[S <: Iterable[(K, Any)]](map: Expectable[S]) = {
result(map.value.exists(_._1 == k),
map.description + " has the key " + q(k),
map.description + " doesn't have the key " + q(k),
map)
}
}
/** matches if map.contains(k) forall key k */
def haveKeys[K](keys: K*) = new Matcher[Iterable[(K, Any)]] {
def apply[S <: Iterable[(K, Any)]](map: Expectable[S]) = {
MatchersImplicits.forall(keys)(k => haveKey(k).apply(map)).map(m => map.value)
}
}
/** matches if map contains a pair (key, value) with value == v */
def haveValue[V](v: V) = new Matcher[Iterable[(Any, V)]] {
def apply[S <: Iterable[(Any, V)]](map: Expectable[S]) = {
result(map.value.exists(_._2 == v),
map.description + " has the value " + q(v),
map.description + " doesn't have the value " + q(v),
map)
}
}
/** matches if map contains a pair (key, value) with value == v for all value v*/
def haveValues[V](values: V*) = new Matcher[Iterable[(Any, V)]] {
def apply[S <: Iterable[(Any, V)]](map: Expectable[S]) = {
MatchersImplicits.forall(values)(v => haveValue(v).apply(map)).map(m => map.value)
}
}
/** matches if map contains a pair (key, value) == (k, v) */
def havePair[K, V](p: (K, V)) = new Matcher[Iterable[(K, V)]] {
def apply[S <: Iterable[(K, V)]](map: Expectable[S]) = {
result(map.value.exists(_ == p),
map.description + " has the pair " + q(p),
map.description + " doesn't have the pair " + q(p),
map)
}
}
/** matches if map contains all the specified pairs */
def havePairs[K, V](pairs: (K, V)*) = new Matcher[Iterable[(K, V)]] {
def apply[S <: Iterable[(K, V)]](map: Expectable[S]) = {
result(pairs.forall(pair => map.value.exists(_ == pair)),
map.description + " has the pairs " + q(pairs.mkString(", ")),
map.description + " doesn't have the pairs " + q(pairs.mkString(", ")),
map)
}
}
/** matches if the partial function is defined at those values */
def beDefinedAt[K](values: K*) = new Matcher[PartialFunction[K, Any]] {
def apply[S <: PartialFunction[K, Any]](f: Expectable[S]) = {
val isDefined = values.map(v => (v, f.value.isDefinedAt(v)))
val undefined = isDefined.filter(!_._2).map(_._1)
result(isDefined.map(_._2).forall(_ == true),
f.optionalDescription.getOrElse("the function") + noun(" is defined for the value").plural(values.size) +
" " + q(values.mkString(", ")),
f.optionalDescription.getOrElse("the function") +
noun(" is not defined for the value").plural(undefined.size) + " " +
q(undefined.mkString(", ")), f)
}
}
/** matches if the partial function is defined at those values and return expected values */
def beDefinedBy[K, V](values: (K, V)*) = new Matcher[PartialFunction[K, V]] {
def apply[S <: PartialFunction[K, V]](f: Expectable[S]) = {
val isDefined = values.map(v => (v, f.value.isDefinedAt(v._1) && f.value(v._1) == v._2))
val undefined = isDefined.filter(!_._2).map(_._1)
result(isDefined.map(_._2).forall(_ == true),
f.optionalDescription.getOrElse("the function") + noun(" is defined by the value").plural(values.size) + " " + q(values.mkString(", ")),
f.optionalDescription.getOrElse("the function") + noun(" is not defined by the value").plural(undefined.size) + " " + q(undefined.mkString(", ")),
f)
}
}
}
private[specs2]
trait MapBeHaveMatchers { outer: MapBaseMatchers =>
implicit def toMapKeyResultMatcher[K](result: MatchResult[Iterable[(K, Any)]]) = new MapKeyResultMatcher(result)
class MapKeyResultMatcher[K](result: MatchResult[Iterable[(K, Any)]]) {
def key(k: K) = result(outer.haveKey(k))
def keys(ks: K*) = result(outer.haveKeys(ks:_*))
def haveKey(k: K) = result(outer.haveKey(k))
def haveKeys(ks: K*) = result(outer.haveKeys(ks:_*))
}
implicit def toMapValueResultMatcher[V](result: MatchResult[Iterable[(Any, V)]]) = new MapValueResultMatcher(result)
class MapValueResultMatcher[V](result: MatchResult[Iterable[(Any, V)]]) {
def value(v: V) = result(outer.haveValue(v))
def values(vs: V*) = result(outer.haveValues(vs:_*))
def haveValue(v: V) = result(outer.haveValue(v))
def haveValues(vs: V*) = result(outer.haveValues(vs:_*))
}
implicit def toMapResultMatcher[K, V](result: MatchResult[Iterable[(K, V)]]) = new MapResultMatcher(result)
class MapResultMatcher[K, V](result: MatchResult[Iterable[(K, V)]]) {
def pair(p: (K, V)) = result(outer.havePair(p))
def pairs(pairs: (K, V)*) = result(outer.havePairs(pairs:_*))
def havePair(p: (K, V)) = result(outer.havePair(p))
def havePairs(pairs: (K, V)*) = result(outer.havePairs(pairs:_*))
}
implicit def toPartialFunctionResultMatcher[K, V](result: MatchResult[PartialFunction[K, V]]) = new PartialFunctionResultMatcher(result)
class PartialFunctionResultMatcher[K, V](result: MatchResult[PartialFunction[K, V]]) {
def definedAt(values: K*) = result(outer.beDefinedAt(values:_*))
def beDefinedAt(values: K*) = result(outer.beDefinedAt(values:_*))
def definedBy(values: (K, V)*) = result(outer.beDefinedBy(values:_*))
def beDefinedBy(values: (K, V)*) = result(outer.beDefinedBy(values:_*))
}
def key[K](k: K) = haveKey(k)
def keys[K](ks: K*) = haveKeys(ks:_*)
def value[V](v: V) = haveValue(v)
def values[V](vs: V*) = haveValues(vs:_*)
def pair[K, V](p: (K, V)) = havePair(p)
def pairs[K, V](pairs: (K, V)*) = havePairs(pairs:_*)
def definedAt[K](values: K*) = beDefinedAt(values:_*)
def definedBy[K, V](values: (K, V)*) = beDefinedBy(values:_*)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy