Package

org.scalatest

matchers

Permalink

package matchers

Classes and traits for matchers.

This package is released as part of the scalatest-matchers-core module.

Source
package.scala
Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. matchers
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. All

Type Members

  1. trait BeMatcher[-T] extends (T) ⇒ MatchResult

    Permalink

    Trait extended by matcher objects, which may appear after the word be, that can match a value of the specified type.

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

    Although BeMatcher and Matcher represent very similar concepts, they have no inheritance relationship because Matcher is intended for use right after should or must whereas BeMatcher is intended for use right after be.

    As an example, you could create BeMatcher[Int] called odd that would match any odd Int, and one called even that would match any even Int. Given this pair of BeMatchers, you could check whether an Int was odd or even with expressions like:

    num should be (odd)
    num should not be (even)
    

    Here's is how you might define the odd and even BeMatchers:

    trait CustomMatchers {
    
      class OddMatcher extends BeMatcher[Int] {
        def apply(left: Int) =
          MatchResult(
            left % 2 == 1,
            left.toString + " was even",
            left.toString + " was odd"
          )
      }
      val odd = new OddMatcher
      val even = not (odd)
    }
    
    // Make them easy to import with:
    // import CustomMatchers._
    object CustomMatchers extends CustomMatchers
    

    These BeMatchers are defined inside a trait to make them easy to mix into any suite or spec that needs them. The CustomMatchers companion object exists to make it easy to bring the BeMatchers 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.

    Here's an rather contrived example of how you might use odd and even:

    class DoubleYourPleasureSuite extends FunSuite with MustMatchers with CustomMatchers {
    
      def doubleYourPleasure(i: Int): Int = i * 2
    
      test("The doubleYourPleasure method must return proper odd or even values")
    
        val evenNum = 2
        evenNum must be (even)
        doubleYourPleasure(evenNum) must be (even)
    
        val oddNum = 3
        oddNum must be (odd)
        doubleYourPleasure(oddNum) must be (odd) // This will fail
      }
    }
    

    The last assertion in the above test will fail with this failure message:

    6 was even
    

    For more information on MatchResult and the meaning of its fields, please see the documentation for MatchResult. To understand why BeMatcher is contravariant in its type parameter, see the section entitled "Matcher's variance" in the documentation for Matcher.

  2. final case class BePropertyMatchResult(matches: Boolean, propertyName: String) extends Product with Serializable

    Permalink

    The result of a Boolean property match operation, such as one performed by a BePropertyMatcher, which contains one field that indicates whether the match succeeded (i.e., the Boolean property was true) and one field that provides the name of the property.

    The result of a Boolean property match operation, such as one performed by a BePropertyMatcher, which contains one field that indicates whether the match succeeded (i.e., the Boolean property was true) and one field that provides the name of the property.

    For an example of a BePropertyMatchResult in action, see the documentation for BePropertyMatcher.

    matches

    indicates whether or not the matcher matched (if the Boolean property was true, it was a match)

    propertyName

    the name of the Boolean property that was matched against

  3. trait BePropertyMatcher[-T] extends (T) ⇒ BePropertyMatchResult

    Permalink

    Trait extended by matcher objects, which may appear after the word be, that can match against a Boolean property.

    Trait extended by matcher objects, which may appear after the word be, that can match against a Boolean property. The match will succeed if and only if the Boolean property equals true. The object containing the property, which must be of the type specified by the BePropertyMatcher's type parameter T, is passed to the BePropertyMatcher's apply method. The result is a BePropertyMatchResult. A BePropertyMatcher is, therefore, a function from the specified type, T, to a BePropertyMatchResult.

    Although BePropertyMatcher and Matcher represent similar concepts, they have no inheritance relationship because Matcher is intended for use right after should or must whereas BePropertyMatcher is intended for use right after be.

    A BePropertyMatcher essentially allows you to write statically typed Boolean property assertions similar to the dynamic ones that use symbols:

    tempFile should be a ('file) // dynamic: uses reflection
    tempFile should be a (file)  // type safe: only works on Files; no reflection used
    

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

    trait CustomMatchers {
    
      class FileBePropertyMatcher extends BePropertyMatcher[java.io.File] {
        def apply(left: java.io.File) = BePropertyMatchResult(left.isFile, "file")
      }
    
      class DirectoryBePropertyMatcher extends BePropertyMatcher[java.io.File] {
        def apply(left: java.io.File) = BePropertyMatchResult(left.isDirectory, "directory")
      }
    
      val file = new FileBePropertyMatcher
      val directory = new DirectoryBePropertyMatcher
    }
    

    Because the type parameter of these two BePropertyMatchers is java.io.File, they can only be used with instances of that type. (The compiler will enforce this.) All they do is create a BePropertyMatchResult whose matches field is true if and only if the Boolean property is true. The second field, propertyName, is simply the string name of the property. The file and directory vals create variables that can be used in matcher expressions that test whether a java.io.File is a file or a directory. Here's an example:

    class ExampleSpec extends RefSpec with Matchers with CustomMatchers {
    
      describe("A temp file") {
    
        it("should be a file, not a directory") {
    
          val tempFile = java.io.File.createTempFile("delete", "me")
    
          try {
            tempFile should be a (file)
            tempFile should not be a (directory)
          }
          finally {
            tempFile.delete()
          }
        }
      }
    }
    

    These matches should succeed, but if for example the first match, tempFile should be a (file), were to fail, you would get an error message like:

    /tmp/delme1234me was not a file
    

    For more information on BePropertyMatchResult and the meaning of its fields, please see the documentation for BePropertyMatchResult. To understand why BePropertyMatcher is contravariant in its type parameter, see the section entitled "Matcher's variance" in the documentation for Matcher.

  4. final case class HavePropertyMatchResult[P](matches: Boolean, propertyName: String, expectedValue: P, actualValue: P) extends Product with Serializable

    Permalink

    The result of a property match operation such as one performed by a HavePropertyMatcher, which contains one field that indicates whether the match succeeded (i.e., the property had its expected value), one field that provides the name of the property, and two fields giving the expected and actual values.

    The result of a property match operation such as one performed by a HavePropertyMatcher, which contains one field that indicates whether the match succeeded (i.e., the property had its expected value), one field that provides the name of the property, and two fields giving the expected and actual values. HavePropertyMatchResult's type parameter, P, specifies the type of the property.

    For an example of a HavePropertyMatchResult in action, see the documentation for HavePropertyMatcher.

    matches

    indicates whether or not the matcher matched (if the property had its expected value, it was a match)

    propertyName

    the name of the property (of type P) that was matched against

    expectedValue

    the expected value of the property

    actualValue

    the actual value of the property

  5. trait HavePropertyMatcher[-T, P] extends (T) ⇒ HavePropertyMatchResult[P]

    Permalink

    Trait extended by matcher objects, which may appear after the word have, that can match against a property of the type specified by the HavePropertyMatcher's second type parameter P.

    Trait extended by matcher objects, which may appear after the word have, that can match against a property of the type specified by the HavePropertyMatcher's second type parameter P. HavePropertyMatcher's first type parameter, T, specifies the type that declares the property. The match will succeed if and only if the value of the property equals the specified value. The object containing the property is passed to the HavePropertyMatcher's apply method. The result is a HavePropertyMatchResult[P]. A HavePropertyMatcher is, therefore, a function from the specified type, T, to a HavePropertyMatchResult[P].

    Although HavePropertyMatcher and Matcher represent similar concepts, they have no inheritance relationship because Matcher is intended for use right after should or must whereas HavePropertyMatcher is intended for use right after have.

    A HavePropertyMatcher essentially allows you to write statically typed property assertions similar to the dynamic ones that use symbols:

    book should have ('title ("Moby Dick")) // dynamic: uses reflection
    book should have (title ("Moby Dick"))  // type safe: only works on Books; no reflection used
    

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

    case class Book(val title: String, val author: String)
    
    trait CustomMatchers {
    
      def title(expectedValue: String) =
        new HavePropertyMatcher[Book, String] {
          def apply(book: Book) =
            HavePropertyMatchResult(
              book.title == expectedValue,
              "title",
              expectedValue,
              book.title
            )
        }
    
      def author(expectedValue: String) =
        new HavePropertyMatcher[Book, String] {
          def apply(book: Book) =
            HavePropertyMatchResult(
              book.author == expectedValue,
              "author",
              expectedValue,
              book.author
            )
        }
    }
    

    Each time the title method is called, it returns a new HavePropertyMatcher[Book, String] that can be used to match against the title property of the Book passed to its apply method. Because the type parameter of these two HavePropertyMatchers is Book, they can only be used with instances of that type. (The compiler will enforce this.) The match will succeed if the title property equals the value passed as expectedValue. If the match succeeds, the matches field of the returned HavePropertyMatchResult will be true. The second field, propertyName, is simply the string name of the property. The third and fourth fields, expectedValue and actualValue indicate the expected and actual values, respectively, for the property. Here's an example that uses these HavePropertyMatchers:

    class ExampleSpec extends RefSpec with Matchers with CustomMatchers {
    
      describe("A book") {
    
        it("should have the correct title and author") {
    
          val book = Book("Moby Dick", "Melville")
    
          book should have (
            title ("Moby Dick"),
            author ("Melville")
          )
        }
      }
    }
    

    These matches should succeed, but if for example the first property, title ("Moby Dick"), were to fail, you would get an error message like:

    The title property had value "A Tale of Two Cities", instead of its expected value "Moby Dick",
    on object Book(A Tale of Two Cities,Dickens)
    

    For more information on HavePropertyMatchResult and the meaning of its fields, please see the documentation for HavePropertyMatchResult. To understand why HavePropertyMatcher is contravariant in its type parameter, see the section entitled "Matcher's variance" in the documentation for Matcher.

  6. final case class LazyArg(arg: Any)(f: (Any) ⇒ String) extends Product with Serializable

    Permalink

    Transforms a given object's toString with a given function lazily.

    Transforms a given object's toString with a given function lazily.

    This class is intended to be used with the mapResult method of MatcherProducers, which you can use to modify error messages when composing matchers. This class exists to enable those error messages to be modified lazily, so that toString is invoked on the given arg, and its result transformed by the given function f, only when and if the toString method is invoked on the LazyArg. As a performance optimization, ScalaTest's MatchResult avoids invoking toString on objects until and unless an error message is actually needed, to minimize unecessary creation and concatenation of strings. The LazyArg class enables this same performance optimization when composing matchers.

    The other design goal of LazyArg is to make the internal arg available for inspection in an IDE. In a future version of ScalaTest, the args of MatchResult that were used to create the error message will be included in the TestFailedException, so they can be inspected in IDEs. This is why the arg field of LazyArg is public.

    For an example of using LazyArg, see the Composing matchers section in the main documentation for trait Matcher.

    arg

    the argument

    f

    a function that given the arg will produce a String

  7. sealed case class MatchResult(matches: Boolean, rawFailureMessage: String, rawNegatedFailureMessage: String, rawMidSentenceFailureMessage: String, rawMidSentenceNegatedFailureMessage: String, failureMessageArgs: IndexedSeq[Any], negatedFailureMessageArgs: IndexedSeq[Any], midSentenceFailureMessageArgs: IndexedSeq[Any], midSentenceNegatedFailureMessageArgs: IndexedSeq[Any]) extends Product with Serializable

    Permalink

    The result of a match operation, such as one performed by a Matcher or BeMatcher, which contains one field that indicates whether the match succeeded, four fields that provide raw failure messages to report under different circumstances, four fields providing arguments used to construct the final failure messages using raw failure messages and a Prettifier.

    The result of a match operation, such as one performed by a Matcher or BeMatcher, which contains one field that indicates whether the match succeeded, four fields that provide raw failure messages to report under different circumstances, four fields providing arguments used to construct the final failure messages using raw failure messages and a Prettifier. Using the default constructor, failure messages will be constructed lazily (when required).

    A MatchResult's matches field indicates whether a match succeeded. If it succeeded, matches will be true. There are four methods, failureMessage, negatedfailureMessage, midSentenceFailureMessage and negatedMidSentenceFailureMessage that can be called to get final failure message strings, one of which will be presented to the user in case of a match failure. If a match succeeds, none of these strings will be used, because no failure message will be reported (i.e., because there was no failure to report). If a match fails (matches is false), the failureMessage (or midSentenceFailure—more on that below) will be reported to help the user understand what went wrong.

    Understanding negatedFailureMessage

    The negatedFailureMessage exists so that it can become the failureMessage if the matcher is inverted, which happens, for instance, if it is passed to not. Here's an example:

    val equalSeven = equal (7)
    val notEqualSeven = not (equalSeven)
    

    The Matcher[Int] that results from passing 7 to equal, which is assigned to the equalSeven variable, will compare Ints passed to its apply method with 7. If 7 is passed, the equalSeven match will succeed. If anything other than 7 is passed, it will fail. By contrast, the notEqualSeven matcher, which results from passing equalSeven to not, does just the opposite. If 7 is passed, the notEqualSeven match will fail. If anything other than 7 is passed, it will succeed.

    For example, if 8 is passed, equalSeven's MatchResult will contain:

               expression: equalSeven(8)
                  matches: false
           failureMessage: 8 did not equal 7
    negatedFailureMessage: 8 equaled 7
    

    Although the negatedFailureMessage is nonsensical, it will not be reported to the user. Only the failureMessage, which does actually explain what caused the failure, will be reported by the user. If you pass 8 to notEqualSeven's apply method, by contrast, the failureMessage and negatedFailureMessage will be:

               expression: notEqualSeven(8)
                  matches: true
           failureMessage: 8 equaled 7
    negatedFailureMessage: 8 did not equal 7
    

    Note that the messages are swapped from the equalSeven messages. This swapping was effectively performed by the not matcher, which in addition to swapping the failureMessage and negatedFailureMessage, also inverted the matches value. Thus when you pass the same value to both equalSeven and notEqualSeven the matches field of one MatchResult will be true and the other false. Because the matches field of the MatchResult returned by notEqualSeven(8) is true, the nonsensical failureMessage, "8 equaled 7", will not be reported to the user.

    If 7 is passed, by contrast, the failureMessage and negatedFailureMessage of equalSeven will be:

               expression: equalSeven(7)
                  matches: true
           failureMessage: 7 did not equal 7
    negatedFailureMessage: 7 equaled 7
    

    In this case equalSeven's failureMessage is nonsensical, but because the match succeeded, the nonsensical message will not be reported to the user. If you pass 7 to notEqualSeven's apply method, you'll get:

               expression: notEqualSeven(7)
                  matches: false
           failureMessage: 7 equaled 7
    negatedFailureMessage: 7 did not equal 7
    

    Again the messages are swapped from the equalSeven messages, but this time, the failureMessage makes sense and explains what went wrong: the notEqualSeven match failed because the number passed did in fact equal 7. Since the match failed, this failure message, "7 equaled 7", will be reported to the user.

    Understanding the "midSentence" messages

    When a ScalaTest matcher expression that involves and or or fails, the failure message that results is composed from the failure messages of the left and right matcher operatnds to and or or. For example:

    8 should (equal (7) or equal (9))
    

    This above expression would fail with the following failure message reported to the user:

    8 did not equal 7, and 8 did not equal 9
    

    This works fine, but what if the failure messages being combined begin with a capital letter, such as:

    The name property did not equal "Ricky"
    

    A combination of two such failure messages might result in an abomination of English punctuation, such as:

    The name property did not equal "Ricky", and The name property did not equal "Bobby"
    

    Because ScalaTest is an internationalized application, taking all of its strings from a property file enabling it to be localized, it isn't a good idea to force the first character to lower case. Besides, it might actually represent a String value which should stay upper case. The midSentenceFailureMessage exists for this situation. If the failure message is used at the beginning of the sentence, failureMessage will be used. But if it appears mid-sentence, or at the end of the sentence, midSentenceFailureMessage will be used. Given these failure message strings:

               failureMessage: The name property did not equal "Bobby"
    midSentenceFailureMessage: the name property did not equal "Bobby"
    

    The resulting failure of the or expression involving to matchers would make any English teacher proud:

    The name property did not equal "Ricky", and the name property did not equal "Bobby"
    

    matches

    indicates whether or not the matcher matched

    rawFailureMessage

    raw failure message to report if a match fails

    rawNegatedFailureMessage

    raw message with a meaning opposite to that of the failure message

    rawMidSentenceFailureMessage

    raw failure message suitable for appearing mid-sentence

    rawMidSentenceNegatedFailureMessage

    raw negated failure message suitable for appearing mid-sentence

    failureMessageArgs

    arguments for constructing failure message to report if a match fails

    negatedFailureMessageArgs

    arguments for constructing message with a meaning opposite to that of the failure message

    midSentenceFailureMessageArgs

    arguments for constructing failure message suitable for appearing mid-sentence

    midSentenceNegatedFailureMessageArgs

    arguments for constructing negated failure message suitable for appearing mid-sentence

  8. trait Matcher[-T] extends (T) ⇒ MatchResult

    Permalink

    Trait extended by objects that can match a value of the specified type.

    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].

  9. trait MatcherProducers extends AnyRef

    Permalink

    Provides an implicit conversion on functions that produce Matchers, i.e., T => Matcher[T] that enables you to modify error messages when composing Matchers.

    Provides an implicit conversion on functions that produce Matchers, i.e., T => Matcher[T] that enables you to modify error messages when composing Matchers.

    For an example of using MatcherProducers, see the Composing matchers section in the main documentation for trait Matcher.

Value Members

  1. object BeMatcher

    Permalink

    Companion object for trait BeMatcher that provides a factory method that creates a BeMatcher[T] from a passed function of type (T => MatchResult).

    Companion object for trait BeMatcher that provides a factory method that creates a BeMatcher[T] from a passed function of type (T => MatchResult).

  2. object BePropertyMatchResult extends Serializable

    Permalink

    Companion object for the BePropertyMatchResult case class.

    Companion object for the BePropertyMatchResult case class.

  3. object BePropertyMatcher

    Permalink

    Companion object for trait BePropertyMatcher that provides a factory method that creates a BePropertyMatcher[T] from a passed function of type (T => BePropertyMatchResult).

    Companion object for trait BePropertyMatcher that provides a factory method that creates a BePropertyMatcher[T] from a passed function of type (T => BePropertyMatchResult).

  4. object HavePropertyMatchResult extends Serializable

    Permalink

    Companion object for the HavePropertyMatchResult case class.

    Companion object for the HavePropertyMatchResult case class.

  5. object HavePropertyMatcher

    Permalink

    Companion object for trait HavePropertyMatcher that provides a factory method that creates a HavePropertyMatcher[T] from a passed function of type (T => HavePropertyMatchResult).

    Companion object for trait HavePropertyMatcher that provides a factory method that creates a HavePropertyMatcher[T] from a passed function of type (T => HavePropertyMatchResult).

  6. object MatchFailed

    Permalink

    Singleton object that provides unapply method to extract failure message from MatchResult having matches property value of false.

    Singleton object that provides unapply method to extract failure message from MatchResult having matches property value of false.

  7. object MatchPatternHelper

    Permalink

    MatchPatternHelper is called by MatchPatternMacro to support matchPattern syntax.

    MatchPatternHelper is called by MatchPatternMacro to support matchPattern syntax.

  8. object MatchResult extends Serializable

    Permalink

    Companion object for the MatchResult case class.

    Companion object for the MatchResult case class.

  9. object MatchSucceeded

    Permalink

    Singleton object that provides unapply method to extract negated failure message from MatchResult having matches property value of true.

    Singleton object that provides unapply method to extract negated failure message from MatchResult having matches property value of true.

  10. object Matcher

    Permalink

    Companion object for trait Matcher that provides a factory method that creates a Matcher[T] from a passed function of type (T => MatchResult).

    Companion object for trait Matcher that provides a factory method that creates a Matcher[T] from a passed function of type (T => MatchResult).

  11. object MatcherProducers extends MatcherProducers

    Permalink

    Companion object that facilitates the importing of MatcherProducers members as an alternative to mixing it in.

    Companion object that facilitates the importing of MatcherProducers members as an alternative to mixing it in. One use case is to import MatcherProducers's members so you can use MatcherProducers in the Scala interpreter.

  12. object TypeMatcherHelper

    Permalink

    TypeMatcherHelper is called by TypeMatcherMacro to support a [Type] and an [Type] syntax.

    TypeMatcherHelper is called by TypeMatcherMacro to support a [Type] and an [Type] syntax.

    This object needs to be public so that the macro-generated code can be compiled. It is expected that ScalaTest users would ever need to use TypeMatcherHelper directly.

  13. package dsl

    Permalink

    Classes and traits supporting ScalaTest's matchers DSL.

    Classes and traits supporting ScalaTest's matchers DSL.

    This package is released as part of the scalatest-matchers-core module.

  14. package must

    Permalink
  15. package should

    Permalink

    Trait and object for ScalaTest Matchers DSL using should.

    Trait and object for ScalaTest Matchers DSL using should.

    This package is released as part of the scalatest-shouldmatchers module.

Inherited from AnyRef

Inherited from Any

Ungrouped