Matcher

trait Matcher[-T] extends T => MatchResult

Trait extended by objects that can match a value of the specified type. The value to match is passed to the matcher's apply method. The result is a MatchResult. A matcher is, therefore, a function from the specified type, T, to a MatchResult.

== Creating custom matchers ==

If none of the built-in matcher syntax satisfies a particular need you have, you can create custom Matchers that allow you to place your own syntax directly after should. For example, although you can ensure that a java.io.File has a name that ends with a particular extension like this:

file.getName should endWith (".txt")

You might prefer to create a custom Matcher[java.io.File] named endWithExtension, so you could write expressions like:

file should endWithExtension ("txt")
file should not endWithExtension "txt"
file should (exist and endWithExtension ("txt"))

One good way to organize custom matchers is to place them inside one or more traits that you can then mix into the suites that need them. Here's an example:

import org.scalatest._
import matchers._

trait CustomMatchers {

 class FileEndsWithExtensionMatcher(expectedExtension: String) extends Matcher[java.io.File] {

   def apply(left: java.io.File) = {
     val name = left.getName
     MatchResult(
       name.endsWith(expectedExtension),
       s"""File $name did not end with extension "$expectedExtension"""",
       s"""File $name ended with extension "$expectedExtension""""
     )
   }
 }

 def endWithExtension(expectedExtension: String) = new FileEndsWithExtensionMatcher(expectedExtension)
}

// Make them easy to import with:
// import CustomMatchers._
object CustomMatchers extends CustomMatchers

Note: the CustomMatchers companion object exists to make it easy to bring the matchers defined in this trait into scope via importing, instead of mixing in the trait. The ability to import them is useful, for example, when you want to use the matchers defined in a trait in the Scala interpreter console.

This trait contains one matcher class, FileEndsWithExtensionMatcher, and a def named endWithExtension that returns a new instance of FileEndsWithExtensionMatcher. Because the class extends Matcher[java.io.File], the compiler will only allow it be used to match against instances of java.io.File. A matcher must declare an apply method that takes the type decared in Matcher's type parameter, in this case java.io.File. The apply method will return a MatchResult whose matches field will indicate whether the match succeeded. The failureMessage field will provide a programmer-friendly error message indicating, in the event of a match failure, what caused the match to fail.

The FileEndsWithExtensionMatcher matcher in this example determines success by determining if the passed java.io.File ends with the desired extension. It does this in the first argument passed to the MatchResult factory method:

name.endsWith(expectedExtension)

In other words, if the file name has the expected extension, this matcher matches. The next argument to MatchResult's factory method produces the failure message string:

s"""File $name did not end with extension "$expectedExtension"""",

For example, consider this matcher expression:

import org.scalatest._
import Matchers._
import java.io.File
import CustomMatchers._

new File("essay.text") should endWithExtension ("txt")

Because the passed java.io.File has the name essay.text, but the expected extension is "txt", the failure message would be:

File essay.text did not have extension "txt"

For more information on the fields in a MatchResult, including the subsequent field (or fields) that follow the failure message, please see the documentation for MatchResult.

== Creating dynamic matchers ==

There are other ways to create new matchers besides defining one as shown above. For example, you might check that a file is hidden like this:

