All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.scalatest.matchers.MustMatchers.scala Maven / Gradle / Ivy

Go to download

ScalaTest is a free, open-source testing toolkit for Scala and Java programmers.

There is a newer version: 2.0.M6-SNAP4
Show newest version
/*
 * Copyright 2001-2008 Artima, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.scalatest.matchers

import org.scalatest._
import scala.reflect.Manifest
import org.scalatest.verb.MustVerb
import scala.collection.GenTraversable
import scala.collection.GenSeq
import scala.collection.GenMap
import Assertions.areEqualComparingArraysStructurally

/**
 * Trait that provides a domain specific language (DSL) for expressing assertions in tests
 * using the word must. (If you prefer the word should, you can alternatively
 * mix in trait ShouldMatchers.) For example, if you mix MustMatchers into
 * a suite class, you can write an equality assertion in that suite like this:
 * 
 * 
 * result must equal (3)
 * 
* *

* Here result is a variable, and can be of any type. If the object is an * Int with the value 3, execution will continue (i.e., the expression will result * in the unit value, ()). Otherwise, a TestFailedException * will be thrown with a detail message that explains the problem, such as "7 did not equal 3". * This TestFailedException will cause the test to fail. *

* *

* The left must equal (right) syntax works by calling == on the left * value, passing in the right value, on every type except arrays. If both left and right are arrays, deep * will be invoked on both left and right before comparing them with ==. Thus, even though this expression * will yield false, because Array's equals method compares object identity: *

* *
 * Array(1, 2) == Array(1, 2) // yields false
 * 
* *

* The following expression will not result in a TestFailedException, because ScalaTest compares * the two arrays structurally, taking into consideration the equality of the array's contents: *

* *
 * Array(1, 2) must equal (Array(1, 2)) // succeeds (i.e., does not throw TestFailedException)
 * 
* *

* If you ever do want to verify that two arrays are actually the same object (have the same identity), you can use the * be theSameInstanceAs syntax, described below. *

* *

Checking size and length

* *

* You can check the size or length of just about any type of object for which it * would make sense. Here's how checking for length looks: *

*
 * result must have length (3)
 * 
* *

* Size is similar: *

* *
 * result must have size (10)
 * 
* *

* The length syntax can be used with String, Array, any scala.collection.GenSeq, * any java.util.List, and any type T for which an implicit Length[T] type class is * available in scope. * Similarly, the size syntax can be used with Array, any scala.collection.GenTraversable, * any java.util.List, and any type T for which an implicit Size[T] type class is * available in scope. You can enable the length or size syntax for your own arbitrary types, therefore, * by defining Length or Size type * classes for those types. *

* *

Checking strings

* *

* You can check for whether a string starts with, ends with, or includes a substring like this: *

* *
 * string must startWith ("Hello")
 * string must endWith ("world")
 * string must include ("seven")
 * 
* *

* You can check for whether a string starts with, ends with, or includes a regular expression, like this: *

* *
 * string must startWith regex ("Hel*o")
 * string must endWith regex ("wo.ld")
 * string must include regex ("wo.ld")
 * 
* *

* And you can check whether a string fully matches a regular expression, like this: *

* *
 * string must fullyMatch regex ("""(-)?(\d+)(\.\d*)?""")
 * 
* *

* The regular expression passed following the regex token can be either a String * or a scala.util.matching.Regex. *

* *

Greater and less than

*

* You can check whether any type that is, or can be implicitly converted to, * an Ordered[T] is greater than, less than, greater than or equal, or less * than or equal to a value of type T. The syntax is: *

*
 * one must be < (7)
 * one must be > (0)
 * one must be <= (7)
 * one must be >= (0)
 * 
* *

Checking equality with be ===

* *

* An alternate way to check for equality of two objects is to use be with * ===. Here's an example: *

* *
 * result must be === (3)
 * 
* *

* Here result is a variable, and can be of any type. If the object is an * Int with the value 3, execution will continue (i.e., the expression will result * in the unit value, ()). Otherwise, a TestFailedException * will be thrown with a detail message that explains the problem, such as "7 was not equal to 3". * This TestFailedException will cause the test to fail. *

* *

* The left must be === (right) syntax works by calling == on the left * value, passing in the right value, on every type except arrays. If both left and right are arrays, deep * will be invoked on both left and right before comparing them with ==. Thus, even though this expression * will yield false, because Array's equals method compares object identity: *

* *
 * Array(1, 2) == Array(1, 2) // yields false
 * 
* *

* The following expression will not result in a TestFailedException, because ScalaTest compares * the two arrays structurally, taking into consideration the equality of the array's contents: *

* *
 * Array(1, 2) must be === (Array(1, 2)) // succeeds (i.e., does not throw TestFailedException)
 * 
* *

* If you ever do want to verify that two arrays are actually the same object (have the same identity), you can use the * be theSameInstanceAs syntax, described below. *

* *

Checking Boolean properties with be

* *

* If an object has a method that takes no parameters and returns boolean, you can check * it by placing a Symbol (after be) that specifies the name * of the method (excluding an optional prefix of "is"). A symbol literal * in Scala begins with a tick mark and ends at the first non-identifier character. Thus, * 'empty results in a Symbol object at runtime, as does * 'defined and 'file. Here's an example: *

* *
 * emptySet must be ('empty)
 * 
* * Given this code, ScalaTest will use reflection to look on the object referenced from * emptySet for a method that takes no parameters and results in Boolean, * with either the name empty or isEmpty. If found, it will invoke * that method. If the method returns true, execution will continue. But if it returns * false, a TestFailedException will be thrown that will contain a detail message, such as: * *
 * Set(1, 2, 3) was not empty
 * 
* *

* This be syntax can be used with any type. If the object does * not have an appropriately named predicate method, you'll get a TestFailedException * at runtime with a detail message that explains the problem. * (For the details on how a field or method is selected during this * process, see the documentation for BeWord.) *

* *

* If you think it reads better, you can optionally put a or an after * be. For example, java.io.File has two predicate methods, * isFile and isDirectory. Thus with a File object * named temp, you could write: *

* *
 * temp must be a ('file)
 * 
* *

* Or, given java.awt.event.KeyEvent has a method isActionKey that takes * no arguments and returns Boolean, you could assert that a KeyEvent is * an action key with: *

* *
 * keyEvent must be an ('actionKey)
 * 
* *

* If you prefer to check Boolean properties in a type-safe manner, you can use a BePropertyMatcher. * This would allow you to write expressions such as: *

* *
 * emptySet must be (empty)
 * temp must be a (file)
 * keyEvent must be an (actionKey)
 * 
* *

* These expressions would fail to compile if must is used on an inappropriate type, as determined * by the type parameter of the BePropertyMatcher being used. (For example, file in this example * would likely be of type BePropertyMatcher[java.io.File]. If used with an appropriate type, such an expression will compile * and at run time the Boolean property method or field will be accessed directly; i.e., no reflection will be used. * See the documentation for BePropertyMatcher for more information. *

* *

Using custom BeMatchers

* * If you want to create a new way of using be, which doesn't map to an actual property on the * type you care about, you can create a BeMatcher. You could use this, for example, to create BeMatcher[Int] * called odd, which would match any odd Int, and even, which would match * any even Int. * Given this pair of BeMatchers, you could check whether an Int was odd or even with expressions like: *

* *
 * num must be (odd)
 * num must not be (even)
 * 
* * For more information, see the documentation for BeMatcher. * *

Checking object identity

* *

* If you need to check that two references refer to the exact same object, you can write: *

* *
 * ref1 must be theSameInstanceAs (ref2)
 * 
* *

Checking numbers against a range

* *

* To check whether a floating point number has a value that exactly matches another, you * can use must equal: *

* *
 * sevenDotOh must equal (7.0)
 * 
* *

* Often, however, you may want to check whether a floating point number is within a * range. You can do that using be and plusOrMinus, like this: *

* *
 * sevenDotOh must be (6.9 plusOrMinus 0.2)
 * 
* *

* This expression will cause a TestFailedException to be thrown if the floating point * value, sevenDotOh is outside the range 6.7 to 7.1. * You can also use plusOrMinus with integral types, for example: *

* *
 * seven must be (6 plusOrMinus 2)
 * 
* *

Traversables, iterables, sets, sequences, and maps

* *

* You can use some of the syntax shown previously with Iterable and its * subtypes. For example, you can check whether an Iterable is empty, * like this: *

* *
 * iterable must be ('empty)
 * 
* *

* You can check the length of an Seq (Array, List, etc.), * like this: *

* *
 * array must have length (3)
 * list must have length (9)
 * 
* *

* You can check the size of any Traversable, like this: *

* *
 * map must have size (20)
 * set must have size (90)
 * 
* *

* In addition, you can check whether an Iterable contains a particular * element, like this: *

* *
 * iterable must contain ("five")
 * 
* *

* You can also check whether a Map contains a particular key, or value, like this: *

* *
 * map must contain key (1)
 * map must contain value ("Howdy")
 * 
* *

Java collections and maps

* *

* You can use similar syntax on Java collections (java.util.Collection) and maps (java.util.Map). * For example, you can check whether a Java Collection or Map is empty, * like this: *

* *
 * javaCollection must be ('empty)
 * javaMap must be ('empty)
 * 
* *

* Even though Java's List type doesn't actually have a length or getLength method, * you can nevertheless check the length of a Java List (java.util.List) like this: *

* *
 * javaList must have length (9)
 * 
* *

* You can check the size of any Java Collection or Map, like this: *

* *
 * javaMap must have size (20)
 * javaSet must have size (90)
 * 
* *

* In addition, you can check whether a Java Collection contains a particular * element, like this: *

* *
 * javaCollection must contain ("five")
 * 
* *

* One difference to note between the syntax supported on Java collections and that of Scala * iterables is that you can't use contain (...) syntax with a Java Map. * Java differs from Scala in that its Map is not a subtype of its Collection type. * If you want to check that a Java Map contains a specific key/value pair, the best approach is * to invoke entrySet on the Java Map and check that entry set for the appropriate * element (a java.util.Map.Entry) using contain (...). *

* *

* Despite this difference, the other (more commonly used) map matcher syntax works just fine on Java Maps. * You can, for example, check whether a Java Map contains a particular key, or value, like this: *

* *
 * javaMap must contain key (1)
 * javaMap must contain value ("Howdy")
 * 
* *

Be as an equality comparison

* *

* All uses of be other than those shown previously perform an equality comparison. In other words, they work * the same as equals. This redundance between be and equals exists because it enables syntax * that sometimes sounds more natural. For example, instead of writing: *

* *
 * result must equal (null)
 * 
* *

* You can write: *

* *
 * result must be (null)
 * 
* *

* (Hopefully you won't write that too much given null is error prone, and Option * is usually a better, well, option.) * Here are some other examples of be used for equality comparison: *

* *
 * sum must be (7.0)
 * boring must be (false)
 * fun must be (true)
 * list must be (Nil)
 * option must be (None)
 * option must be (Some(1))
 * 
* *

* As with equal, using be on two arrays results in deep being called on both arrays prior to * calling equal. As a result, * the following expression would not throw a TestFailedException: *

* *
 * Array(1, 2) must be (Array(1, 2)) // succeeds (i.e., does not throw TestFailedException)
 * 
* *

* Because be is used in several ways in ScalaTest matcher syntax, just as it is used in many ways in English, one * potential point of confusion in the event of a failure is determining whether be was being used as an equality comparison or * in some other way, such as a property assertion. To make it more obvious when be is being used for equality, the failure * messages generated for those equality checks will include the word equal in them. For example, if this expression fails with a * TestFailedException: *

* *
 * option must be (Some(1))
 * 
* *

* The detail message in that TestFailedException will include the words "equal to" to signify be * was in this case being used for equality comparison: *

* *
 * Some(2) was not equal to Some(1)
 * 
* *

Being negative

* *

* If you wish to check the opposite of some condition, you can simply insert not in the expression. * Here are a few examples: *

* *
 * result must not be (null)
 * sum must not be <= (10)
 * mylist must not equal (yourList)
 * string must not startWith ("Hello")
 * 
* *

Logical expressions with and and or

* *

* You can also combine matcher expressions with and and/or or, however, * you must place parentheses or curly braces around the and or or expression. For example, * this and-expression would not compile, because the parentheses are missing: *

* *
 * map must contain key ("two") and not contain value (7) // ERROR, parentheses missing!
 * 
* *

* Instead, you need to write: *

* *
 * map must (contain key ("two") and not contain value (7))
 * 
* *

* Here are some more examples: *

* *
 * number must (be > (0) and be <= (10))
 * option must (equal (Some(List(1, 2, 3))) or be (None))
 * string must (
 *   equal ("fee") or
 *   equal ("fie") or
 *   equal ("foe") or
 *   equal ("fum")
 * )
 * 
* *

* Two differences exist between expressions composed of these and and or operators and the expressions you can write * on regular Booleans using its && and || operators. First, expressions with and * and or do not short-circuit. The following contrived expression, for example, would print "hello, world!": *

* *
 * "yellow" must (equal ("blue") and equal { println("hello, world!"); "green" })
 * 
* *

* In other words, the entire and or or expression is always evaluated, so you'll see any side effects * of the right-hand side even if evaluating * only the left-hand side is enough to determine the ultimate result of the larger expression. Failure messages produced by these * expressions will "short-circuit," however, * mentioning only the left-hand side if that's enough to determine the result of the entire expression. This "short-circuiting" behavior * of failure messages is intended * to make it easier and quicker for you to ascertain which part of the expression caused the failure. The failure message for the previous * expression, for example, would be: *

* *
 * "yellow" did not equal "blue"
 * 
* *

* Most likely this lack of short-circuiting would rarely be noticeable, because evaluating the right hand side will usually not * involve a side effect. One situation where it might show up, however, is if you attempt to and a null check on a variable with an expression * that uses the variable, like this: *

* *
 * map must (not be (null) and contain key ("ouch"))
 * 
* *

* If map is null, the test will indeed fail, but with a NullPointerException, not a * TestFailedException. Here, the NullPointerException is the visible right-hand side effect. To get a * TestFailedException, you would need to check each assertion separately: *

* *
 * map must not be (null)
 * map must contain key ("ouch")
 * 
* *

* If map is null in this case, the null check in the first expression will fail with * a TestFailedException, and the second expression will never be executed. *

* *

* The other difference with Boolean operators is that although && has a higher precedence than ||, * and and or * have the same precedence. Thus although the Boolean expression (a || b && c) will evaluate the && expression * before the || expression, like (a || (b && c)), the following expression: *

* *
 * traversable must (contain (7) or contain (8) and have size (9))
 * 
* *

* Will evaluate left to right, as: *

* *
 * traversable must ((contain (7) or contain (8)) and have size (9))
 * 
* *

* If you really want the and part to be evaluated first, you'll need to put in parentheses, like this: *

* *
 * traversable must (contain (7) or (contain (8) and have size (9)))
 * 
* *

Working with Options

* *

* ScalaTest matchers has no special support for Options, but you can * work with them quite easily using syntax shown previously. For example, if you wish to check * whether an option is None, you can write any of: *

* *
 * option must equal (None)
 * option must be (None)
 * option must not be ('defined)
 * option must be ('empty)
 * 
* *

* If you wish to check an option is defined, and holds a specific value, you can write either of: *

* *
 * option must equal (Some("hi"))
 * option must be (Some("hi"))
 * 
* *

* If you only wish to check that an option is defined, but don't care what it's value is, you can write: *

* *
 * option must be ('defined)
 * 
* *

* If you mix in (or import the members of) OptionValues, * you can write one statement that indicates you believe an option must be defined and then say something else about its value. Here's an example: *

* *
 * import org.scalatest.OptionValues._
 * option.value must be < (7)
 * 
* *

Checking arbitrary properties with have

* *

* Using have, you can check properties of any type, where a property is an attribute of any * object that can be retrieved either by a public field, method, or JavaBean-style get * or is method, like this: *

* *
 * book must have (
 *   'title ("Programming in Scala"),
 *   'author (List("Odersky", "Spoon", "Venners")),
 *   'pubYear (2008)
 * )
 * 
* *

* This expression will use reflection to ensure the title, author, and pubYear properties of object book * are equal to the specified values. For example, it will ensure that book has either a public Java field or method * named title, or a public method named getTitle, that when invoked (or accessed in the field case) results * in a the string "Programming in Scala". If all specified properties exist and have their expected values, respectively, * execution will continue. If one or more of the properties either does not exist, or exists but results in an unexpected value, * a TestFailedException will be thrown that explains the problem. (For the details on how a field or method is selected during this * process, see the documentation for HavePropertyMatcherGenerator.) *

* *

* When you use this syntax, you must place one or more property values in parentheses after have, seperated by commas, where a property * value is a symbol indicating the name of the property followed by the expected value in parentheses. The only exceptions to this rule is the syntax * for checking size and length shown previously, which does not require parentheses. If you forget and put parentheses in, however, everything will * still work as you'd expect. Thus instead of writing: *

* *
 * array must have length (3)
 * set must have size (90)
 * 
* *

* You can alternatively, write: *

* *
 * array must have (length (3))
 * set must have (size (90))
 * 
* *

* If a property has a value different from the specified expected value, a TestFailedError will be thrown * with a detail message that explains the problem. For example, if you assert the following on * a book whose title is Moby Dick: *

* *
 * book must have ('title ("A Tale of Two Cities"))
 * 
* *

* You'll get a TestFailedException with this detail message: *

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

* If you prefer to check properties in a type-safe manner, you can use a HavePropertyMatcher. * This would allow you to write expressions such as: *

* *
 * book must have (
 *   title ("Programming in Scala"),
 *   author (List("Odersky", "Spoon", "Venners")),
 *   pubYear (2008)
 * )
 * 
* *

* These expressions would fail to compile if must is used on an inappropriate type, as determined * by the type parameter of the HavePropertyMatcher being used. (For example, title in this example * might be of type HavePropertyMatcher[org.publiclibrary.Book]. If used with an appropriate type, such an expression will compile * and at run time the property method or field will be accessed directly; i.e., no reflection will be used. * See the documentation for HavePropertyMatcher for more information. *

* *

Using custom matchers

* *

* If none of the built-in matcher syntax (or options shown so far for extending the syntax) satisfy a particular need you have, you can create * custom Matchers that allow * you to place your own syntax directly after must. For example, class java.io.File has a method exists, which * indicates whether a file of a certain path and name exists. Because the exists method takes no parameters and returns Boolean, * you can call it using be with a symbol or BePropertyMatcher, yielding assertions like: *

* *
 * file must be ('exists)  // using a symbol
 * file must be (inExistance)   // using a BePropertyMatcher
 * 
* *

* Although these expressions will achieve your goal of throwing a TestFailedException if the file does not exist, they don't produce * the most readable code because the English is either incorrect or awkward. In this case, you might want to create a * custom Matcher[java.io.File] * named exist, which you could then use to write expressions like: *

* *
 * // using a plain-old Matcher
 * file must exist
 * file must not (exist)
 * file must (exist and have ('name ("temp.txt")))
 * 
* *

* Note that when you use custom Matchers, you will need to put parentheses around the custom matcher in more cases than with * the built-in syntax. For example you will often need the parentheses after not, as shown above. (There's no penalty for * always surrounding custom matchers with parentheses, and if you ever leave them off when they are needed, you'll get a compiler error.) * For more information about how to create custom Matchers, please see the documentation for the Matcher trait. *

* *

Checking for expected exceptions

* *

* Sometimes you need to test whether a method throws an expected exception under certain circumstances, such * as when invalid arguments are passed to the method. With MustMatchers mixed in, you can * check for an expected exception like this: *

* *
 * evaluating { s.charAt(-1) } must produce [IndexOutOfBoundsException]
 * 
* *

* If charAt throws an instance of StringIndexOutOfBoundsException, * this expression will result in that exception. But if charAt completes normally, or throws a different * exception, this expression will complete abruptly with a TestFailedException. * This expression returns the caught exception so that you can inspect it further if you wish, for * example, to ensure that data contained inside the exception has the expected values. Here's an * example: *

* *
 * val thrown = evaluating { s.charAt(-1) } must produce [IndexOutOfBoundsException]
 * thrown.getMessage must equal ("String index out of range: -1")
 * 
* *

Those pesky parens

* *

* Perhaps the most tricky part of writing assertions using ScalaTest matchers is remembering * when you need or don't need parentheses, but bearing in mind a few simple rules should help. * It is also reassuring to know that if you ever leave off a set of parentheses when they are * required, your code will not compile. Thus the compiler will help you remember when you need the parens. * That said, the rules are: *

* *

* 1. Although you don't always need them, it is recommended style to always put parentheses * around right-hand values, such as the 7 in num must equal (7): *

* *
 * result must equal (4)
 * array must have length (3)
 * book must have (
 *   'title ("Programming in Scala"),
 *   'author (List("Odersky", "Spoon", "Venners")),
 *   'pubYear (2008)
 * )
 * option must be ('defined)
 * catMap must (contain key (9) and contain value ("lives"))
 * keyEvent must be an ('actionKey)
 * javaSet must have size (90)
 * 
* *

* 2. Except for length and size, you must always put parentheses around * the list of one or more property values following a have: *

* *
 * file must (exist and have ('name ("temp.txt")))
 * book must have (
 *   title ("Programming in Scala"),
 *   author (List("Odersky", "Spoon", "Venners")),
 *   pubYear (2008)
 * )
 * javaList must have length (9) // parens optional for length and size
 * 
* *

* 3. You must always put parentheses around and and or expressions, as in: *

* *
 * catMap must (contain key (9) and contain value ("lives"))
 * number must (equal (2) or equal (4) or equal (8))
 * 
* *

* 4. Although you don't always need them, it is recommended style to always put parentheses * around custom Matchers when they appear directly after not: *

* *
 * file must exist
 * file must not (exist)
 * file must (exist and have ('name ("temp.txt")))
 * file must (not (exist) and have ('name ("temp.txt"))
 * file must (have ('name ("temp.txt") or exist)
 * file must (have ('name ("temp.txt") or not (exist))
 * 
* *

* That's it. With a bit of practice it should become natural to you, and the compiler will always be there to tell you if you * forget a set of needed parentheses. *

*/ trait MustMatchers extends Matchers with MustVerb { private object MustMethodHelper { def mustMatcher[T](left: T, rightMatcher: Matcher[T]) { rightMatcher(left) match { case MatchResult(false, failureMessage, _, _, _) => throw newTestFailedException(failureMessage) case _ => () } } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on objects of type Any. *

* * @author Bill Venners */ final class AnyMustWrapper[T](left: T) { /** * This method enables syntax such as the following: * *
     * result must equal (3)
     *        ^
     * 
*/ def must(rightMatcher: Matcher[T]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * result must not equal (3)
     *        ^
     * 
*/ def must(notWord: NotWord) = new ResultOfNotWord[T](left, false) } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on Strings. *

* * @author Bill Venners */ final class StringMustWrapper(left: String) extends StringMustWrapperForVerb(left) { /* * * This method enables syntax such as the following in a FlatSpec: * *
     * "A Stack (when empty)" must "be empty" in {
     *   assert(emptyStack.empty)
     * }
     * 
* *

* FlatSpec passes in a function via the implicit parameter that takes * three strings and results in a ResultOfStringPassedToVerb. This method * simply invokes this function, passing in left, right, and the verb string * "must". *

* def must(right: String)(implicit fun: (String, String, String) => ResultOfStringPassedToVerb): ResultOfStringPassedToVerb = { fun(left, right, "must") } def must(right: => Unit)(implicit fun: (String, () => Unit, String) => Unit) { fun(left, right _, "must") } */ /** * This method enables syntax such as the following: * *
     * string must equal ("hi")
     *        ^
     * 
*/ def must(rightMatcher: Matcher[String]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * string must be theSameInstanceAs anotherObject
     *        ^
     * 
*/ def must(beWord: BeWord): ResultOfBeWordForAnyRef[String] = new ResultOfBeWordForAnyRef(left, true) /** * This method enables syntax such as the following: * *
     * string must have length (3)
     *        ^
     * 
*/ def must(haveWord: HaveWord): ResultOfHaveWordForString = { new ResultOfHaveWordForString(left, true) } /** * This method enables syntax such as the following: * *
     * string must include regex ("hi")
     *        ^
     * 
*/ def must(includeWord: IncludeWord): ResultOfIncludeWordForString = { new ResultOfIncludeWordForString(left, true) } /** * This method enables syntax such as the following: * *
     * string must startWith regex ("hello")
     *        ^
     * 
*/ def must(startWithWord: StartWithWord): ResultOfStartWithWordForString = { new ResultOfStartWithWordForString(left, true) } /** * This method enables syntax such as the following: * *
     * string must endWith regex ("world")
     *        ^
     * 
*/ def must(endWithWord: EndWithWord): ResultOfEndWithWordForString = { new ResultOfEndWithWordForString(left, true) } /** * This method enables syntax such as the following: * *
     * string must fullyMatch regex ("""(-)?(\d+)(\.\d*)?""")
     *        ^
     * 
*/ def must(fullyMatchWord: FullyMatchWord): ResultOfFullyMatchWordForString = { new ResultOfFullyMatchWordForString(left, true) } /** * This method enables syntax such as the following: * *
     * string must not have length (3)
     *        ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForString = { new ResultOfNotWordForString(left, false) } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on Doubles. *

* * @author Bill Venners */ final class DoubleMustWrapper(left: Double) { /** * This method enables syntax such as the following: * *
     * aDouble must equal (8.8)
     *        ^
     * 
*/ def must(rightMatcher: Matcher[Double]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * result must not equal (8.8)
     *        ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForDouble = { new ResultOfNotWordForDouble(left, false) } def mustBe(right: Double) { if (left != right) { val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) throw newTestFailedException(FailureMessages("wasNotEqualTo", leftee, rightee)) } } def mustBe(beMatcher: BeMatcher[Double]) { beMatcher.apply(left).matches } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on Floats. *

* * @author Bill Venners */ final class FloatMustWrapper(left: Float) { /** * This method enables syntax such as the following: * *
     * aFloat must equal (3.3f)
     *       ^
     * 
*/ def must(rightMatcher: Matcher[Float]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * result must not equal (8.8f)
     *        ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForFloat = { new ResultOfNotWordForFloat(left, false) } def mustBe(right: Float) { if (left != right) { val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) throw newTestFailedException(FailureMessages("wasNotEqualTo", leftee, rightee)) } } def mustBe(beMatcher: BeMatcher[Float]) { beMatcher.apply(left).matches } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on Longs. *

* * @author Bill Venners */ final class LongMustWrapper(left: Long) { /** * This method enables syntax such as the following: * *
     * aLong must equal (3L)
     *      ^
     * 
*/ def must(rightMatcher: Matcher[Long]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * result must not equal (88L)
     *        ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForLong = { new ResultOfNotWordForLong(left, false) } def mustBe(right: Long) { if (left != right) { val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) throw newTestFailedException(FailureMessages("wasNotEqualTo", leftee, rightee)) } } def mustBe(beMatcher: BeMatcher[Long]) { beMatcher.apply(left).matches } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on Ints. *

* * @author Bill Venners */ final class IntMustWrapper(left: Int) { /** * This method enables syntax such as the following: * *
     * anInt must equal (3)
     *      ^
     * 
*/ def must(rightMatcher: Matcher[Int]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * result must not equal (8)
     *        ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForInt = { new ResultOfNotWordForInt(left, false) } def mustBe(right: Int) { if (left != right) { val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) throw newTestFailedException(FailureMessages("wasNotEqualTo", leftee, rightee)) } } def mustBe(beMatcher: BeMatcher[Int]) { beMatcher.apply(left).matches } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on Shorts. *

* * @author Bill Venners */ final class ShortMustWrapper(left: Short) { /** * This method enables syntax such as the following: * *
     * aShort must equal (3.toShort)
     *        ^
     * 
*/ def must(rightMatcher: Matcher[Short]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * result must not equal (8.toShort)
     *        ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForShort = { new ResultOfNotWordForShort(left, false) } def mustBe(right: Short) { if (left != right) { val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) throw newTestFailedException(FailureMessages("wasNotEqualTo", leftee, rightee)) } } def mustBe(beMatcher: BeMatcher[Short]) { beMatcher.apply(left).matches } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on Bytes. *

* * @author Bill Venners */ final class ByteMustWrapper(left: Byte) { /** * This method enables syntax such as the following: * *
     * aByte must equal (3.toByte)
     *       ^
     * 
*/ def must(rightMatcher: Matcher[Byte]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * result must not equal (8.toByte)
     *        ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForByte = { new ResultOfNotWordForByte(left, false) } def mustBe(right: Byte) { if (left != right) { val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) throw newTestFailedException(FailureMessages("wasNotEqualTo", leftee, rightee)) } } def mustBe(beMatcher: BeMatcher[Byte]) { beMatcher.apply(left).matches } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on objects of type scala.collection.GenMap[K, V]. *

* * @author Bill Venners */ final class MapMustWrapper[K, V](left: scala.collection.GenMap[K, V]) { /** * This method enables syntax such as the following: * *
     * map must equal (Map(1 -> "one", 2 -> "two"))
     *     ^
     * 
*/ def must(rightMatcher: Matcher[scala.collection.GenMap[K, V]]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * map must be theSameInstanceAs (anotherMap)
     *     ^
     * 
*/ def must(beWord: BeWord): ResultOfBeWordForAnyRef[scala.collection.GenMap[K, V]] = new ResultOfBeWordForAnyRef(left, true) /** * This method enables syntax such as the following: * *
     * map must have size (3)
     *     ^
     * 
*/ def must(haveWord: HaveWord): ResultOfHaveWordForTraversable[(K, V)] = { new ResultOfHaveWordForTraversable(left, true) } /** * This method enables syntax such as the following: * *
     * map must contain key (10)
     *     ^
     * 
*/ def must(containWord: ContainWord): ResultOfContainWordForMap[K, V] = { new ResultOfContainWordForMap(left, true) } /** * This method enables syntax such as the following: * *
     * map must not have size (3)
     *     ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForMap[K, V] = { new ResultOfNotWordForMap(left, false) } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on AnyRefs. *

* * @author Bill Venners */ final class AnyRefMustWrapper[T <: AnyRef](left: T) { /** * This method enables syntax such as the following: * *
     * anyRef must equal (anotherObject)
     *        ^
     * 
*/ def must(rightMatcher: Matcher[T]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * result must not have length (3)
     *        ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForAnyRef[T] = new ResultOfNotWordForAnyRef(left, false) /** * This method enables syntax such as the following: * *
     * result must be theSameInstanceAs anotherObject
     *        ^
     * 
*/ def must(beWord: BeWord): ResultOfBeWordForAnyRef[T] = new ResultOfBeWordForAnyRef(left, true) /** * This method enables syntax such as the following: * *
     * result must have length (3)
     *        ^
     * result must have size (3)
     *        ^
     * 
*/ def must(haveWord: HaveWord)(implicit ev: Extent[T]): ResultOfHaveWordForExtent[T] = new ResultOfHaveWordForExtent(left, true) def mustBe = new ResultOfBeWordForAnyRef(left, true) def mustBe(right: AnyRef) { def mustBeEqual(right: AnyRef): Boolean = { if (right.isInstanceOf[ResultOfAWordToBePropertyMatcherApplication[AnyRef]]) { // need to put in if because NoSuchMethodError when pattern match ResultOfAWordToBePropertyMatcherApplication val app = right.asInstanceOf[ResultOfAWordToBePropertyMatcherApplication[AnyRef]] app.bePropertyMatcher.apply(left).matches } else if (right.isInstanceOf[ResultOfAnWordToBePropertyMatcherApplication[AnyRef]]) { val app = right.asInstanceOf[ResultOfAnWordToBePropertyMatcherApplication[AnyRef]] app.bePropertyMatcher.apply(left).matches } else { val beWord = new BeWord right match { case rightSymbol: ResultOfAWordToSymbolApplication => beWord.a[AnyRef](rightSymbol.symbol)(left).matches case rightSymbol: ResultOfAnWordToSymbolApplication => beWord.an[AnyRef](rightSymbol.symbol)(left).matches case beMatcher: BeMatcher[AnyRef] => beMatcher.apply(left).matches case bePropertyMatcher: BePropertyMatcher[AnyRef] => bePropertyMatcher.apply(left).matches case _ => left == right } } } if (!mustBeEqual(right)) { val (resourceName, leftee, rightee) = if (right.isInstanceOf[ResultOfAWordToBePropertyMatcherApplication[AnyRef]]) { val app = right.asInstanceOf[ResultOfAWordToBePropertyMatcherApplication[AnyRef]] val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, UnquotedString(app.bePropertyMatcher.apply(left).propertyName)) ("wasNotA", leftee, rightee) } else if (right.isInstanceOf[ResultOfAnWordToBePropertyMatcherApplication[AnyRef]]) { val app = right.asInstanceOf[ResultOfAnWordToBePropertyMatcherApplication[AnyRef]] val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, UnquotedString(app.bePropertyMatcher.apply(left).propertyName)) ("wasNotAn", leftee, rightee) } else { right match { case bePropertyMatcher: BePropertyMatcher[AnyRef] => val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, UnquotedString(bePropertyMatcher.apply(left).propertyName)) ("wasNot", leftee, rightee) case _ => val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) ("wasNotEqualTo", leftee, rightee) } } throw newTestFailedException(FailureMessages(resourceName, leftee, rightee)) } } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on objects of type scala.Collection[T]. *

* * @author Bill Venners */ final class TraversableMustWrapper[T](left: GenTraversable[T]) { /** * This method enables syntax such as the following: * *
     * traversable must equal (Set(1, 2, 3))
     *             ^
     * 
*/ def must(rightMatcher: Matcher[GenTraversable[T]]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * traversable must have size (3)
     *             ^
     * 
*/ def must(haveWord: HaveWord): ResultOfHaveWordForTraversable[T] = new ResultOfHaveWordForTraversable(left, true) /** * This method enables syntax such as the following: * *
     * traversable must be theSameInstanceAs anotherObject
     *             ^
     * 
*/ def must(beWord: BeWord): ResultOfBeWordForAnyRef[GenTraversable[T]] = new ResultOfBeWordForAnyRef(left, true) /** * This method enables syntax such as the following: * *
     * traversable must not have size (3)
     *             ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForTraversable[T, GenTraversable[T]] = new ResultOfNotWordForTraversable(left, false) } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on objects of type java.util.Collection[T]. *

* * @author Bill Venners */ final class JavaCollectionMustWrapper[T](left: java.util.Collection[T]) { /** * This method enables syntax such as the following: * *
     * javaCollection must equal (aJavaSet)
     *                ^
     * 
*/ def must(rightMatcher: Matcher[java.util.Collection[T]]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * javaCollection must have size (3)
     *                ^
     * 
*/ def must(haveWord: HaveWord): ResultOfHaveWordForJavaCollection[T] = new ResultOfHaveWordForJavaCollection(left, true) /** * This method enables syntax such as the following: * *
     * javaCollection must be theSameInstanceAs anotherObject
     *                ^
     * 
*/ def must(beWord: BeWord): ResultOfBeWordForAnyRef[java.util.Collection[T]] = new ResultOfBeWordForAnyRef(left, true) /** * This method enables syntax such as the following: * *
     * javaCollection must not have size (3)
     *                ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForJavaCollection[T, java.util.Collection[T]] = new ResultOfNotWordForJavaCollection(left, false) } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on objects of type java.util.Map[K, V]. *

* * @author Bill Venners */ final class JavaMapMustWrapper[K, V](left: java.util.Map[K, V]) { /** * This method enables syntax such as the following: * *
     * javaMap must equal (someJavaMap)
     *         ^
     * 
*/ def must(rightMatcher: Matcher[java.util.Map[K, V]]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * javaMap must contain value (3)
     *         ^
     * 
*/ def must(containWord: ContainWord): ResultOfContainWordForJavaMap[K, V] = { new ResultOfContainWordForJavaMap(left, true) } /** * This method enables syntax such as the following: * *
     * javaMap must have size (3)
     *         ^
     * 
*/ def must(haveWord: HaveWord): ResultOfHaveWordForJavaMap = { new ResultOfHaveWordForJavaMap(left, true) } /** * This method enables syntax such as the following: * *
     * javaMap must not have length (3)
     *         ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForJavaMap[K, V] = { new ResultOfNotWordForJavaMap[K, V](left, false) } /** * This method enables syntax such as the following: * *
     * javaMap must be theSameInstanceAs anotherObject
     *         ^
     * 
*/ def must(beWord: BeWord): ResultOfBeWordForAnyRef[java.util.Map[K, V]] = new ResultOfBeWordForAnyRef(left, true) } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on objects of type GenSeq[T]. *

* * @author Bill Venners */ final class SeqMustWrapper[T](left: GenSeq[T]) { /** * This method enables syntax such as the following: * *
     * seq must equal (List(1, 2, 3))
     *     ^
     * 
*/ def must(rightMatcher: Matcher[GenSeq[T]]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * seq must have length (3)
     *     ^
     * 
*/ def must(haveWord: HaveWord): ResultOfHaveWordForSeq[T] = new ResultOfHaveWordForSeq(left, true) /* TODO: This is what I think it must be. But it was the AnyRef one, or maybe even not that. def must(notWord: NotWord): ResultOfNotWordForSeq[T, List[T]] = new ResultOfNotWordForSeq(left, false) */ /** * This method enables syntax such as the following: * *
     * seq must not have length (3)
     *     ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForAnyRef[GenSeq[T]] = new ResultOfNotWordForAnyRef(left, false) /** * This method enables syntax such as the following: * *
     * seq must be theSameInstanceAs anotherObject
     *     ^
     * 
*/ def must(beWord: BeWord): ResultOfBeWordForAnyRef[GenSeq[T]] = new ResultOfBeWordForAnyRef(left, true) } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on objects of type scala.Array[T]. *

* * @author Bill Venners */ final class ArrayMustWrapper[T](left: Array[T]) { /** * This method enables syntax such as the following: * *
     * array must equal (Array("one", "two"))
     *       ^
     * 
*/ def must(rightMatcher: Matcher[Array[T]]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * array must have length (3)
     *       ^
     * 
*/ def must(haveWord: HaveWord): ResultOfHaveWordForSeq[T] = { new ResultOfHaveWordForSeq(left, true) } /** * This method enables syntax such as the following: * *
     * array must not have length (3)
     *       ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForArray[T] = new ResultOfNotWordForArray(left, false) def mustBe(right: Array[T]) { if (!left.deep.equals(right.deep)) { val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) throw newTestFailedException(FailureMessages("wasNotEqualTo", leftee, rightee)) } } } // Note, no must(beWord) is needed here because a different implicit conversion will be used // on "array shoudl be ..." because this one doesn't solve the type error. /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on objects of type scala.List[T]. *

* * @author Bill Venners */ final class ListMustWrapper[T](left: List[T]) { /** * This method enables syntax such as the following: * *
     * list must equal (List(1, 2, 3))
     *      ^
     * 
*/ def must(rightMatcher: Matcher[List[T]]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * list must be theSameInstanceAs anotherObject
     *      ^
     * 
*/ def must(beWord: BeWord): ResultOfBeWordForAnyRef[List[T]] = new ResultOfBeWordForAnyRef(left, true) /** * This method enables syntax such as the following: * *
     * list must have length (3)
     *      ^
     * 
*/ def must(haveWord: HaveWord): ResultOfHaveWordForSeq[T] = new ResultOfHaveWordForSeq(left, true) /** * This method enables syntax such as the following: * *
     * list must not have length (3)
     *      ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForSeq[T, List[T]] = new ResultOfNotWordForSeq(left, false) } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable must methods to * be invoked on objects of type java.util.List[T]. *

* * @author Bill Venners */ final class JavaListMustWrapper[T](left: java.util.List[T]) { /** * This method enables syntax such as the following: * *
     * javaList must equal (someOtherJavaList)
     *          ^
     * 
*/ def must(rightMatcher: Matcher[java.util.List[T]]) { MustMethodHelper.mustMatcher(left, rightMatcher) } /** * This method enables syntax such as the following: * *
     * javaList must have length (3)
     *          ^
     * 
*/ def must(haveWord: HaveWord): ResultOfHaveWordForJavaList[T] = { new ResultOfHaveWordForJavaList(left, true) } /** * This method enables syntax such as the following: * *
     * javaList must not have length (3)
     *          ^
     * 
*/ def must(notWord: NotWord): ResultOfNotWordForJavaList[T, java.util.List[T]] = { new ResultOfNotWordForJavaList(left, false) } } /** * This class is part of the ScalaTest matchers DSL. Please see the documentation for MustMatchers or ShouldMatchers for an overview of * the matchers DSL. * *

* This class is used in conjunction with an implicit conversion to enable a must method to * be invoked on objects that result of evaulating { ... }. *

* * @author Bill Venners */ final class EvaluatingApplicationMustWrapper(left: ResultOfEvaluatingApplication) { /** * This method enables syntax such as the following: * *
     * evaluating { "hi".charAt(-1) } must produce [StringIndexOutOfBoundsException]
     *                                ^
     * 
*/ def must[T](resultOfProduceApplication: ResultOfProduceInvocation[T]): T = { val clazz = resultOfProduceApplication.clazz val caught = try { left.fun() None } catch { case u: Throwable => { if (!clazz.isAssignableFrom(u.getClass)) { val s = Resources("wrongException", clazz.getName, u.getClass.getName) throw newTestFailedException(s, Some(u)) // throw new TestFailedException(s, u, 3) XXX } else { Some(u) } } } caught match { case None => val message = Resources("exceptionExpected", clazz.getName) throw newTestFailedException(message) // throw new TestFailedException(message, 3) case Some(e) => e.asInstanceOf[T] // I know this cast will succeed, becuase isAssignableFrom succeeded above } } } /** * Implicitly converts an object of type T to a EvaluatingApplicationMustWrapper[T], * to enable must methods to be invokable on that object. */ implicit def convertToEvaluatingApplicationMustWrapper(o: ResultOfEvaluatingApplication): EvaluatingApplicationMustWrapper = new EvaluatingApplicationMustWrapper(o) /** * Implicitly converts an object of type T to a AnyMustWrapper[T], * to enable must methods to be invokable on that object. */ implicit def convertToAnyMustWrapper[T](o: T): AnyMustWrapper[T] = new AnyMustWrapper(o) /** * Implicitly converts an object of type scala.Double to a DoubleMustWrapper, * to enable must methods to be invokable on that object. */ implicit def convertToDoubleMustWrapper(o: Double): DoubleMustWrapper = new DoubleMustWrapper(o) /** * Implicitly converts an object of type scala.Float to a FloatMustWrapper, * to enable must methods to be invokable on that object. */ implicit def convertToFloatMustWrapper(o: Float): FloatMustWrapper = new FloatMustWrapper(o) /** * Implicitly converts an object of type scala.Long to a LongMustWrapper, * to enable must methods to be invokable on that object. */ implicit def convertToLongMustWrapper(o: Long): LongMustWrapper = new LongMustWrapper(o) /** * Implicitly converts an object of type scala.Int to a IntMustWrapper, * to enable must methods to be invokable on that object. */ implicit def convertToIntMustWrapper(o: Int): IntMustWrapper = new IntMustWrapper(o) /** * Implicitly converts an object of type scala.Short to a ShortMustWrapper, * to enable must methods to be invokable on that object. */ implicit def convertToShortMustWrapper(o: Short): ShortMustWrapper = new ShortMustWrapper(o) /** * Implicitly converts an object of type scala.Byte to a ByteMustWrapper, * to enable must methods to be invokable on that object. */ implicit def convertToByteMustWrapper(o: Byte): ByteMustWrapper = new ByteMustWrapper(o) /** * Implicitly converts a scala.AnyRef of type T to an AnyRefMustWrapper[T], * to enable must methods to be invokable on that object. */ implicit def convertToAnyRefMustWrapper[T <: AnyRef](o: T): AnyRefMustWrapper[T] = new AnyRefMustWrapper[T](o) /** * Implicitly converts an object of type scala.Collection[T] to a CollectionMustWrapper, * to enable must methods to be invokable on that object. */ implicit def convertToTraversableMustWrapper[T](o: GenTraversable[T]): TraversableMustWrapper[T] = new TraversableMustWrapper[T](o) /** * Implicitly converts an object of type GenSeq[T] to a SeqMustWrapper[T], * to enable must methods to be invokable on that object. */ implicit def convertToSeqMustWrapper[T](o: GenSeq[T]): SeqMustWrapper[T] = new SeqMustWrapper[T](o) /** * Implicitly converts an object of type scala.Array[T] to a ArrayMustWrapper[T], * to enable must methods to be invokable on that object. */ implicit def convertToArrayMustWrapper[T](o: Array[T]): ArrayMustWrapper[T] = new ArrayMustWrapper[T](o) /** * Implicitly converts an object of type scala.List[T] to a ListMustWrapper[T], * to enable must methods to be invokable on that object. */ implicit def convertToListMustWrapper[T](o: List[T]): ListMustWrapper[T] = new ListMustWrapper[T](o) /** * Implicitly converts an object of type scala.collection.GenMap[K, V] to a MapMustWrapper[K, V], * to enable must methods to be invokable on that object. */ implicit def convertToMapMustWrapper[K, V](o: scala.collection.GenMap[K, V]): MapMustWrapper[K, V] = new MapMustWrapper[K, V](o) /** * Implicitly converts an object of type java.lang.String to a StringMustWrapper, * to enable must methods to be invokable on that object. */ implicit override def convertToStringMustWrapper(o: String): StringMustWrapper = new StringMustWrapper(o) /** * Implicitly converts an object of type java.util.Collection[T] to a JavaCollectionMustWrapper[T], * to enable must methods to be invokable on that object. */ implicit def convertToJavaCollectionMustWrapper[T](o: java.util.Collection[T]): JavaCollectionMustWrapper[T] = new JavaCollectionMustWrapper[T](o) /** * Implicitly converts an object of type java.util.List[T] to a JavaListMustWrapper[T], * to enable must methods to be invokable on that object. This conversion is necessary to enable * length to be used on Java Lists. */ implicit def convertToJavaListMustWrapper[T](o: java.util.List[T]): JavaListMustWrapper[T] = new JavaListMustWrapper[T](o) /** * Implicitly converts an object of type java.util.Map[K, V] to a JavaMapMustWrapper[K, V], * to enable must methods to be invokable on that object. */ implicit def convertToJavaMapMustWrapper[K, V](o: java.util.Map[K, V]): JavaMapMustWrapper[K, V] = new JavaMapMustWrapper[K, V](o) } /* leave this explanation in. It is a useful reminder. THIS DOESN'T WORK BECAUSE... trait MustMethods[T] { val leftOperand: T def must(rightMatcher: Matcher[T]) { rightMatcher(leftOperand) match { case MatchResult(false, failureMessage, _) => throw newTestFailedException(failureMessage) case _ => () } } // I don't think there's a be on Any, because a (symbol) and an (symbol), pluse // theSameInstanceAs only work on AnyRefs // def must(beWord: BeWord): ResultOfBeWord[T] = new ResultOfBeWord(leftOperand, true) def must(notWord: NotWord) = new ResultOfNotWord[T](leftOperand, false) } trait MustMethodsForAnyRef[T <: AnyRef] extends MustMethods[T] { val leftOperand: T override def must(notWord: NotWord): ResultOfNotWordForAnyRef[T] = { new ResultOfNotWordForAnyRef(leftOperand, false) } def must(beWord: BeWord): ResultOfBeWordForAnyRef[T] = new ResultOfBeWordForAnyRef[T](leftOperand, true) } class CollectionMustWrapper[T](left: Collection[T]) extends { val leftOperand = left } with MustMethodsForAnyRef[Collection[T]] with MustContainWordForIterableMethods[T] with MustHaveWordForCollectionMethods[T] { override def must(notWord: NotWord): ResultOfNotWordForCollection[Collection[T]] = { new ResultOfNotWordForCollection(leftOperand, false) } } When you mix in the latter, the result type of must(BeWord) is still the more generic ResultOfNotWord, not ResultOfNotWordForAnyRef. As a result it doesn't have an "a (Symbol)" method on it. This triggers another implicit conversion in this case: emptySet must be a ('empty) Turns into: BeSymbolSpec.this.convertToAnyRefMustWrapper[BeSymbolSpec.this.CollectionMustWrapper[T]] (BeSymbolSpec.this.convertToCollectionMustWrapper[T](emptySet)).must(BeSymbolSpec.this.be). a(scala.Symbol.apply("empty")); So the problem with having these "methods" traits extend each other is the covariant result types don't get more specific visibly enough. LATER: Well, I'm wondering if now that I've removed the be method in MustMethods if this will work. */ /** * Companion object that facilitates the importing of MustMatchers members as * an alternative to mixing it the trait. One use case is to import MustMatchers members so you can use * them in the Scala interpreter: * *
 * $scala -classpath scalatest.jar
 * Welcome to Scala version 2.7.3.final (Java HotSpot(TM) Client VM, Java 1.5.0_16).
 * Type in expressions to have them evaluated.
 * Type :help for more information.
 * 
 * scala> import org.scalatest.matchers.MustMatchers._
 * import org.scalatest.matchers.MustMatchers._
 * 
 * scala> 1 must equal (2)
 * org.scalatest.TestFailedException: 1 did not equal 2
 * 	at org.scalatest.matchers.Helper$.newTestFailedException(Matchers.template:40)
 * 	at org.scalatest.matchers.MustMatchers$MustMethodHelper$.mustMatcher(MustMatchers.scala:826)
 * 	at org.scalatest.matchers.MustMatchers$IntMustWrapper.must(MustMatchers.scala:1123)
 * 	at .(:9)
 * 	at .()
 * 	at RequestR...
 *
 * scala> "hello, world" must startWith ("hello")
 * 
 * scala> 7 must (be >= (3) and not be <= (7))
 * org.scalatest.TestFailedException: 7 was greater than or equal to 3, but 7 was less than or equal to 7
 * 	at org.scalatest.matchers.Helper$.newTestFailedException(Matchers.template:40)
 * 	at org.scalatest.matchers.MustMatchers$MustMethodHelper$.mustMatcher(MustMatchers.scala:826)
 * 	at org.scalatest.matchers.MustMatchers$IntMustWrapper.must(MustMatchers.scala:1123)
 * 	at .(...
 * 
* * @author Bill Venners */ object MustMatchers extends MustMatchers




© 2015 - 2024 Weber Informatics LLC | Privacy Policy