org.scalatest.matchers.ShouldMatchers.scala Maven / Gradle / Ivy
Show all versions of scalatest_2.11.0-M3 Show documentation
/*
* 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.ShouldVerb
import scala.collection.Traversable
import Assertions.areEqualComparingArraysStructurally
/**
* Trait that provides a domain specific language (DSL) for expressing assertions in tests
* using the word should
. (If you prefer the word must
, you can alternatively
* mix in trait MustMatchers
.) For example, if you mix ShouldMatchers
into
* a suite class, you can write an equality assertion in that suite like this:
*
*
* result should 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 should 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) should 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 should have length (3)
*
*
*
*Size is similar:
*
*
*
* result should have size (10)
*
*
*
* The length
syntax can be used with any object that has a field or method named length
* or a method named getLength
. Similarly, the size
syntax can be used with any
* object that has a field or method named size
or a method named getSize
.
* The type of a length
or size
field, or return type of a method, must be either Int
* or Long
. Any such method must take no parameters. (The Scala compiler will ensure at compile time that
* the object on which should
is being invoked has the appropriate structure.)
*
*
* Checking strings
*
*
* You can check for whether a string starts with, ends with, or includes a substring like this:
*
*
*
* string should startWith ("Hello")
* string should endWith ("world")
* string should include ("seven")
*
*
*
* You can check for whether a string starts with, ends with, or includes a regular expression, like this:
*
*
*
* string should startWith regex ("Hel*o")
* string should endWith regex ("wo.ld")
* string should include regex ("wo.ld")
*
*
*
* And you can check whether a string fully matches a regular expression, like this:
*
*
*
* string should 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 should be < (7)
* one should be > (0)
* one should be <= (7)
* one should 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 should 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 should 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) should 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 should 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 should 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 should 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 should be (empty)
* temp should be a (file)
* keyEvent should be an (actionKey)
*
*
*
* These expressions would fail to compile if should
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 BeMatcher
s, you could check whether an Int
was odd or even with expressions like:
*
*
*
* num should be (odd)
* num should 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 should 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 should equal
:
*
*
*
* sevenDotOh should 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 should 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 should 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 should be ('empty)
*
*
*
* You can check the length of an Seq
(Array
, List
, etc.),
* like this:
*
*
*
* array should have length (3)
* list should have length (9)
*
*
*
* You can check the size of any Traversable
, like this:
*
*
*
* map should have size (20)
* set should have size (90)
*
*
*
* In addition, you can check whether an Iterable
contains a particular
* element, like this:
*
*
*
* iterable should contain ("five")
*
*
*
* You can also check whether a Map
contains a particular key, or value, like this:
*
*
*
* map should contain key (1)
* map should 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 should be ('empty)
* javaMap should 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 should have length (9)
*
*
*
* You can check the size of any Java Collection
or Map
, like this:
*
*
*
* javaMap should have size (20)
* javaSet should have size (90)
*
*
*
* In addition, you can check whether a Java Collection
contains a particular
* element, like this:
*
*
*
* javaCollection should 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 Map
s.
* You can, for example, check whether a Java Map
contains a particular key, or value, like this:
*
*
*
* javaMap should contain key (1)
* javaMap should 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 should equal (null)
*
*
*
* You can write:
*
*
*
* result should 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 should be (7.0)
* boring should be (false)
* fun should be (true)
* list should be (Nil)
* option should be (None)
* option should 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) should 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 should 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 should not be (null)
* sum should not be <= (10)
* mylist should not equal (yourList)
* string should 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 should contain key ("two") and not contain value (7) // ERROR, parentheses missing!
*
*
*
* Instead, you need to write:
*
*
*
* map should (contain key ("two") and not contain value (7))
*
*
*
* Here are some more examples:
*
*
*
* number should (be > (0) and be <= (10))
* option should (equal (Some(List(1, 2, 3))) or be (None))
* string should (
* 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 Boolean
s 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" should (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 should (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 should not be (null)
* map should 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 should (contain (7) or contain (8) and have size (9))
*
*
*
* Will evaluate left to right, as:
*
*
*
* traversable should ((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 should (contain (7) or (contain (8) and have size (9)))
*
*
* Working with Option
s
*
*
* ScalaTest matchers has no special support for Option
s, 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 should equal (None)
* option should be (None)
* option should not be ('defined)
* option should be ('empty)
*
*
*
* If you wish to check an option is defined, and holds a specific value, you can write either of:
*
*
*
* option should equal (Some("hi"))
* option should 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 should be ('defined)
*
*
*
* If you mix in (or import the members of) OptionValues
,
* you can write one statement that indicates you believe an option should be defined and then say something else about its value. Here's an example:
*
*
*
* import org.scalatest.OptionValues._
* option.value should 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 should 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 should have length (3)
* set should have size (90)
*
*
*
* You can alternatively, write:
*
*
*
* array should have (length (3))
* set should 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 should 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 should have (
* title ("Programming in Scala"),
* author (List("Odersky", "Spoon", "Venners")),
* pubYear (2008)
* )
*
*
*
* These expressions would fail to compile if should
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 Matcher
s that allow
* you to place your own syntax directly after should
. 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 should be ('exists) // using a symbol
* file should 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 should exist
* file should not (exist)
* file should (exist and have ('name ("temp.txt")))
*
*
*
* Note that when you use custom Matcher
s, 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 Matcher
s, 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 ShouldMatchers
mixed in, you can
* check for an expected exception like this:
*
*
*
* evaluating { s.charAt(-1) } should 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) } should produce [IndexOutOfBoundsException]
* thrown.getMessage should 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 should equal (7)
:
*
*
*
* result should equal (4)
* array should have length (3)
* book should have (
* 'title ("Programming in Scala"),
* 'author (List("Odersky", "Spoon", "Venners")),
* 'pubYear (2008)
* )
* option should be ('defined)
* catMap should (contain key (9) and contain value ("lives"))
* keyEvent should be an ('actionKey)
* javaSet should 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 should (exist and have ('name ("temp.txt")))
* book should have (
* title ("Programming in Scala"),
* author (List("Odersky", "Spoon", "Venners")),
* pubYear (2008)
* )
* javaList should have length (9) // parens optional for length and size
*
*
*
* 3. You must always put parentheses around and
and or
expressions, as in:
*
*
*
* catMap should (contain key (9) and contain value ("lives"))
* number should (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 Matcher
s when they appear directly after not
:
*
*
*
* file should exist
* file should not (exist)
* file should (exist and have ('name ("temp.txt")))
* file should (not (exist) and have ('name ("temp.txt"))
* file should (have ('name ("temp.txt") or exist)
* file should (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 ShouldMatchers extends Matchers with ShouldVerb {
private object ShouldMethodHelper {
def shouldMatcher[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 ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on objects of type Any
.
*
*
* @author Bill Venners
*/
final class AnyShouldWrapper[T](left: T) {
/**
* This method enables syntax such as the following:
*
*
* result should equal (3)
* ^
*
*/
def should(rightMatcher: Matcher[T]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* result should not equal (3)
* ^
*
*/
def should(notWord: NotWord) = new ResultOfNotWord[T](left, false)
}
// I think the type hasn't been converted yet here. It is just a pass-through. It finally gets
// converted in ResultOfHaveWordForLengthWrapper, at which point the actual implicit conversions
// from String, Array, and the structural types get applied.
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on AnyRef
objects that can be implicitly converted to type LengthWrapper
.
* Trait ShouldMatchers
includes implicit conversions from several types, including many structural types, to LengthWrapper
.
*
*
* @author Bill Venners
*/
final class LengthShouldWrapper[A <: AnyRef <% LengthWrapper](left: A) {
/**
* This method enables syntax such as the following:
*
*
* objectWithLength should equal (3)
* ^
*
*/
def should(rightMatcher: Matcher[A]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* result should have length (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForLengthWrapper[A] =
new ResultOfHaveWordForLengthWrapper(left, true)
/**
* This method enables syntax such as the following:
*
*
* result should not have length (3)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForLengthWrapper[A] =
new ResultOfNotWordForLengthWrapper(left, false)
/**
* This method enables syntax such as the following:
*
*
* result should be theSameInstanceAs anotherObject
* ^
*
*/
def should(beWord: BeWord): ResultOfBeWordForAnyRef[A] = new ResultOfBeWordForAnyRef[A](left, true)
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on AnyRef
objects that can be implicitly converted to type SizeWrapper
.
* Trait ShouldMatchers
includes implicit conversions from several types, including many structural types, to SizeWrapper
.
*
*
* @author Bill Venners
*/
final class SizeShouldWrapper[A <: AnyRef <% SizeWrapper](left: A) {
/**
* This method enables syntax such as the following:
*
*
* objectWithSize should equal (3)
* ^
*
*/
def should(rightMatcher: Matcher[A]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* result should not have size (3)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForSizeWrapper[A] =
new ResultOfNotWordForSizeWrapper(left, false)
/**
* This method enables syntax such as the following:
*
*
* result should have size (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForSizeWrapper[A] =
new ResultOfHaveWordForSizeWrapper(left, true)
// TODO I just added this. Didn't do a test for it.
/**
* This method enables syntax such as the following:
*
*
* result should be theSameInstanceAs anotherObject
* ^
*
*/
def should(beWord: BeWord): ResultOfBeWordForAnyRef[A] = new ResultOfBeWordForAnyRef[A](left, true)
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on String
s.
*
*
* @author Bill Venners
*/
final class StringShouldWrapper(left: String) extends StringShouldWrapperForVerb(left) {
/* *
* This method enables syntax such as the following in a FlatSpec
:
*
*
* "A Stack (when empty)" should "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
* "should"
.
*
*
def should(right: String)(implicit fun: (String, String, String) => ResultOfStringPassedToVerb): ResultOfStringPassedToVerb = {
fun(left, right, "should")
}
def should(right: => Unit)(implicit fun: (String, () => Unit, String) => Unit) {
fun(left, right _, "should")
} */
/**
* This method enables syntax such as the following:
*
*
* string should equal ("hi")
* ^
*
*/
def should(rightMatcher: Matcher[String]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* string should be theSameInstanceAs anotherObject
* ^
*
*/
def should(beWord: BeWord): ResultOfBeWordForAnyRef[String] = new ResultOfBeWordForAnyRef(left, true)
/**
* This method enables syntax such as the following:
*
*
* string should have length (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForString = {
new ResultOfHaveWordForString(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* string should include regex ("hi")
* ^
*
*/
def should(includeWord: IncludeWord): ResultOfIncludeWordForString = {
new ResultOfIncludeWordForString(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* string should startWith regex ("hello")
* ^
*
*/
def should(startWithWord: StartWithWord): ResultOfStartWithWordForString = {
new ResultOfStartWithWordForString(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* string should endWith regex ("world")
* ^
*
*/
def should(endWithWord: EndWithWord): ResultOfEndWithWordForString = {
new ResultOfEndWithWordForString(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* string should fullyMatch regex ("""(-)?(\d+)(\.\d*)?""")
* ^
*
*/
def should(fullyMatchWord: FullyMatchWord): ResultOfFullyMatchWordForString = {
new ResultOfFullyMatchWordForString(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* string should not have length (3)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForString = {
new ResultOfNotWordForString(left, false)
}
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on Double
s.
*
*
* @author Bill Venners
*/
final class DoubleShouldWrapper(left: Double) {
/**
* This method enables syntax such as the following:
*
*
* aDouble should equal (8.8)
* ^
*
*/
def should(rightMatcher: Matcher[Double]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* result should not equal (8.8)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForDouble = {
new ResultOfNotWordForDouble(left, false)
}
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on Float
s.
*
*
* @author Bill Venners
*/
final class FloatShouldWrapper(left: Float) {
/**
* This method enables syntax such as the following:
*
*
* aFloat should equal (3.3f)
* ^
*
*/
def should(rightMatcher: Matcher[Float]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* result should not equal (8.8f)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForFloat = {
new ResultOfNotWordForFloat(left, false)
}
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on Long
s.
*
*
* @author Bill Venners
*/
final class LongShouldWrapper(left: Long) {
/**
* This method enables syntax such as the following:
*
*
* aLong should equal (3L)
* ^
*
*/
def should(rightMatcher: Matcher[Long]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* result should not equal (88L)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForLong = {
new ResultOfNotWordForLong(left, false)
}
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on Int
s.
*
*
* @author Bill Venners
*/
final class IntShouldWrapper(left: Int) {
/**
* This method enables syntax such as the following:
*
*
* anInt should equal (3)
* ^
*
*/
def should(rightMatcher: Matcher[Int]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* result should not equal (8)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForInt = {
new ResultOfNotWordForInt(left, false)
}
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on Short
s.
*
*
* @author Bill Venners
*/
final class ShortShouldWrapper(left: Short) {
/**
* This method enables syntax such as the following:
*
*
* aShort should equal (3.toShort)
* ^
*
*/
def should(rightMatcher: Matcher[Short]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* result should not equal (8.toShort)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForShort = {
new ResultOfNotWordForShort(left, false)
}
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on Byte
s.
*
*
* @author Bill Venners
*/
final class ByteShouldWrapper(left: Byte) {
/**
* This method enables syntax such as the following:
*
*
* aByte should equal (3.toByte)
* ^
*
*/
def should(rightMatcher: Matcher[Byte]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* result should not equal (8.toByte)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForByte = {
new ResultOfNotWordForByte(left, false)
}
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on objects of type scala.collection.Map[K, V]
.
*
*
* @author Bill Venners
*/
final class MapShouldWrapper[K, V](left: scala.collection.Map[K, V]) {
/**
* This method enables syntax such as the following:
*
*
* map should equal (Map(1 -> "one", 2 -> "two"))
* ^
*
*/
def should(rightMatcher: Matcher[scala.collection.Map[K, V]]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* map should be theSameInstanceAs (anotherMap)
* ^
*
*/
def should(beWord: BeWord): ResultOfBeWordForAnyRef[scala.collection.Map[K, V]] = new ResultOfBeWordForAnyRef(left, true)
/**
* This method enables syntax such as the following:
*
*
* map should have size (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForTraversable[(K, V)] = {
new ResultOfHaveWordForTraversable(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* map should contain key (10)
* ^
*
*/
def should(containWord: ContainWord): ResultOfContainWordForMap[K, V] = {
new ResultOfContainWordForMap(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* map should not have size (3)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForMap[K, V] = {
new ResultOfNotWordForMap(left, false)
}
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on AnyRef
s.
*
*
* @author Bill Venners
*/
final class AnyRefShouldWrapper[T <: AnyRef](left: T) {
/**
* This method enables syntax such as the following:
*
*
* anyRef should equal (anotherObject)
* ^
*
*/
def should(rightMatcher: Matcher[T]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* result should not have length (3)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForAnyRef[T] =
new ResultOfNotWordForAnyRef(left, false)
/**
* This method enables syntax such as the following:
*
*
* result should be theSameInstanceAs anotherObject
* ^
*
*/
def should(beWord: BeWord): ResultOfBeWordForAnyRef[T] = new ResultOfBeWordForAnyRef(left, true)
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on objects of type scala.Collection[T]
.
*
*
* @author Bill Venners
*/
final class TraversableShouldWrapper[T](left: Traversable[T]) {
/**
* This method enables syntax such as the following:
*
*
* traversable should equal (Set(1, 2, 3))
* ^
*
*/
def should(rightMatcher: Matcher[Traversable[T]]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* traversable should have size (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForTraversable[T] =
new ResultOfHaveWordForTraversable(left, true)
/**
* This method enables syntax such as the following:
*
*
* traversable should be theSameInstanceAs anotherObject
* ^
*
*/
def should(beWord: BeWord): ResultOfBeWordForAnyRef[Traversable[T]] = new ResultOfBeWordForAnyRef(left, true)
/**
* This method enables syntax such as the following:
*
*
* traversable should not have size (3)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForTraversable[T, Traversable[T]] =
new ResultOfNotWordForTraversable(left, false)
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on objects of type java.util.Collection[T]
.
*
*
* @author Bill Venners
*/
final class JavaCollectionShouldWrapper[T](left: java.util.Collection[T]) {
/**
* This method enables syntax such as the following:
*
*
* javaCollection should equal (aJavaSet)
* ^
*
*/
def should(rightMatcher: Matcher[java.util.Collection[T]]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* javaCollection should have size (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForJavaCollection[T] =
new ResultOfHaveWordForJavaCollection(left, true)
/**
* This method enables syntax such as the following:
*
*
* javaCollection should be theSameInstanceAs anotherObject
* ^
*
*/
def should(beWord: BeWord): ResultOfBeWordForAnyRef[java.util.Collection[T]] = new ResultOfBeWordForAnyRef(left, true)
/**
* This method enables syntax such as the following:
*
*
* javaCollection should not have size (3)
* ^
*
*/
def should(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 ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on objects of type java.util.Map[K, V]
.
*
*
* @author Bill Venners
*/
final class JavaMapShouldWrapper[K, V](left: java.util.Map[K, V]) {
/**
* This method enables syntax such as the following:
*
*
* javaMap should equal (someJavaMap)
* ^
*
*/
def should(rightMatcher: Matcher[java.util.Map[K, V]]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* javaMap should contain value (3)
* ^
*
*/
def should(containWord: ContainWord): ResultOfContainWordForJavaMap[K, V] = {
new ResultOfContainWordForJavaMap(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* javaMap should have size (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForJavaMap = {
new ResultOfHaveWordForJavaMap(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* javaMap should not have length (3)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForJavaMap[K, V] = {
new ResultOfNotWordForJavaMap[K, V](left, false)
}
/**
* This method enables syntax such as the following:
*
*
* javaMap should be theSameInstanceAs anotherObject
* ^
*
*/
def should(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 ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on objects of type scala.Seq[T]
.
*
*
* @author Bill Venners
*/
final class SeqShouldWrapper[T](left: Seq[T]) {
/**
* This method enables syntax such as the following:
*
*
* seq should equal (List(1, 2, 3))
* ^
*
*/
def should(rightMatcher: Matcher[Seq[T]]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* seq should have length (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForSeq[T] =
new ResultOfHaveWordForSeq(left, true)
/* TODO: This is what I think it should be. But it was the AnyRef one, or maybe even not that.
def should(notWord: NotWord): ResultOfNotWordForSeq[T, List[T]] =
new ResultOfNotWordForSeq(left, false)
*/
/**
* This method enables syntax such as the following:
*
*
* seq should not have length (3)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForAnyRef[Seq[T]] =
new ResultOfNotWordForAnyRef(left, false)
/**
* This method enables syntax such as the following:
*
*
* seq should be theSameInstanceAs anotherObject
* ^
*
*/
def should(beWord: BeWord): ResultOfBeWordForAnyRef[Seq[T]] = new ResultOfBeWordForAnyRef(left, true)
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on objects of type scala.Array[T]
.
*
*
* @author Bill Venners
*/
final class ArrayShouldWrapper[T](left: Array[T]) {
/**
* This method enables syntax such as the following:
*
*
* array should equal (Array("one", "two"))
* ^
*
*/
def should(rightMatcher: Matcher[Array[T]]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* array should have length (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForSeq[T] = {
new ResultOfHaveWordForSeq(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* array should not have length (3)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForArray[T] =
new ResultOfNotWordForArray(left, false)
}
// Note, no should(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 ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on objects of type scala.List[T]
.
*
*
* @author Bill Venners
*/
final class ListShouldWrapper[T](left: List[T]) {
/**
* This method enables syntax such as the following:
*
*
* list should equal (List(1, 2, 3))
* ^
*
*/
def should(rightMatcher: Matcher[List[T]]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* list should be theSameInstanceAs anotherObject
* ^
*
*/
def should(beWord: BeWord): ResultOfBeWordForAnyRef[List[T]] = new ResultOfBeWordForAnyRef(left, true)
/**
* This method enables syntax such as the following:
*
*
* list should have length (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForSeq[T] =
new ResultOfHaveWordForSeq(left, true)
/**
* This method enables syntax such as the following:
*
*
* list should not have length (3)
* ^
*
*/
def should(notWord: NotWord): ResultOfNotWordForSeq[T, List[T]] =
new ResultOfNotWordForSeq(left, false)
}
/**
* This class is part of the ScalaTest matchers DSL. Please see the documentation for ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable should
methods to
* be invoked on objects of type java.util.List[T]
.
*
*
* @author Bill Venners
*/
final class JavaListShouldWrapper[T](left: java.util.List[T]) {
/**
* This method enables syntax such as the following:
*
*
* javaList should equal (someOtherJavaList)
* ^
*
*/
def should(rightMatcher: Matcher[java.util.List[T]]) {
ShouldMethodHelper.shouldMatcher(left, rightMatcher)
}
/**
* This method enables syntax such as the following:
*
*
* javaList should have length (3)
* ^
*
*/
def should(haveWord: HaveWord): ResultOfHaveWordForJavaList[T] = {
new ResultOfHaveWordForJavaList(left, true)
}
/**
* This method enables syntax such as the following:
*
*
* javaList should not have length (3)
* ^
*
*/
def should(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 ShouldMatchers
or MustMatchers
for an overview of
* the matchers DSL.
*
*
* This class is used in conjunction with an implicit conversion to enable a should
method to
* be invoked on objects that result of evaulating { ... }
.
*
*
* @author Bill Venners
*/
final class EvaluatingApplicationShouldWrapper(left: ResultOfEvaluatingApplication) {
/**
* This method enables syntax such as the following:
*
*
* evaluating { "hi".charAt(-1) } should produce [StringIndexOutOfBoundsException]
* ^
*
*/
def should[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 EvaluatingApplicationShouldWrapper[T]
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToEvaluatingApplicationShouldWrapper(o: ResultOfEvaluatingApplication): EvaluatingApplicationShouldWrapper = new EvaluatingApplicationShouldWrapper(o)
/**
* Implicitly converts an object of type T
to a AnyShouldWrapper[T]
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToAnyShouldWrapper[T](o: T): AnyShouldWrapper[T] = new AnyShouldWrapper(o)
/**
* Implicitly converts an object of type scala.Double
to a DoubleShouldWrapper
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToDoubleShouldWrapper(o: Double): DoubleShouldWrapper = new DoubleShouldWrapper(o)
/**
* Implicitly converts an object of type scala.Float
to a FloatShouldWrapper
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToFloatShouldWrapper(o: Float): FloatShouldWrapper = new FloatShouldWrapper(o)
/**
* Implicitly converts an object of type scala.Long
to a LongShouldWrapper
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToLongShouldWrapper(o: Long): LongShouldWrapper = new LongShouldWrapper(o)
/**
* Implicitly converts an object of type scala.Int
to a IntShouldWrapper
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToIntShouldWrapper(o: Int): IntShouldWrapper = new IntShouldWrapper(o)
/**
* Implicitly converts an object of type scala.Short
to a ShortShouldWrapper
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToShortShouldWrapper(o: Short): ShortShouldWrapper = new ShortShouldWrapper(o)
/**
* Implicitly converts an object of type scala.Byte
to a ByteShouldWrapper
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToByteShouldWrapper(o: Byte): ByteShouldWrapper = new ByteShouldWrapper(o)
/**
* Implicitly converts a scala.AnyRef
of type T
to an AnyRefShouldWrapper[T]
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToAnyRefShouldWrapper[T <: AnyRef](o: T): AnyRefShouldWrapper[T] = new AnyRefShouldWrapper[T](o)
/**
* Implicitly converts an object of type scala.Collection[T]
to a CollectionShouldWrapper
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToTraversableShouldWrapper[T](o: Traversable[T]): TraversableShouldWrapper[T] = new TraversableShouldWrapper[T](o)
/**
* Implicitly converts an object of type scala.Seq[T]
to a SeqShouldWrapper[T]
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToSeqShouldWrapper[T](o: Seq[T]): SeqShouldWrapper[T] = new SeqShouldWrapper[T](o)
/**
* Implicitly converts an object of type scala.Array[T]
to a ArrayShouldWrapper[T]
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToArrayShouldWrapper[T](o: Array[T]): ArrayShouldWrapper[T] = new ArrayShouldWrapper[T](o)
/**
* Implicitly converts an object of type scala.List[T]
to a ListShouldWrapper[T]
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToListShouldWrapper[T](o: List[T]): ListShouldWrapper[T] = new ListShouldWrapper[T](o)
/**
* Implicitly converts an object of type scala.collection.Map[K, V]
to a MapShouldWrapper[K, V]
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToMapShouldWrapper[K, V](o: scala.collection.Map[K, V]): MapShouldWrapper[K, V] = new MapShouldWrapper[K, V](o)
/**
* Implicitly converts an object of type java.lang.String
to a StringShouldWrapper
,
* to enable should
methods to be invokable on that object.
*/
implicit override def convertToStringShouldWrapper(o: String): StringShouldWrapper = new StringShouldWrapper(o)
/**
* Implicitly converts an object of type java.util.Collection[T]
to a JavaCollectionShouldWrapper[T]
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToJavaCollectionShouldWrapper[T](o: java.util.Collection[T]): JavaCollectionShouldWrapper[T] = new JavaCollectionShouldWrapper[T](o)
/**
* Implicitly converts an object of type java.util.List[T]
to a JavaListShouldWrapper[T]
,
* to enable should
methods to be invokable on that object. This conversion is necessary to enable
* length
to be used on Java List
s.
*/
implicit def convertToJavaListShouldWrapper[T](o: java.util.List[T]): JavaListShouldWrapper[T] = new JavaListShouldWrapper[T](o)
/**
* Implicitly converts an object of type java.util.Map[K, V]
to a JavaMapShouldWrapper[K, V]
,
* to enable should
methods to be invokable on that object.
*/
implicit def convertToJavaMapShouldWrapper[K, V](o: java.util.Map[K, V]): JavaMapShouldWrapper[K, V] = new JavaMapShouldWrapper[K, V](o)
// Implicitly just used to trigger the addition of the should method. The LengthShouldWrapper
// doesn't actually convert them, just passes it through. The conversion that happens here is to LengthShouldWrapper,
// and later, inside ResultOfHaveWordForLengthWrapper, the implicit conversion from T to LengthWrapper takes place. So
// weirdly enough, here strings are treated structurally for the implicit that adds the should, but later they are
// treated nominally by the implicit conversion from plain old String to StringLengthWrapper. So when length is
// ultimately invoked up in ResultOfHaveWordForLengthWrapper, it is done directly, not with reflection. That's my
// theory anyway.
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getLength
method that results in Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntGetLengthMethodToLengthShouldWrapper[T <: AnyRef { def getLength(): Int}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getLength
parameterless method that results in Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntGetLengthParameterlessMethodToLengthShouldWrapper[T <: AnyRef { def getLength: Int}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getLength
val
of type Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntGetLengthFieldToLengthShouldWrapper[T <: AnyRef { val getLength: Int}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a length
val
of type Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntLengthFieldToLengthShouldWrapper[T <: AnyRef { val length: Int}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a length
method that results in Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntLengthMethodToLengthShouldWrapper[T <: AnyRef { def length(): Int}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a length
parameterless method that results in Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntParameterlessLengthMethodToLengthShouldWrapper[T <: AnyRef { def length: Int}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getLength
method that results in Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongGetLengthMethodToLengthShouldWrapper[T <: AnyRef { def getLength(): Long}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getLength
parameterless method that results in Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongGetLengthParameterlessMethodToLengthShouldWrapper[T <: AnyRef { def getLength: Long}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getLength
val
of type Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongGetLengthFieldToLengthShouldWrapper[T <: AnyRef { val getLength: Long}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a length
val
of type Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongLengthFieldToLengthShouldWrapper[T <: AnyRef { val length: Long}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a length
method that results in Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongLengthMethodToLengthShouldWrapper[T <: AnyRef { def length(): Long}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a length
parameterless method that results in Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongLengthParameterlessMethodToLengthShouldWrapper[T <: AnyRef { def length: Long}](o: T): LengthShouldWrapper[T] = new LengthShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getSize
method that results in Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntGetSizeMethodToSizeShouldWrapper[T <: AnyRef { def getSize(): Int}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getSize
parameterless method that results in Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntGetSizeParameterlessMethodToSizeShouldWrapper[T <: AnyRef { def getSize: Int}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getSize
val
of type Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntGetSizeFieldToSizeShouldWrapper[T <: AnyRef { val getSize: Int}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a size
val
of type Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntSizeFieldToSizeShouldWrapper[T <: AnyRef { val size: Int}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a size
method that results in Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntSizeMethodToSizeShouldWrapper[T <: AnyRef { def size(): Int}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a size
parameterless method that results in Int
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasIntSizeParameterlessMethodToSizeShouldWrapper[T <: AnyRef { def size: Int}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getSize
method that results in Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongGetSizeMethodToSizeShouldWrapper[T <: AnyRef { def getSize(): Long}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getSize
parameterless method that results in Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongGetSizeParameterlessMethodToSizeShouldWrapper[T <: AnyRef { def getSize: Long}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a getSize
val
of type Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongGetSizeFieldToSizeShouldWrapper[T <: AnyRef { val getSize: Long}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a size
val
type Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongSizeFieldToSizeShouldWrapper[T <: AnyRef { val size: Long}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a size
method that results in Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongSizeMethodToSizeShouldWrapper[T <: AnyRef { def size(): Long}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
/**
* Implicitly converts an AnyRef
of type T
whose structure includes
* a size
parameterless method that results in Long
* to a SizeShouldWrapper[T]
, to enable should
methods to be invokable on that object.
*/
implicit def convertHasLongSizeParameterlessMethodToSizeShouldWrapper[T <: AnyRef { def size: Long}](o: T): SizeShouldWrapper[T] = new SizeShouldWrapper[T](o)
}
/*
When Scala must chose between an implicit with a structural type and one with a nominal one,
the nominal one wins.
scala> set.size
res0: Int = 3
scala> class SetWrapper(payload: Set[Int]) { def prove() { println("SetWrapper") }}
defined class SetWrapper
scala> class SizeWrapper(payload: { def size: Int }) { def prove() { println("SizeWrapper") }}
defined class SizeWrapper
scala> new SizeWrapper(set)
res1: SizeWrapper = SizeWrapper@39ce9b
scala> res1.prove
SizeWrapper
scala> new SetWrapper(set)
res3: SetWrapper = SetWrapper@9fc9fe
scala> res3.prove
SetWrapper
scala> implicit def convertToSetWrapper(setParam: Set[Int]): SetWrapper = new SetWrapper(setParam)
convertToSetWrapper: (Set[Int])SetWrapper
scala> implicit def convertToSizeWrapper(setParam: { def size: Int }): SizeWrapper = new SizeWrapper(setParam)
convertToSizeWrapper: (AnyRef{def size: Int})SizeWrapper
scala> convertToSetWrapper(set)
res5: SetWrapper = SetWrapper@598095
scala> convertToSizeWrapper(set)
res6: SizeWrapper = SizeWrapper@660ff1
scala> set.prove
SetWrapper
*/
/*
leave this explanation in. It is a useful reminder.
THIS DOESN'T WORK BECAUSE...
trait ShouldMethods[T] {
val leftOperand: T
def should(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 should(beWord: BeWord): ResultOfBeWord[T] = new ResultOfBeWord(leftOperand, true)
def should(notWord: NotWord) = new ResultOfNotWord[T](leftOperand, false)
}
trait ShouldMethodsForAnyRef[T <: AnyRef] extends ShouldMethods[T] {
val leftOperand: T
override def should(notWord: NotWord): ResultOfNotWordForAnyRef[T] = {
new ResultOfNotWordForAnyRef(leftOperand, false)
}
def should(beWord: BeWord): ResultOfBeWordForAnyRef[T] = new ResultOfBeWordForAnyRef[T](leftOperand, true)
}
class CollectionShouldWrapper[T](left: Collection[T]) extends { val leftOperand = left }
with ShouldMethodsForAnyRef[Collection[T]]
with ShouldContainWordForIterableMethods[T] with ShouldHaveWordForCollectionMethods[T] {
override def should(notWord: NotWord): ResultOfNotWordForCollection[Collection[T]] = {
new ResultOfNotWordForCollection(leftOperand, false)
}
}
When you mix in the latter, the result type of should(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 should be a ('empty)
Turns into:
BeSymbolSpec.this.convertToAnyRefShouldWrapper[BeSymbolSpec.this.CollectionShouldWrapper[T]]
(BeSymbolSpec.this.convertToCollectionShouldWrapper[T](emptySet)).should(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 ShouldMethods if this will work.
*/
/**
* Companion object that facilitates the importing of ShouldMatchers
members as
* an alternative to mixing it the trait. One use case is to import ShouldMatchers
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.ShouldMatchers._
* import org.scalatest.matchers.ShouldMatchers._
*
* scala> 1 should equal (2)
* org.scalatest.TestFailedException: 1 did not equal 2
* at org.scalatest.matchers.Helper$.newTestFailedException(Matchers.scala:40)
* at org.scalatest.matchers.ShouldMatchers$ShouldMethodHelper$.shouldMatcher(ShouldMatchers.scala:826)
* at org.scalatest.matchers.ShouldMatchers$IntShouldWrapper.should(ShouldMatchers.scala:1123)
* at .(:9)
* at .()
* at RequestR...
*
* scala> "hello, world" should startWith ("hello")
*
* scala> 7 should (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.scala:40)
* at org.scalatest.matchers.ShouldMatchers$ShouldMethodHelper$.shouldMatcher(ShouldMatchers.scala:826)
* at org.scalatest.matchers.ShouldMatchers$IntShouldWrapper.should(ShouldMatchers.scala:1123)
* at .(...
*
*
* @author Bill Venners
*/
object ShouldMatchers extends ShouldMatchers