org.scalatest.words.BeWord.scala Maven / Gradle / Ivy
Show all versions of scalatest_2.11.0-M5 Show documentation
/*
* 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.words
import org.scalatest.matchers._
import org.scalautils._
import org.scalautils.TripleEqualsSupport.Spread
import org.scalatest.FailureMessages
import org.scalatest.Resources
import org.scalatest.UnquotedString
import org.scalatest.Suite
import org.scalatest.Assertions.areEqualComparingArraysStructurally
import org.scalatest.MatchersHelper.matchSymbolToPredicateMethod
import org.scalatest.enablers.Sequencing
import org.scalatest.enablers.Sortable
import org.scalatest.enablers.Readability
import org.scalatest.enablers.Writability
import org.scalatest.enablers.Emptiness
import org.scalatest.enablers.Definition
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* Class BeWord
contains an apply
method that takes a Symbol
, which uses reflection
* to find and access a Boolean
property and determine if it is true
.
* If the symbol passed is 'empty
, for example, the apply
method
* will use reflection to look for a public Java field named
* "empty", a public method named "empty", or a public method named "isEmpty". If a field, it must be of type Boolean
.
* If a method, it must take no parameters and return Boolean
. If multiple candidates are found,
* the apply
method will select based on the following algorithm:
*
*
*
* Field Method "is" Method Result
* Throws TestFailedException
, because no candidates found
* isEmpty()
Invokes isEmpty()
* empty()
Invokes empty()
* empty()
isEmpty()
Invokes empty()
(this can occur when BeanProperty
annotation is used)
* empty
Accesses field empty
* empty
isEmpty()
Invokes isEmpty()
* empty
empty()
Invokes empty()
* empty
empty()
isEmpty()
Invokes empty()
(this can occur when BeanProperty
annotation is used)
*
*
* @author Bill Venners
*/
final class BeWord {
/**
* This method enables the following syntax:
*
*
* result should be < (7)
* ^
*
*
*
* Note that the less than operator will be invoked on be
in this expression, not
* on a result of passing be
to should
, as with most other operators
* in the matchers DSL, because the less than operator has a higher precedence than should
.
* Thus in the above case the first expression evaluated will be be < (7)
, which results
* in a matcher that is passed to should
.
*
*
*
* This method also enables the following syntax:
*
*
*
* result should not (be < (7))
* ^
*
*/
def <[T : Ordering](right: T): Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = {
val ordering = implicitly[Ordering[T]]
MatchResult(
ordering.lt(left, right), // left < right
Resources("wasNotLessThan"),
Resources("wasLessThan"),
Vector(left, right)
)
}
override def toString: String = "be < " + Prettifier.default(right)
}
/**
* This method enables the following syntax:
*
*
* result should be > (7)
* ^
*
*
*
* Note that the greater than operator will be invoked on be
in this expression, not
* on a result of passing be
to should
, as with most other operators
* in the matchers DSL, because the greater than operator has a higher precedence than should
.
* Thus in the above case the first expression evaluated will be be > (7)
, which results
* in a matcher that is passed to should
.
*
*
*
* This method also enables the following syntax:
*
*
*
* result should not (be > (7))
* ^
*
*/
def >[T : Ordering](right: T): Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = {
val ordering = implicitly[Ordering[T]]
MatchResult(
ordering.gt(left, right), // left > right
Resources("wasNotGreaterThan"),
Resources("wasGreaterThan"),
Vector(left, right)
)
}
override def toString: String = "be > " + Prettifier.default(right)
}
/**
* This method enables the following syntax:
*
*
* result should be <= (7)
* ^
*
*
*
* Note that the less than or equal to operator will be invoked on be
in this expression, not
* on a result of passing be
to should
, as with most other operators
* in the matchers DSL, because the less than or equal to operator has a higher precedence than should
.
* Thus in the above case the first expression evaluated will be be <= (7)
, which results
* in a matcher that is passed to should
.
*
*
*
* This method also enables the following syntax:
*
*
*
* result should not (be <= (7))
* ^
*
*/
def <=[T : Ordering](right: T): Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = {
val ordering = implicitly[Ordering[T]]
MatchResult(
ordering.lteq(left, right), // left <= right
Resources("wasNotLessThanOrEqualTo"),
Resources("wasLessThanOrEqualTo"),
Vector(left, right)
)
}
override def toString: String = "be <= " + Prettifier.default(right)
}
/**
* This method enables the following syntax:
*
*
* result should be >= (7)
* ^
*
*
*
* Note that the greater than or equal to operator will be invoked on be
in this expression, not
* on a result of passing be
to should
, as with most other operators
* in the matchers DSL, because the greater than or equal to operator has a higher precedence than should
.
* Thus in the above case the first expression evaluated will be be >= (7)
, which results
* in a matcher that is passed to should
.
*
*
*
* This method also enables the following syntax:
*
*
*
* result should not (be >= (7))
* ^
*
*/
def >=[T : Ordering](right: T): Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = {
val ordering = implicitly[Ordering[T]]
MatchResult(
ordering.gteq(left, right), // left >= right
Resources("wasNotGreaterThanOrEqualTo"),
Resources("wasGreaterThanOrEqualTo"),
Vector(left, right)
)
}
override def toString: String = "be >= " + Prettifier.default(right)
}
/**
*
* The should be === syntax has been deprecated and will be removed in a future version of ScalaTest. Please use should equal, should ===, shouldEqual,
* should be, or shouldBe instead. Note, the reason this was deprecated was so that === would mean only one thing in ScalaTest: a customizable, type-
* checkable equality comparison.
*
*
*
* This method enables the following syntax:
*
*
*
* result should be === (7)
* ^
*
*
*
* Note that the === operator will be invoked on be
in this expression, not
* on a result of passing be
to should
, as with most other operators
* in the matchers DSL, because the ===n operator has a higher precedence than should
.
* Thus in the above case the first expression evaluated will be be === (7)
, which results
* in a matcher that is passed to should
.
*
*
*
* This method also enables the following syntax:
*
*
*
* result should not (be === (7))
* ^
*
*/
@deprecated("The should be === syntax has been deprecated. Please use should equal, should ===, shouldEqual, should be, or shouldBe instead.")
def ===(right: Any): Matcher[Any] =
new Matcher[Any] {
def apply(left: Any): MatchResult = {
val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) // TODO: Should move this part to reporter
MatchResult(
areEqualComparingArraysStructurally(left, right),
Resources("wasNotEqualTo"),
Resources("wasEqualTo"),
Vector(leftee, rightee),
Vector(left, right)
)
}
override def toString: String = "be === " + Prettifier.default(right)
}
/**
* This method enables the following syntax:
*
*
* fileMock should not { be a ('file) }
* ^
*
*/
def a(right: Symbol): Matcher[AnyRef] =
new Matcher[AnyRef] {
def apply(left: AnyRef): MatchResult = matchSymbolToPredicateMethod(left, right, true, true)
override def toString: String = "be a " + Prettifier.default(right)
}
/**
* This method enables the following syntax, where fileMock
is, for example, of type File
and
* file
refers to a BePropertyMatcher[File]
:
*
*
* fileMock should not { be a (file) }
* ^
*
*/
def a[S <: AnyRef](bePropertyMatcher: BePropertyMatcher[S]): Matcher[S] =
new Matcher[S] {
def apply(left: S): MatchResult = {
val result = bePropertyMatcher(left)
MatchResult(
result.matches,
FailureMessages("wasNotA"),
FailureMessages("wasA"),
Vector(left, UnquotedString(result.propertyName))
)
}
override def toString: String = "be a " + Prettifier.default(bePropertyMatcher)
}
/**
* This method enables the following syntax, where negativeNumber
is, for example, of type AMatcher
:
*
*
* 8 should not { be a (negativeNumber) }
* ^
*
*/
def a[S](aMatcher: AMatcher[S]): Matcher[S] =
new Matcher[S] {
def apply(left: S): MatchResult = aMatcher(left)
override def toString: String = "be a " + Prettifier.default(aMatcher)
}
/**
* This method enables the following syntax:
*
*
* animal should not { be an ('elephant) }
* ^
*
*/
def an(right: Symbol): Matcher[AnyRef] =
new Matcher[AnyRef] {
def apply(left: AnyRef): MatchResult = matchSymbolToPredicateMethod(left, right, true, false)
override def toString: String = "be an " + Prettifier.default(right)
}
/**
* This method enables the following syntax, where keyEvent
is, for example, of type KeyEvent
and
* actionKey
refers to a BePropertyMatcher[KeyEvent]
:
*
*
* keyEvent should not { be an (actionKey) }
* ^
*
*/
def an[S <: AnyRef](bePropertyMatcher: BePropertyMatcher[S]): Matcher[S] =
new Matcher[S] {
def apply(left: S): MatchResult = {
val result = bePropertyMatcher(left)
MatchResult(
result.matches,
Resources("wasNotAn"),
Resources("wasAn"),
Vector(left, UnquotedString(result.propertyName))
)
}
override def toString: String = "be an " + Prettifier.default(bePropertyMatcher)
}
/**
* This method enables the following syntax, where oddNumber
is, for example, of type AnMatcher
:
*
*
* 8 should not { be an (oddNumber) }
* ^
*
*/
def an[S](anMatcher: AnMatcher[S]): Matcher[S] =
new Matcher[S] {
def apply(left: S): MatchResult = anMatcher(left)
override def toString: String = "be an " + Prettifier.default(anMatcher)
}
/**
* This method enables the following syntax for the "primitive" numeric types:
*
*
* sevenDotOh should be (7.1 plusOrMinus 0.2)
* ^
*
*/
def apply[U](spread: Spread[U]): Matcher[U] =
new Matcher[U] {
def apply(left: U): MatchResult = {
MatchResult(
spread.isWithin(left),
Resources("wasNotPlusOrMinus"),
Resources("wasPlusOrMinus"),
Vector(left, spread.pivot, spread.tolerance)
)
}
override def toString: String = "be (" + Prettifier.default(spread) + ")"
}
/**
* This method enables the following syntax:
*
*
* result should be theSameInstancreAs (anotherObject)
* ^
*
*/
def theSameInstanceAs(right: AnyRef): Matcher[AnyRef] =
new Matcher[AnyRef] {
def apply(left: AnyRef): MatchResult =
MatchResult(
left eq right,
Resources("wasNotSameInstanceAs"),
Resources("wasSameInstanceAs"),
Vector(left, right)
)
override def toString: String = "be theSameInstanceAs " + Prettifier.default(right)
}
/**
* This method enables the following syntax:
*
*
* result should be (true)
* ^
*
*/
def apply(right: Boolean): Matcher[Boolean] =
new Matcher[Boolean] {
def apply(left: Boolean): MatchResult =
MatchResult(
left == right,
Resources("wasNot"),
Resources("was"),
Vector(left, right)
)
override def toString: String = "be (" + Prettifier.default(right) + ")"
}
/**
* This method enables the following syntax:
*
*
* result should be (null)
* ^
*
*/
def apply(o: Null): Matcher[AnyRef] =
new Matcher[AnyRef] {
def apply(left: AnyRef): MatchResult = {
MatchResult(
left == null,
Resources("wasNotNull"),
Resources("wasNull"),
Resources("wasNotNull"),
Resources("midSentenceWasNull"),
Vector(left),
Vector.empty
)
}
override def toString: String = "be (null)"
}
/* *
* This method enables the following syntax:
*
*
* set should be ('empty)
* ^
*
def apply[T](right: AType[T]): Matcher[Any] =
new Matcher[Any] {
def apply(left: Any): MatchResult =
MatchResult(
right.isAssignableFromClassOf(left),
FailureMessages("wasNotAnInstanceOf", left, UnquotedString(right.className)),
FailureMessages("wasAnInstanceOf"), // TODO, missing the left, right.className here. Write a test and fix it.
FailureMessages("wasNotAnInstanceOf", left, UnquotedString(right.className)),
FailureMessages("wasAnInstanceOf")
)
}
*/
/**
* This method enables the following syntax:
*
*
* set should be ('empty)
* ^
*
*/
def apply(right: Symbol): Matcher[AnyRef] =
new Matcher[AnyRef] {
def apply(left: AnyRef): MatchResult = matchSymbolToPredicateMethod(left, right, false, false)
override def toString: String = "be (" + Prettifier.default(right) + ")"
}
/**
* This method enables the following syntax, where num
is, for example, of type Int
and
* odd
refers to a BeMatcher[Int]
:
*
*
* num should be (odd)
* ^
*
*/
def apply[T](right: BeMatcher[T]): Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = right(left)
override def toString: String = "be (" + Prettifier.default(right) + ")"
}
/**
* This method enables the following syntax, where open
refers to a BePropertyMatcher
:
*
*
* door should be (open)
* ^
*
*/
def apply[T](bePropertyMatcher: BePropertyMatcher[T]): Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = {
val result = bePropertyMatcher(left)
MatchResult(
result.matches,
Resources("wasNot"),
Resources("was"),
Vector(left, UnquotedString(result.propertyName))
)
}
override def toString: String = "be (" + Prettifier.default(bePropertyMatcher) + ")"
}
/**
* This method enables be
to be used for equality comparison. Here are some examples:
*
*
* result should be (None)
* ^
* result should be (Some(1))
* ^
* result should be (true)
* ^
* result should be (false)
* ^
* sum should be (19)
* ^
*
*/
def apply(right: Any): Matcher[Any] =
new Matcher[Any] {
def apply(left: Any): MatchResult = {
val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) // TODO: To move this to reporter
MatchResult(
areEqualComparingArraysStructurally(left, right),
Resources("wasNotEqualTo"),
Resources("wasEqualTo"),
Vector(leftee, rightee),
Vector(left, right)
)
}
override def toString: String = "be (" + Prettifier.default(right) + ")"
}
/**
* This method enables the following syntax, where open
refers to a BePropertyMatcher
:
*
*
* List(1, 2, 3) should be (sorted)
* ^
*
*/
def apply(right: SortedWord): MatcherFactory1[Any, Sortable] =
new MatcherFactory1[Any, Sortable] {
def matcher[T <: Any : Sortable]: Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = {
val sortable = implicitly[Sortable[T]]
MatchResult(
sortable.isSorted(left),
Resources("wasNotSorted"),
Resources("wasSorted"),
Vector(left)
)
}
override def toString: String = "be (sorted)"
}
override def toString: String = "be (sorted)"
}
/**
* This method enables the following syntax, where fraction
refers to a PartialFunction
:
*
*
* fraction should (be definedAt (6) and be definedAt (8))
* ^
*
*/
def definedAt[A, U <: PartialFunction[A, _]](right: A): Matcher[U] =
new Matcher[U] {
def apply(left: U): MatchResult =
MatchResult(
left.isDefinedAt(right),
Resources("wasNotDefinedAt"),
Resources("wasDefinedAt"),
Vector(left, right)
)
override def toString: String = "be definedAt " + Prettifier.default(right)
}
/**
* This method enables the following syntax, where fraction
refers to a PartialFunction
:
*
*
* fraction should (be (definedAt (6)) and be (definedAt (8)))
* ^
*
*/
def apply[A, U <: PartialFunction[A, _]](resultOfDefinedAt: ResultOfDefinedAt[A]): Matcher[U] =
new Matcher[U] {
def apply(left: U): MatchResult =
MatchResult(
left.isDefinedAt(resultOfDefinedAt.right),
Resources("wasNotDefinedAt"),
Resources("wasDefinedAt"),
Vector(left, resultOfDefinedAt.right)
)
override def toString: String = "be definedAt " + Prettifier.default(resultOfDefinedAt.right)
}
/**
* This method enables the following syntax, where open
refers to a BePropertyMatcher
:
*
*
* result should be (a [Book])
* ^
*
*/
def apply(aType: ResultOfATypeInvocation[_]): Matcher[Any] =
new Matcher[Any] {
def apply(left: Any): MatchResult = {
val clazz = aType.clazz
MatchResult(
clazz.isAssignableFrom(left.getClass),
Resources("wasNotAnInstanceOf"),
Resources("wasAnInstanceOf"),
Vector(left, UnquotedString(clazz.getName))
)
}
override def toString: String = "be (" + Prettifier.default(aType) + ")"
}
/**
* This method enables the following syntax, where open
refers to a BePropertyMatcher
:
*
*
* result should be (an [Book])
* ^
*
*/
def apply(anType: ResultOfAnTypeInvocation[_]): Matcher[Any] =
new Matcher[Any] {
def apply(left: Any): MatchResult = {
val clazz = anType.clazz
MatchResult(
clazz.isAssignableFrom(left.getClass),
Resources("wasNotAnInstanceOf"),
Resources("wasAnInstanceOf"),
Vector(left, UnquotedString(clazz.getName))
)
}
override def toString: String = "be (" + Prettifier.default(anType) + ")"
}
/**
* This method enables the following syntax, where open
refers to a BePropertyMatcher
:
*
*
* file should be (readable)
* ^
*
*/
def apply(readable: ReadableWord): MatcherFactory1[Any, Readability] =
new MatcherFactory1[Any, Readability] {
def matcher[T <: Any : Readability]: Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = {
val readability = implicitly[Readability[T]]
MatchResult(
readability.isReadable(left),
Resources("wasNotReadable"),
Resources("wasReadable"),
Vector(left)
)
}
override def toString: String = "be (" + Prettifier.default(readable) + ")"
}
override def toString: String = "be (" + Prettifier.default(readable) + ")"
}
/**
* This method enables the following syntax, where open
refers to a BePropertyMatcher
:
*
*
* file should be (writable)
* ^
*
*/
def apply(writable: WritableWord): MatcherFactory1[Any, Writability] =
new MatcherFactory1[Any, Writability] {
def matcher[T <: Any : Writability]: Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = {
val writability = implicitly[Writability[T]]
MatchResult(
writability.isWritable(left),
Resources("wasNotWritable"),
Resources("wasWritable"),
Vector(left)
)
}
override def toString: String = "be (writable)"
}
override def toString: String = "be (writable)"
}
/**
* This method enables syntax such as the following:
*
*
* array should be (empty)
* ^
*
*/
def apply(empty: EmptyWord): MatcherFactory1[Any, Emptiness] =
new MatcherFactory1[Any, Emptiness] {
def matcher[T <: Any : Emptiness]: Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = {
val emptiness = implicitly[Emptiness[T]]
MatchResult(
emptiness.isEmpty(left),
Resources("wasNotEmpty"),
Resources("wasEmpty"),
Vector(left)
)
}
override def toString: String = "be (empty)"
}
override def toString: String = "be (empty)"
}
/**
* This method enables syntax such as the following:
*
*
* array should be (defined)
* ^
*
*/
def apply(defined: DefinedWord): MatcherFactory1[Any, Definition] =
new MatcherFactory1[Any, Definition] {
def matcher[T <: Any : Definition]: Matcher[T] =
new Matcher[T] {
def apply(left: T): MatchResult = {
val definition = implicitly[Definition[T]]
MatchResult(
definition.isDefined(left),
Resources("wasNotDefined"),
Resources("wasDefined"),
Vector(left)
)
}
override def toString: String = "be (defined)"
}
override def toString: String = "be (defined)"
}
/**
* Overrides toString to return "be"
*/
override def toString: String = "be"
}