org.scalatest.matchers.dsl.ContainWord.scala Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2001-2013 Artima, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.scalatest.matchers.dsl
import org.scalatest.matchers._
import scala.collection.GenTraversable
import org.scalactic._
import org.scalatest.FailureMessages
import org.scalatest.Resources
import org.scalatest.UnquotedString
import org.scalactic.{Equality, Every}
import org.scalatest.enablers.Containing
import org.scalatest.enablers.Aggregating
import org.scalatest.enablers.Sequencing
import org.scalatest.enablers.KeyMapping
import org.scalatest.enablers.ValueMapping
import org.scalatest.exceptions.NotAllowedException
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers
for an overview of
* the matchers DSL.
*
* @author Bill Venners
*/
final class ContainWord {
/**
* This method enables the following syntax:
*
*
* list should contain (null)
* ^
*
**/
def apply(nullValue: Null): MatcherFactory1[Any, Containing] =
new MatcherFactory1[Any, Containing] {
def matcher[U <: Any : Containing]: Matcher[U] =
new Matcher[U] {
def apply(left: U): MatchResult = {
val containing = implicitly[Containing[U]]
MatchResult(
containing.contains(left, null),
Resources.rawDidNotContainNull,
Resources.rawContainedNull,
Vector(left)
)
}
override def toString: String = "contain (null)"
}
override def toString: String = "contain (null)"
}
/**
* This method enables the following syntax:
*
*
* Array(1, 2) should (contain (2) and contain (1))
* ^
*
**/
def apply(expectedElement: Any): MatcherFactory1[Any, Containing] =
new MatcherFactory1[Any, Containing] {
def matcher[U <: Any : Containing]: Matcher[U] =
new Matcher[U] {
def apply(left: U): MatchResult = {
val containing = implicitly[Containing[U]]
MatchResult(
containing.contains(left, expectedElement),
Resources.rawDidNotContainExpectedElement,
Resources.rawContainedExpectedElement,
Vector(left, expectedElement)
)
}
override def toString: String = "contain (" + Prettifier.default(expectedElement) + ")"
}
override def toString: String = "contain (" + Prettifier.default(expectedElement) + ")"
}
//
// This key method is called when "contain" is used in a logical expression, such as:
// map should { contain key 1 and equal (Map(1 -> "Howdy")) }. It results in a matcher
// that remembers the key value. By making the value type Any, it causes overloaded shoulds
// to work, because for example a Matcher[GenMap[Int, Any]] is a subtype of Matcher[GenMap[Int, String]],
// given Map is covariant in its V (the value type stored in the map) parameter and Matcher is
// contravariant in its lone type parameter. Thus, the type of the Matcher resulting from contain key 1
// is a subtype of the map type that has a known value type parameter because its that of the map
// to the left of should. This means the should method that takes a map will be selected by Scala's
// method overloading rules.
//
/**
* This method enables the following syntax:
*
*
* map should (contain key ("fifty five") or contain key ("twenty two"))
* ^
*
*
* The map's value type parameter cannot be inferred because only a key type is provided in
* an expression like (contain key ("fifty five"))
. The matcher returned
* by this method matches scala.collection.Map
s with the inferred key type and value type Any
. Given
* Map
is covariant in its value type, and Matcher
is contravariant in
* its type parameter, a Matcher[Map[Int, Any]]
, for example, is a subtype of Matcher[Map[Int, String]]
.
* This will enable the matcher returned by this method to be used against any Map
that has
* the inferred key type.
*/
infix def key[K](expectedKey: Any): MatcherFactory1[Any, KeyMapping] =
new MatcherFactory1[Any, KeyMapping] {
def matcher[U <: Any : KeyMapping]: Matcher[U] =
new Matcher[U] {
def apply(left: U): MatchResult = {
val keyMapping = implicitly[KeyMapping[U]]
MatchResult(
keyMapping.containsKey(left, expectedKey),
Resources.rawDidNotContainKey,
Resources.rawContainedKey,
Vector(left, expectedKey)
)
}
override def toString: String = "contain key " + Prettifier.default(expectedKey)
}
override def toString: String = "contain key " + Prettifier.default(expectedKey)
}
// Holy smokes I'm starting to scare myself. I fixed the problem of the compiler not being
// able to infer the value type in contain value 1 and ... like expressions, because the
// value type is there, with an existential type. Since I don't know what K is, I decided to
// try just saying that with an existential type, and it compiled and ran. Pretty darned
// amazing compiler. The problem could not be fixed like I fixed the key method above, because
// Maps are nonvariant in their key type parameter, whereas they are covariant in their value
// type parameter, so the same trick wouldn't work. But this existential type trick seems to
// work like a charm.
/**
* This method enables the following syntax:
*
*
* Map("one" -> 1, "two" -> 2) should (not contain value (5) and not contain value (3))
* ^
*
*
* The map's key type parameter cannot be inferred because only a value type is provided in
* an expression like (contain value (5))
. The matcher returned
* by this method matches scala.collection.Map
s with the inferred value type and the existential key
* type [K] forSome { type K }
. Even though Matcher
is contravariant in its type parameter, because
* Map
is nonvariant in its key type,
* a Matcher[Map[Any, Int]]
, for example, is not a subtype of Matcher[Map[String, Int]]
,
* so the key type parameter of the Map
returned by this method cannot be Any
. By making it
* an existential type, the Scala compiler will not infer it to anything more specific.
* This will enable the matcher returned by this method to be used against any Map
that has
* the inferred value type.
*
*/
infix def value[K](expectedValue: Any): MatcherFactory1[Any, ValueMapping] =
new MatcherFactory1[Any, ValueMapping] {
def matcher[U <: Any : ValueMapping]: Matcher[U] =
new Matcher[U] {
def apply(left: U): MatchResult = {
val valueMapping = implicitly[ValueMapping[U]]
MatchResult(
valueMapping.containsValue(left, expectedValue),
Resources.rawDidNotContainValue,
Resources.rawContainedValue,
Vector(left, expectedValue)
)
}
override def toString: String = "contain value " + Prettifier.default(expectedValue)
}
override def toString: String = "contain value " + Prettifier.default(expectedValue)
}
/**
* This method enables the following syntax, where positiveNumber
and validNumber
are, for example, of type AMatcher
:
*
*
* Array(1, 2, 3) should (contain a positiveNumber and contain a validNumber)
* ^
*
**/
infix private[scalatest] def a[T](aMatcher: AMatcher[T]): Matcher[GenTraversable[T]] =
new Matcher[GenTraversable[T]] {
def apply(left: GenTraversable[T]): MatchResult = {
val matched = left.find(aMatcher(_).matches)
MatchResult(
matched.isDefined,
Resources.rawDidNotContainA,
Resources.rawContainedA,
Vector(left, UnquotedString(aMatcher.nounName)),
Vector(left, UnquotedString(aMatcher.nounName), UnquotedString(if (matched.isDefined) aMatcher(matched.get).negatedFailureMessage(Prettifier.default) else "-"))
)
}
override def toString: String = "contain a " + Prettifier.default(aMatcher)
}
/**
* This method enables the following syntax, where oddNumber
and invalidNumber
are, for example, of type AnMatcher
:
*
*
* Array(1, 2, 3) should (contain an oddNumber and contain an invalidNumber)
* ^
*
**/
infix private[scalatest] def an[T](anMatcher: AnMatcher[T]): Matcher[GenTraversable[T]] =
new Matcher[GenTraversable[T]] {
def apply(left: GenTraversable[T]): MatchResult = {
val matched = left.find(anMatcher(_).matches)
MatchResult(
matched.isDefined,
Resources.rawDidNotContainAn,
Resources.rawContainedAn,
Vector(left, UnquotedString(anMatcher.nounName)),
Vector(left, UnquotedString(anMatcher.nounName), UnquotedString(if (matched.isDefined) anMatcher(matched.get).negatedFailureMessage(Prettifier.default) else "-"))
)
}
override def toString: String = "contain an " + Prettifier.default(anMatcher)
}
infix def oneOf(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit prettifier: Prettifier, pos: source.Position): MatcherFactory1[Any, Containing] = {
val right = firstEle :: secondEle :: remainingEles.toList
if (right.distinct.size != right.size)
throw new NotAllowedException(FailureMessages.oneOfDuplicate, pos)
new MatcherFactory1[Any, Containing] {
def matcher[T](implicit containing: Containing[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
containing.containsOneOf(left, right),
Resources.rawDidNotContainOneOfElements,
Resources.rawContainedOneOfElements,
Vector(left, UnquotedString(right.map(r => FailureMessages.decorateToStringValue(prettifier, r)).mkString(", ")))
)
}
override def toString: String = "contain oneOf (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
override def toString: String = "contain oneOf (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
infix def oneElementOf(elements: GenTraversable[Any]): MatcherFactory1[Any, Containing] = {
val right = elements.toList
new MatcherFactory1[Any, Containing] {
def matcher[T](implicit containing: Containing[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
containing.containsOneOf(left, right.distinct),
Resources.rawDidNotContainOneElementOf,
Resources.rawContainedOneElementOf,
Vector(left, right)
)
}
override def toString: String = "contain oneElementOf " + Prettifier.default(right)
}
}
override def toString: String = "contain oneElementOf " + Prettifier.default(right)
}
}
infix def atLeastOneOf(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit prettifier: Prettifier, pos: source.Position): MatcherFactory1[Any, Aggregating] = {
val right = firstEle :: secondEle :: remainingEles.toList
if (right.distinct.size != right.size)
throw new NotAllowedException(FailureMessages.atLeastOneOfDuplicate, pos)
new MatcherFactory1[Any, Aggregating] {
def matcher[T](implicit aggregating: Aggregating[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
aggregating.containsAtLeastOneOf(left, right),
Resources.rawDidNotContainAtLeastOneOf,
Resources.rawContainedAtLeastOneOf,
Vector(left, UnquotedString(right.map(r => FailureMessages.decorateToStringValue(prettifier, r)).mkString(", ")))
)
}
override def toString: String = "contain atLeastOneOf (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
override def toString: String = "contain atLeastOneOf (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
infix def atLeastOneElementOf(elements: GenTraversable[Any]): MatcherFactory1[Any, Aggregating] = {
val right = elements.toList
new MatcherFactory1[Any, Aggregating] {
def matcher[T](implicit aggregating: Aggregating[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
aggregating.containsAtLeastOneOf(left, right),
Resources.rawDidNotContainAtLeastOneElementOf,
Resources.rawContainedAtLeastOneElementOf,
Vector(left, right)
)
}
override def toString: String = "contain atLeastOneElementOf " + Prettifier.default(right)
}
}
override def toString: String = "contain atLeastOneElementOf " + Prettifier.default(right)
}
}
infix def noneOf(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit prettifier: Prettifier, pos: source.Position): MatcherFactory1[Any, Containing] = {
val right = firstEle :: secondEle :: remainingEles.toList
if (right.distinct.size != right.size)
throw new NotAllowedException(FailureMessages.noneOfDuplicate, pos)
new MatcherFactory1[Any, Containing] {
def matcher[T](implicit containing: Containing[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
containing.containsNoneOf(left, right),
Resources.rawContainedAtLeastOneOf,
Resources.rawDidNotContainAtLeastOneOf,
Vector(left, UnquotedString(right.map(r => FailureMessages.decorateToStringValue(prettifier, r)).mkString(", ")))
)
}
override def toString: String = "contain noneOf (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
override def toString: String = "contain noneOf (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
infix def noElementsOf(elements: GenTraversable[Any]): MatcherFactory1[Any, Containing] = {
val right = elements.toList
new MatcherFactory1[Any, Containing] {
def matcher[T](implicit containing: Containing[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
containing.containsNoneOf(left, right.distinct),
Resources.rawContainedAtLeastOneElementOf,
Resources.rawDidNotContainAtLeastOneElementOf,
Vector(left, right)
)
}
override def toString: String = "contain noElementsOf (" + Prettifier.default(right) + ")"
}
}
override def toString: String = "contain noElementsOf (" + Prettifier.default(right) + ")"
}
}
infix def theSameElementsAs(right: GenTraversable[Any]): MatcherFactory1[Any, Aggregating] = {
new MatcherFactory1[Any, Aggregating] {
def matcher[T](implicit aggregating: Aggregating[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
aggregating.containsTheSameElementsAs(left, right),
Resources.rawDidNotContainSameElements,
Resources.rawContainedSameElements,
Vector(left, right)
)
}
override def toString: String = "contain theSameElementsAs " + Prettifier.default(right)
}
}
override def toString: String = "contain theSameElementsAs " + Prettifier.default(right)
}
}
infix def theSameElementsInOrderAs(right: GenTraversable[Any]): MatcherFactory1[Any, Sequencing] = {
new MatcherFactory1[Any, Sequencing] {
def matcher[T](implicit sequencing: Sequencing[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
sequencing.containsTheSameElementsInOrderAs(left, right),
Resources.rawDidNotContainSameElementsInOrder,
Resources.rawContainedSameElementsInOrder,
Vector(left, right)
)
}
override def toString: String = "contain theSameElementsInOrderAs " + Prettifier.default(right)
}
}
override def toString: String = "contain theSameElementsInOrderAs " + Prettifier.default(right)
}
}
infix def only(right: Any*)(implicit prettifier: Prettifier, pos: source.Position): MatcherFactory1[Any, Aggregating] = {
if (right.isEmpty)
throw new NotAllowedException(FailureMessages.onlyEmpty, pos)
if (right.distinct.size != right.size)
throw new NotAllowedException(FailureMessages.onlyDuplicate, pos)
new MatcherFactory1[Any, Aggregating] {
def matcher[T](implicit aggregating: Aggregating[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
val withFriendlyReminder = right.size == 1 && (right(0).isInstanceOf[scala.collection.GenTraversable[_]] || right(0).isInstanceOf[Every[_]])
MatchResult(
aggregating.containsOnly(left, right),
if (withFriendlyReminder) Resources.rawDidNotContainOnlyElementsWithFriendlyReminder else Resources.rawDidNotContainOnlyElements,
if (withFriendlyReminder) Resources.rawContainedOnlyElementsWithFriendlyReminder else Resources.rawContainedOnlyElements,
Vector(left, UnquotedString(right.map(r => FailureMessages.decorateToStringValue(prettifier, r)).mkString(", ")))
)
}
override def toString: String = "contain only (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
override def toString: String = "contain only (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
infix def inOrderOnly(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit prettifier: Prettifier, pos: source.Position): MatcherFactory1[Any, Sequencing] = {
val right = firstEle :: secondEle :: remainingEles.toList
if (right.distinct.size != right.size)
throw new NotAllowedException(FailureMessages.inOrderOnlyDuplicate, pos)
new MatcherFactory1[Any, Sequencing] {
def matcher[T](implicit sequencing: Sequencing[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
sequencing.containsInOrderOnly(left, right),
Resources.rawDidNotContainInOrderOnlyElements,
Resources.rawContainedInOrderOnlyElements,
Vector(left, UnquotedString(right.map(r => FailureMessages.decorateToStringValue(prettifier, r)).mkString(", ")))
)
}
override def toString: String = "contain inOrderOnly (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
override def toString: String = "contain inOrderOnly (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
infix def allOf(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit prettifier: Prettifier, pos: source.Position): MatcherFactory1[Any, Aggregating] = {
val right = firstEle :: secondEle :: remainingEles.toList
if (right.distinct.size != right.size)
throw new NotAllowedException(FailureMessages.allOfDuplicate, pos)
new MatcherFactory1[Any, Aggregating] {
def matcher[T](implicit aggregating: Aggregating[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
aggregating.containsAllOf(left, right),
Resources.rawDidNotContainAllOfElements,
Resources.rawContainedAllOfElements,
Vector(left, UnquotedString(right.map(r => FailureMessages.decorateToStringValue(prettifier, r)).mkString(", ")))
)
}
override def toString: String = "contain allOf (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
override def toString: String = "contain allOf (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
infix def allElementsOf(elements: GenTraversable[Any]): MatcherFactory1[Any, Aggregating] = {
val right = elements.toList
new MatcherFactory1[Any, Aggregating] {
def matcher[T](implicit aggregating: Aggregating[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
aggregating.containsAllOf(left, right.distinct),
Resources.rawDidNotContainAllElementsOf,
Resources.rawContainedAllElementsOf,
Vector(left, right)
)
}
override def toString: String = "contain allElementsOf " + Prettifier.default(right)
}
}
override def toString: String = "contain allElementsOf " + Prettifier.default(right)
}
}
infix def inOrder(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit prettifier: Prettifier, pos: source.Position): MatcherFactory1[Any, Sequencing] = {
val right = firstEle :: secondEle :: remainingEles.toList
if (right.distinct.size != right.size)
throw new NotAllowedException(FailureMessages.inOrderDuplicate, pos)
new MatcherFactory1[Any, Sequencing] {
def matcher[T](implicit sequencing: Sequencing[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
sequencing.containsInOrder(left, right),
Resources.rawDidNotContainAllOfElementsInOrder,
Resources.rawContainedAllOfElementsInOrder,
Vector(left, UnquotedString(right.map(r => FailureMessages.decorateToStringValue(prettifier, r)).mkString(", ")))
)
}
override def toString: String = "contain inOrder (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
override def toString: String = "contain inOrder (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
infix def inOrderElementsOf(elements: GenTraversable[Any]): MatcherFactory1[Any, Sequencing] = {
val right = elements.toList
new MatcherFactory1[Any, Sequencing] {
def matcher[T](implicit sequencing: Sequencing[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
sequencing.containsInOrder(left, right.distinct),
Resources.rawDidNotContainAllElementsOfInOrder,
Resources.rawContainedAllElementsOfInOrder,
Vector(left, right)
)
}
override def toString: String = "contain inOrderElementsOf (" + Prettifier.default(right) + ")"
}
}
override def toString: String = "contain inOrderElementsOf (" + Prettifier.default(right) + ")"
}
}
infix def atMostOneOf(firstEle: Any, secondEle: Any, remainingEles: Any*)(implicit prettifier: Prettifier, pos: source.Position): MatcherFactory1[Any, Aggregating] = {
val right = firstEle :: secondEle :: remainingEles.toList
if (right.distinct.size != right.size)
throw new NotAllowedException(FailureMessages.atMostOneOfDuplicate, pos)
new MatcherFactory1[Any, Aggregating] {
def matcher[T](implicit aggregating: Aggregating[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
aggregating.containsAtMostOneOf(left, right),
Resources.rawDidNotContainAtMostOneOf,
Resources.rawContainedAtMostOneOf,
Vector(left, UnquotedString(right.map(r => FailureMessages.decorateToStringValue(prettifier, r)).mkString(", ")))
)
}
override def toString: String = "contain atMostOneOf (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
override def toString: String = "contain atMostOneOf (" + right.map(Prettifier.default(_)).mkString(", ") + ")"
}
}
infix def atMostOneElementOf(elements: GenTraversable[Any]): MatcherFactory1[Any, Aggregating] = {
val right = elements.toList
new MatcherFactory1[Any, Aggregating] {
def matcher[T](implicit aggregating: Aggregating[T]): Matcher[T] = {
new Matcher[T] {
def apply(left: T): MatchResult = {
MatchResult(
aggregating.containsAtMostOneOf(left, right.distinct),
Resources.rawDidNotContainAtMostOneElementOf,
Resources.rawContainedAtMostOneElementOf,
Vector(left, right)
)
}
override def toString: String = "contain atMostOneElementOf (" + Prettifier.default(right) + ")"
}
}
override def toString: String = "contain atMostOneElementOf (" + Prettifier.default(right) + ")"
}
}
/**
* Overrides toString to return "contain"
*/
override def toString: String = "contain"
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy