package matchers
Classes and traits for matchers.
This package is released as part of the scalatest-matchers-core module.
- Source
- package.scala
- Alphabetic
- By Inheritance
- matchers
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Package Members
- package dsl
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-coremodule. - package must
- package should
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-shouldmatchersmodule.
Type Members
- trait BeMatcher[-T] extends (T) => MatchResult
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 theBeMatcher'sapplymethod. The result is aMatchResult. ABeMatcheris, therefore, a function from the specified type,T, to aMatchResult.Although
BeMatcherandMatcherrepresent very similar concepts, they have no inheritance relationship becauseMatcheris intended for use right aftershouldormustwhereasBeMatcheris intended for use right afterbe.As an example, you could create
BeMatcher[Int]calledoddthat would match any oddInt, and one calledeventhat would match any evenInt. Given this pair ofBeMatchers, you could check whether anIntwas 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 CustomMatchersThese
BeMatchers are defined inside a trait to make them easy to mix into any suite or spec that needs them. TheCustomMatcherscompanion object exists to make it easy to bring theBeMatchers 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
oddandeven: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 evenFor more information on
MatchResultand the meaning of its fields, please see the documentation forMatchResult. To understand whyBeMatcheris contravariant in its type parameter, see the section entitled "Matcher's variance" in the documentation forMatcher. - final case class BePropertyMatchResult(matches: Boolean, propertyName: String) extends Product with Serializable
The result of a
Booleanproperty match operation, such as one performed by aBePropertyMatcher, which contains one field that indicates whether the match succeeded (i.e., theBooleanproperty wastrue) and one field that provides the name of the property.The result of a
Booleanproperty match operation, such as one performed by aBePropertyMatcher, which contains one field that indicates whether the match succeeded (i.e., theBooleanproperty wastrue) and one field that provides the name of the property.For an example of a
BePropertyMatchResultin action, see the documentation forBePropertyMatcher.- matches
indicates whether or not the matcher matched (if the
Booleanproperty was true, it was a match)- propertyName
the name of the
Booleanproperty that was matched against
- trait BePropertyMatcher[-T] extends (T) => BePropertyMatchResult
Trait extended by matcher objects, which may appear after the word
be, that can match against aBooleanproperty.Trait extended by matcher objects, which may appear after the word
be, that can match against aBooleanproperty. The match will succeed if and only if theBooleanproperty equalstrue. The object containing the property, which must be of the type specified by theBePropertyMatcher's type parameterT, is passed to theBePropertyMatcher'sapplymethod. The result is aBePropertyMatchResult. ABePropertyMatcheris, therefore, a function from the specified type,T, to aBePropertyMatchResult.Although
BePropertyMatcherandMatcherrepresent similar concepts, they have no inheritance relationship becauseMatcheris intended for use right aftershouldormustwhereasBePropertyMatcheris intended for use right afterbe.A
BePropertyMatcheressentially allows you to write statically typedBooleanproperty 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 isjava.io.File, they can only be used with instances of that type. (The compiler will enforce this.) All they do is create aBePropertyMatchResultwhosematchesfield istrueif and only if theBooleanproperty istrue. The second field,propertyName, is simply the string name of the property. Thefileanddirectoryvals create variables that can be used in matcher expressions that test whether ajava.io.Fileis 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
BePropertyMatchResultand the meaning of its fields, please see the documentation forBePropertyMatchResult. To understand whyBePropertyMatcheris contravariant in its type parameter, see the section entitled "Matcher's variance" in the documentation forMatcher. - final case class HavePropertyMatchResult[P](matches: Boolean, propertyName: String, expectedValue: P, actualValue: P) extends Product with Serializable
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
HavePropertyMatchResultin action, see the documentation forHavePropertyMatcher.- 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
- trait HavePropertyMatcher[-T, P] extends (T) => HavePropertyMatchResult[P]
Trait extended by matcher objects, which may appear after the word
have, that can match against a property of the type specified by theHavePropertyMatcher's second type parameterP.Trait extended by matcher objects, which may appear after the word
have, that can match against a property of the type specified by theHavePropertyMatcher's second type parameterP.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 theHavePropertyMatcher'sapplymethod. The result is aHavePropertyMatchResult[P]. AHavePropertyMatcheris, therefore, a function from the specified type,T, to aHavePropertyMatchResult[P].Although
HavePropertyMatcherandMatcherrepresent similar concepts, they have no inheritance relationship becauseMatcheris intended for use right aftershouldormustwhereasHavePropertyMatcheris intended for use right afterhave.A
HavePropertyMatcheressentially 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
titlemethod is called, it returns a newHavePropertyMatcher[Book, String]that can be used to match against thetitleproperty of theBookpassed to itsapplymethod. Because the type parameter of these twoHavePropertyMatchers isBook, they can only be used with instances of that type. (The compiler will enforce this.) The match will succeed if thetitleproperty equals the value passed asexpectedValue. If the match succeeds, thematchesfield of the returnedHavePropertyMatchResultwill betrue. The second field,propertyName, is simply the string name of the property. The third and fourth fields,expectedValueandactualValueindicate the expected and actual values, respectively, for the property. Here's an example that uses theseHavePropertyMatchers: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
HavePropertyMatchResultand the meaning of its fields, please see the documentation forHavePropertyMatchResult. To understand whyHavePropertyMatcheris contravariant in its type parameter, see the section entitled "Matcher's variance" in the documentation forMatcher. - final case class LazyArg(arg: Any)(f: (Any) => String) extends Product with Serializable
Transforms a given object's
toStringwith a given function lazily.Transforms a given object's
toStringwith a given function lazily.This class is intended to be used with the
mapResultmethod ofMatcherProducers, which you can use to modify error messages when composing matchers. This class exists to enable those error messages to be modified lazily, so thattoStringis invoked on the givenarg, and its result transformed by the given functionf, only when and if thetoStringmethod is invoked on theLazyArg. As a performance optimization, ScalaTest'sMatchResultavoids invokingtoStringon objects until and unless an error message is actually needed, to minimize unecessary creation and concatenation of strings. TheLazyArgclass enables this same performance optimization when composing matchers.The other design goal of
LazyArgis to make the internalargavailable for inspection in an IDE. In a future version of ScalaTest, theargsofMatchResultthat were used to create the error message will be included in theTestFailedException, so they can be inspected in IDEs. This is why theargfield ofLazyArgis public.For an example of using
LazyArg, see the Composing matchers section in the main documentation for traitMatcher.- arg
the argument
- f
a function that given the
argwill produce aString
- 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
The result of a match operation, such as one performed by a
MatcherorBeMatcher, 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 aPrettifier.The result of a match operation, such as one performed by a
MatcherorBeMatcher, 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 aPrettifier. Using the default constructor, failure messages will be constructed lazily (when required).A
MatchResult'smatchesfield indicates whether a match succeeded. If it succeeded,matcheswill betrue. There are four methods,failureMessage,negatedfailureMessage,midSentenceFailureMessageandnegatedMidSentenceFailureMessagethat 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 (matchesisfalse), thefailureMessage(ormidSentenceFailure—more on that below) will be reported to help the user understand what went wrong.Understanding
negatedFailureMessageThe
negatedFailureMessageexists so that it can become thefailureMessageif the matcher is inverted, which happens, for instance, if it is passed tonot. Here's an example:val equalSeven = equal (7) val notEqualSeven = not (equalSeven)
The
Matcher[Int]that results from passing 7 toequal, which is assigned to theequalSevenvariable, will compareInts passed to itsapplymethod with 7. If 7 is passed, theequalSevenmatch will succeed. If anything other than 7 is passed, it will fail. By contrast, thenotEqualSevenmatcher, which results from passingequalSeventonot, does just the opposite. If 7 is passed, thenotEqualSevenmatch will fail. If anything other than 7 is passed, it will succeed.For example, if 8 is passed,
equalSeven'sMatchResultwill contain:expression: equalSeven(8) matches: false failureMessage: 8 did not equal 7 negatedFailureMessage: 8 equaled 7Although the
negatedFailureMessageis nonsensical, it will not be reported to the user. Only thefailureMessage, which does actually explain what caused the failure, will be reported by the user. If you pass 8 tonotEqualSeven'sapplymethod, by contrast, thefailureMessageandnegatedFailureMessagewill be:expression: notEqualSeven(8) matches: true failureMessage: 8 equaled 7 negatedFailureMessage: 8 did not equal 7Note that the messages are swapped from the
equalSevenmessages. This swapping was effectively performed by thenotmatcher, which in addition to swapping thefailureMessageandnegatedFailureMessage, also inverted thematchesvalue. Thus when you pass the same value to bothequalSevenandnotEqualSeventhematchesfield of oneMatchResultwill betrueand the otherfalse. Because thematchesfield of theMatchResultreturned bynotEqualSeven(8)istrue, the nonsensicalfailureMessage, "8 equaled 7", will not be reported to the user.If 7 is passed, by contrast, the
failureMessageandnegatedFailureMessageofequalSevenwill be:expression: equalSeven(7) matches: true failureMessage: 7 did not equal 7 negatedFailureMessage: 7 equaled 7In this case
equalSeven'sfailureMessageis nonsensical, but because the match succeeded, the nonsensical message will not be reported to the user. If you pass 7 tonotEqualSeven'sapplymethod, you'll get:expression: notEqualSeven(7) matches: false failureMessage: 7 equaled 7 negatedFailureMessage: 7 did not equal 7Again the messages are swapped from the
equalSevenmessages, but this time, thefailureMessagemakes sense and explains what went wrong: thenotEqualSevenmatch 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" messagesWhen a ScalaTest matcher expression that involves
andororfails, the failure message that results is composed from the failure messages of the left and right matcher operatnds toandor 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
midSentenceFailureMessageexists for this situation. If the failure message is used at the beginning of the sentence,failureMessagewill be used. But if it appears mid-sentence, or at the end of the sentence,midSentenceFailureMessagewill 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
orexpression 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
- trait Matcher[-T] extends (T) => MatchResult
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
applymethod. The result is aMatchResult. A matcher is, therefore, a function from the specified type,T, to aMatchResult.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 aftershould. For example, although you can ensure that ajava.io.Filehas 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]namedendWithExtension, 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 CustomMatchersNote: the
CustomMatcherscompanion 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 adefnamedendWithExtensionthat returns a new instance ofFileEndsWithExtensionMatcher. Because the class extendsMatcher[java.io.File], the compiler will only allow it be used to match against instances ofjava.io.File. A matcher must declare anapplymethod that takes the type decared inMatcher's type parameter, in this casejava.io.File. The apply method will return aMatchResultwhosematchesfield will indicate whether the match succeeded. ThefailureMessagefield will provide a programmer-friendly error message indicating, in the event of a match failure, what caused the match to fail.The
FileEndsWithExtensionMatchermatcher in this example determines success by determining if the passedjava.io.Fileends with the desired extension. It does this in the first argument passed to theMatchResultfactory 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.Filehas the nameessay.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 forMatchResult.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
hiddenlike 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
beOddmatcher, you could use it like this:3 should beOdd 4 should not (beOdd)
Composing matchers
You can also compose matchers. For example, the
endWithExtensionmatcher from the example above can be more easily created by composing a function with the existingendWithmatcher: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]whoseapplymethod first invokes the converter function to convert the passedFileto aString, then passes the resultingStringtoendWith. Thus, you could use this versionendWithExtensionlike 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
beAsIntsGreaterThangives no hint that theInts being compared were parsed fromStrings:scala> "7" should beAsIntsGreaterThan ("8") org.scalatest.exceptions.TestFailedException: 7 was not greater than 8To modify error message, you can use trait
MatcherProducers, which also provides acomposeTwicemethod that performs thecompose...andThen...composeoperation: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 8To modify the error messages, you can use
mapResultfromMatcherProducers. 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
mapResultmethod takes a function that accepts aMatchResultand produces a newMatchResult, which can contain modified arguments and modified error messages. In this example, the error messages are being modified by wrapping the old arguments inLazyArginstances that lazily apply the given prettification functions to thetoStringresult 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".toIntMatcher's variance
Matcheris 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 inMatchers, result in an object that has ashouldmethod that takes aMatcher[Orange]. If the static type of the matcher being passed toshouldisMatcher[Valencia]it shouldn't (and won't) compile. The reason it shouldn't compile is that the left value is anOrange, but not necessarily aValencia, and aMatcher[Valencia]only knows how to match against aValencia. The reason it won't compile is given thatMatcheris contravariant in its type parameter,T, aMatcher[Valencia]is not a subtype ofMatcher[Orange].By contrast, if the static type of the matcher being passed to
shouldisMatcher[Fruit], it should (and will) compile. The reason it should compile is that given the left value is anOrange, it is also aFruit, and aMatcher[Fruit]knows how to match againstFruits. The reason it will compile is that given thatMatcheris contravariant in its type parameter,T, aMatcher[Fruit]is indeed a subtype ofMatcher[Orange]. - trait MatcherProducers extends AnyRef
Provides an implicit conversion on functions that produce
Matchers, i.e.,T => Matcher[T]that enables you to modify error messages when composingMatchers.Provides an implicit conversion on functions that produce
Matchers, i.e.,T => Matcher[T]that enables you to modify error messages when composingMatchers.For an example of using
MatcherProducers, see the Composing matchers section in the main documentation for traitMatcher.
Value Members
- object BeMatcher
Companion object for trait
BeMatcherthat provides a factory method that creates aBeMatcher[T]from a passed function of type(T => MatchResult). - object BePropertyMatchResult extends Serializable
Companion object for the
BePropertyMatchResultcase class. - object BePropertyMatcher
Companion object for trait
BePropertyMatcherthat provides a factory method that creates aBePropertyMatcher[T]from a passed function of type(T => BePropertyMatchResult). - object HavePropertyMatchResult extends Serializable
Companion object for the
HavePropertyMatchResultcase class. - object HavePropertyMatcher
Companion object for trait
HavePropertyMatcherthat provides a factory method that creates aHavePropertyMatcher[T]from a passed function of type(T => HavePropertyMatchResult). - object MatchFailed
Singleton object that provides
unapplymethod to extract failure message fromMatchResulthavingmatchesproperty value offalse. - object MatchPatternHelper
MatchPatternHelperis called byMatchPatternMacroto supportmatchPatternsyntax. - object MatchResult extends Serializable
Companion object for the
MatchResultcase class. - object MatchSucceeded
Singleton object that provides
unapplymethod to extract negated failure message fromMatchResulthavingmatchesproperty value oftrue. - object Matcher
Companion object for trait
Matcherthat provides a factory method that creates aMatcher[T]from a passed function of type(T => MatchResult). - object MatcherProducers extends MatcherProducers
Companion object that facilitates the importing of
MatcherProducersmembers as an alternative to mixing it in.Companion object that facilitates the importing of
MatcherProducersmembers as an alternative to mixing it in. One use case is to importMatcherProducers's members so you can useMatcherProducersin the Scala interpreter. - object TypeMatcherHelper
TypeMatcherHelperis called byTypeMatcherMacroto supporta [Type]andan [Type]syntax.TypeMatcherHelperis called byTypeMatcherMacroto supporta [Type]andan [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
TypeMatcherHelperdirectly.