new File("secret.txt") should be ('hidden)

If you wanted to get rid of the tick mark, you could simply define hidden like this:

val hidden = 'hidden

Now you can check that an file is hidden without the tick mark:

new File("secret.txt") should be (hidden)

You could get rid of the parens with by using shouldBe:

new File("secret.txt") shouldBe hidden

== Creating matchers using logical operators ==

You can also use ScalaTest matchers' logical operators to combine existing matchers into new ones, like this:

val beWithinTolerance = be >= 0 and be <= 10

Now you could check that a number is within the tolerance (in this case, between 0 and 10, inclusive), like this:

num should beWithinTolerance

When defining a full blown matcher, one shorthand is to use one of the factory methods in Matcher's companion object. For example, instead of writing this:

val beOdd =
 new Matcher[Int] {
   def apply(left: Int) =
     MatchResult(
       left % 2 == 1,
       left + " was not odd",
       left + " was odd"
     )
 }

You could alternately write this:

val beOdd =
 Matcher { (left: Int) =>
   MatchResult(
     left % 2 == 1,
     left + " was not odd",
     left + " was odd"
   )
 }

Either way you define the beOdd matcher, you could use it like this:

3 should beOdd
4 should not (beOdd)

== Composing matchers ==

You can also compose matchers. For example, the endWithExtension matcher from the example above can be more easily created by composing a function with the existing endWith matcher:

scala> import org.scalatest._
import org.scalatest._

scala> import Matchers._
import Matchers._

scala> import java.io.File
import java.io.File

scala> def endWithExtension(ext: String) = endWith(ext) compose { (f: File) => f.getPath }
endWithExtension: (ext: String)org.scalatest.matchers.Matcher[java.io.File]

Now you have a Matcher[File] whose apply method first invokes the converter function to convert the passed File to a String, then passes the resulting String to endWith. Thus, you could use this version endWithExtension like the previous one:

scala> new File("output.txt") should endWithExtension("txt")

In addition, by composing twice, you can modify the type of both sides of a match statement with the same function, like this:

scala> val f = be > (_: Int)
f: Int => org.scalatest.matchers.Matcher[Int] = <function1>

scala> val g = (_: String).toInt
g: String => Int = <function1>

scala> val beAsIntsGreaterThan = (f compose g) andThen (_ compose g)
beAsIntsGreaterThan: String => org.scalatest.matchers.Matcher[String] = <function1>

scala> "8" should beAsIntsGreaterThan ("7")

At thsi point, however, the error message for the beAsIntsGreaterThan gives no hint that the Ints being compared were parsed from Strings:

scala> "7" should beAsIntsGreaterThan ("8")
org.scalatest.exceptions.TestFailedException: 7 was not greater than 8

To modify error message, you can use trait MatcherProducers, which also provides a composeTwice method that performs the compose ... andThen ... compose operation:

scala> import matchers._
import matchers._

scala> import MatcherProducers._
import MatcherProducers._

scala> val beAsIntsGreaterThan = f composeTwice g // means: (f compose g) andThen (_ compose g)
beAsIntsGreaterThan: String => org.scalatest.matchers.Matcher[String] = <function1>

scala> "8" should beAsIntsGreaterThan ("7")

Of course, the error messages is still the same:

scala> "7" should beAsIntsGreaterThan ("8")
org.scalatest.exceptions.TestFailedException: 7 was not greater than 8

To modify the error messages, you can use mapResult from MatcherProducers. Here's an example:

scala> val beAsIntsGreaterThan =
 f composeTwice g mapResult { mr =>
   mr.copy(
     failureMessageArgs =
       mr.failureMessageArgs.map((LazyArg(_) { "\"" + _.toString + "\".toInt"})),
     negatedFailureMessageArgs =
       mr.negatedFailureMessageArgs.map((LazyArg(_) { "\"" + _.toString + "\".toInt"})),
     midSentenceFailureMessageArgs =
       mr.midSentenceFailureMessageArgs.map((LazyArg(_) { "\"" + _.toString + "\".toInt"})),
     midSentenceNegatedFailureMessageArgs =
       mr.midSentenceNegatedFailureMessageArgs.map((LazyArg(_) { "\"" + _.toString + "\".toInt"}))
   )
 }
beAsIntsGreaterThan: String => org.scalatest.matchers.Matcher[String] = <function1>

The mapResult method takes a function that accepts a MatchResult and produces a new MatchResult, which can contain modified arguments and modified error messages. In this example, the error messages are being modified by wrapping the old arguments in LazyArg instances that lazily apply the given prettification functions to the toString result of the old args. Now the error message is clearer:

scala> "7" should beAsIntsGreaterThan ("8")
org.scalatest.exceptions.TestFailedException: "7".toInt was not greater than "8".toInt

== Matcher's variance ==

Matcher is contravariant in its type parameter, T, to make its use more flexible. As an example, consider the hierarchy:

class Fruit
class Orange extends Fruit
class ValenciaOrange extends Orange

Given an orange:

val orange = Orange

The expression "orange should" will, via an implicit conversion in Matchers, result in an object that has a should method that takes a Matcher[Orange]. If the static type of the matcher being passed to should is Matcher[Valencia] it shouldn't (and won't) compile. The reason it shouldn't compile is that the left value is an Orange, but not necessarily a Valencia, and a Matcher[Valencia] only knows how to match against a Valencia. The reason it won't compile is given that Matcher is contravariant in its type parameter, T, a Matcher[Valencia] is not a subtype of Matcher[Orange].

By contrast, if the static type of the matcher being passed to should is Matcher[Fruit], it should (and will) compile. The reason it should compile is that given the left value is an Orange, it is also a Fruit, and a Matcher[Fruit] knows how to match against Fruits. The reason it will compile is that given that Matcher is contravariant in its type parameter, T, a Matcher[Fruit] is indeed a subtype of Matcher[Orange].

Companion:
object
trait T => MatchResult
class Object
trait Matchable
class Any

Type members

Classlikes

final class AndBeWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class AndContainWord(prettifier: Prettifier, pos: Position)

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class AndEndWithWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class AndFullyMatchWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class AndHaveWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class AndIncludeWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class AndNotWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class AndStartWithWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class OrBeWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class OrContainWord(prettifier: Prettifier, pos: Position)

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class OrEndWithWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class OrFullyMatchWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class OrHaveWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class OrIncludeWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class OrNotWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

final class OrStartWithWord

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

This class is part of the ScalaTest matchers DSL. Please see the documentation for Matchers for an overview of the matchers DSL.

Value members

Abstract methods

def apply(left: T): MatchResult

Check to see if the specified object, left, matches, and report the result in the returned MatchResult. The parameter is named left, because it is usually the value to the left of a should or must invocation. For example, in:

Check to see if the specified object, left, matches, and report the result in the returned MatchResult. The parameter is named left, because it is usually the value to the left of a should or must invocation. For example, in:

list should equal (List(1, 2, 3))

The equal (List(1, 2, 3)) expression results in a matcher that holds a reference to the right value, List(1, 2, 3). The should method invokes apply on this matcher, passing in list, which is therefore the "left" value. The matcher will compare the list (the left value) with List(1, 2, 3) (the right value), and report the result in the returned MatchResult.

Value parameters:
left

the value against which to match

Returns:

the MatchResult that represents the result of the match

Concrete methods

infix def and[U <: T](rightMatcher: Matcher[U]): Matcher[U]

Returns a matcher whose apply method returns a MatchResult that represents the logical-and of the results of the wrapped and the passed matcher applied to the same value.

Returns a matcher whose apply method returns a MatchResult that represents the logical-and of the results of the wrapped and the passed matcher applied to the same value.

The reason and has an upper bound on its type parameter is so that the Matcher resulting from an invocation of and will have the correct type parameter. If you call and on a Matcher[Orange], passing in a Matcher[Valencia], the result will have type Matcher[Valencia]. This is correct because both a Matcher[Orange] and a Matcher[Valencia] know how to match a Valencia (but a Matcher[Valencia] doesn't know how to match any old Orange). If you call and on a Matcher[Orange], passing in a Matcher[Fruit], the result will have type Matcher[Orange]. This is also correct because both a Matcher[Orange] and a Matcher[Fruit] know how to match an Orange (but a Matcher[Orange] doesn't know how to match any old Fruit).

Value parameters:
the

matcher to logical-and with this matcher

Returns:

a matcher that performs the logical-and of this and the passed matcher

infix def and[U, TC1[_]](rightMatcherFactory1: MatcherFactory1[U, TC1]): MatcherFactory1[T & U, TC1]

Returns a MatcherFactory whose matcher method returns a Matcher, which has apply method that returns a MatchResult that represents the logical-and of the results of the wrapped and the passed MatcherFactory applied to the same value.

Returns a MatcherFactory whose matcher method returns a Matcher, which has apply method that returns a MatchResult that represents the logical-and of the results of the wrapped and the passed MatcherFactory applied to the same value.

Value parameters:
rightMatcherFactory1

the MatcherFactory to logical-and with this MatcherFactory

Returns:

a MatcherFactory that performs the logical-and of this and the passed MatcherFactory

infix def and(haveWord: HaveWord): AndHaveWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher and have size (3 - 1)
        ^
infix def and(containWord: ContainWord)(implicit prettifier: Prettifier, pos: Position): AndContainWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher and contain key ("one")
        ^
infix def and(beWord: BeWord): AndBeWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher and be a ('file)
        ^
infix def and(fullyMatchWord: FullyMatchWord): AndFullyMatchWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher and fullyMatch regex (decimalRegex)
        ^
infix def and(includeWord: IncludeWord): AndIncludeWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher and include regex ("wor.d")
        ^
infix def and(startWithWord: StartWithWord): AndStartWithWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher and startWith regex ("1.7")
        ^
infix def and(endWithWord: EndWithWord): AndEndWithWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher and endWith regex (decimalRegex)
        ^
infix def and(notWord: NotWord): AndNotWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher and not contain value (3)
        ^
infix def and(existWord: ExistWord): MatcherFactory1[T, Existence]

This method enables the following syntax:

This method enables the following syntax:

aMatcher and exist
        ^
infix def and(notExist: ResultOfNotExist): MatcherFactory1[T, Existence]

This method enables the following syntax:

This method enables the following syntax:

aMatcher and not (exist)
        ^
override def compose[U](g: U => T): Matcher[U]

Compose this matcher with the passed function, returning a new matcher.

Compose this matcher with the passed function, returning a new matcher.

This method overrides compose on Function1 to return a more specific function type of Matcher. For example, given a beOdd matcher defined like this:

val beOdd =
 new Matcher[Int] {
   def apply(left: Int) =
     MatchResult(
       left % 2 == 1,
       left + " was not odd",
       left + " was odd"
     )
 }

You could use beOdd like this:

3 should beOdd
4 should not (beOdd)

If for some odd reason, you wanted a Matcher[String] that checked whether a string, when converted to an Int, was odd, you could make one by composing beOdd with a function that converts a string to an Int, like this:

val beOddAsInt = beOdd compose { (s: String) => s.toInt }

Now you have a Matcher[String] whose apply method first invokes the converter function to convert the passed string to an Int, then passes the resulting Int to beOdd. Thus, you could use beOddAsInt like this:

"3" should beOddAsInt
"4" should not (beOddAsInt)
Definition Classes
Function1
def mapArgs(prettify: Any => String): Matcher[T]

Creates a new Matcher that will produce MatchResults that contain error messages constructed using arguments that are transformed by the passed prettify function. In other words, the MatchResult produced by this Matcher will use arguments transformed by prettify function to construct the final error messages.

Creates a new Matcher that will produce MatchResults that contain error messages constructed using arguments that are transformed by the passed prettify function. In other words, the MatchResult produced by this Matcher will use arguments transformed by prettify function to construct the final error messages.

Value parameters:
prettify

a function with which to transform the arguments of error messages.

Returns:

a new Matcher that will produce MatchResults that contain error messages constructed using arguments transformed by the passed prettify function.

Creates a new Matcher that will produce MatchResults by applying the original MatchResult produced by this Matcher to the passed prettify function. In other words, the MatchResult produced by this Matcher will be passed to prettify to produce the final MatchResult

Creates a new Matcher that will produce MatchResults by applying the original MatchResult produced by this Matcher to the passed prettify function. In other words, the MatchResult produced by this Matcher will be passed to prettify to produce the final MatchResult

Value parameters:
prettify

a function to apply to the original MatchResult produced by this Matcher

Returns:

a new Matcher that will produce MatchResults by applying the original MatchResult produced by this Matcher to the passed prettify function

infix def or[U <: T](rightMatcher: Matcher[U]): Matcher[U]

Returns a matcher whose apply method returns a MatchResult that represents the logical-or of the results of this and the passed matcher applied to the same value.

Returns a matcher whose apply method returns a MatchResult that represents the logical-or of the results of this and the passed matcher applied to the same value.

The reason or has an upper bound on its type parameter is so that the Matcher resulting from an invocation of or will have the correct type parameter. If you call or on a Matcher[Orange], passing in a Matcher[Valencia], the result will have type Matcher[Valencia]. This is correct because both a Matcher[Orange] and a Matcher[Valencia] know how to match a Valencia (but a Matcher[Valencia] doesn't know how to match any old Orange). If you call or on a Matcher[Orange], passing in a Matcher[Fruit], the result will have type Matcher[Orange]. This is also correct because both a Matcher[Orange] and a Matcher[Fruit] know how to match an Orange (but a Matcher[Orange] doesn't know how to match any old Fruit).

Value parameters:
rightMatcher

the matcher to logical-or with this matcher

Returns:

a matcher that performs the logical-or of this and the passed matcher

infix def or[U, TC1[_]](rightMatcherFactory1: MatcherFactory1[U, TC1]): MatcherFactory1[T & U, TC1]

Returns a MatcherFactory whose matcher method returns a Matcher, which has apply method that returns a MatchResult that represents the logical-or of the results of the wrapped and the passed MatcherFactory applied to the same value.

Returns a MatcherFactory whose matcher method returns a Matcher, which has apply method that returns a MatchResult that represents the logical-or of the results of the wrapped and the passed MatcherFactory applied to the same value.

Value parameters:
rightMatcherFactory1

the MatcherFactory to logical-or with this MatcherFactory

Returns:

a MatcherFactory that performs the logical-or of this and the passed MatcherFactory

infix def or(haveWord: HaveWord): OrHaveWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher or have size (3 - 1)
        ^
infix def or(containWord: ContainWord)(implicit prettifier: Prettifier, pos: Position): OrContainWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher or contain value (1)
        ^
infix def or(beWord: BeWord): OrBeWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher or be a ('directory)
        ^
infix def or(fullyMatchWord: FullyMatchWord): OrFullyMatchWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher or fullyMatch regex (decimal)
        ^
infix def or(includeWord: IncludeWord): OrIncludeWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher or include regex ("1.7")
        ^
infix def or(startWithWord: StartWithWord): OrStartWithWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher or startWith regex ("1.7")
        ^
infix def or(endWithWord: EndWithWord): OrEndWithWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher or endWith regex ("7b")
        ^
infix def or(notWord: NotWord): OrNotWord

This method enables the following syntax:

This method enables the following syntax:

aMatcher or not contain value (3)
        ^
infix def or(existWord: ExistWord): MatcherFactory1[T, Existence]

This method enables the following syntax:

This method enables the following syntax:

aMatcher or exist
        ^
infix def or(notExist: ResultOfNotExist): MatcherFactory1[T, Existence]

This method enables the following syntax:

This method enables the following syntax:

aMatcher or not (exist)
        ^

Inherited methods

@unspecialized
def andThen[A](g: MatchResult => A): T => A
Inherited from:
Function1
override def toString(): String
Definition Classes
Function1 -> Any
Inherited from:
Function1