org.scalatest.Assertions.scala Maven / Gradle / Ivy
Show all versions of scalatest_2.9.0 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 import exceptions.TestCanceledException import scala.reflect.Manifest import Assertions.areEqualComparingArraysStructurally import org.scalautils.LegacyTripleEquals /** * Trait that contains ScalaTest's basic assertion methods. * *
Equalizer. * * ** You can use the assertions provided by this trait in any ScalaTest
* *Suite
, becauseSuite
* mixes in this trait. This trait is designed to be used independently of anything else in ScalaTest, though, so you * can mix it into anything. (You can alternatively import the methods defined in this trait. For details, see the documentation * for theAssertions
companion object. ** In any Scala program, you can write assertions by invoking
* *assert
and passing in aBoolean
expression, * such as: ** val left = 2 * val right = 1 * assert(left == right) ** ** If the passed expression is
true
,assert
will return normally. Iffalse
, * Scala'sassert
will complete abruptly with anAssertionError
. This behavior is provided by * theassert
method defined in objectPredef
, whose members are implicitly imported into every * Scala source file. ThisAssertions
traits defines anotherassert
method that hides the * one inPredef
. It behaves the same, except that iffalse
is passed it throws *TestFailedException
instead ofAssertionError
. The reason it throwsTestFailedException
* is becauseTestFailedException
carries information about exactly which item in the stack trace represents * the line of test code that failed, which can help users more quickly find an offending line of code in a failing test. ** *
* If you pass the previous
* *Boolean
expression,left == right
toassert
in a ScalaTest test, a failure * will be reported, but without reporting the left and right values. You can alternatively encode these values in aString
passed as * a second argument toassert
, like this: ** val left = 2 * val right = 1 * assert(left == right, left + " did not equal " + right) ** ** Using this form of
* *assert
, the failure report will include the left and right values, thereby * helping you debug the problem. However, ScalaTest provides the===
operator to make this easier. * You use it like this: ** val left = 2 * val right = 1 * assert(left === right) ** ** Because you use
* *===
here instead of==
, the failure report will include the left * and right values. For example, the detail message in the thrownTestFailedException
from theassert
* shown previously will include, "2 did not equal 1". * From this message you will know that the operand on the left had the value 2, and the operand on the right had the value 1. ** If you're familiar with JUnit, you would use
* *===
* in a ScalaTestSuite
where you'd useassertEquals
in a JUnitTestCase
. * The===
operator is made possible by an implicit conversion fromAny
* toEqualizer
. If you're curious to understand the mechanics, see the documentation for *Equalizer
and theconvertToEqualizer
method. *Expected results
* * Although===
provides a natural, readable extension to Scala'sassert
mechanism, * as the operands become lengthy, the code becomes less readable. In addition, the===
comparison * doesn't distinguish between actual and expected values. The operands are just calledleft
andright
, * because if one were namedexpected
and the otheractual
, it would be difficult for people to * remember which was which. To help with these limitations of assertions,Suite
includes a method calledexpectResult
that * can be used as an alternative toassert
with===
. To useexpectResult
, you place * the expected value in parentheses afterexpectResult
, followed by curly braces containing code * that should result in the expected value. For example: * ** val a = 5 * val b = 2 * expectResult(2) { * a - b * } ** ** In this case, the expected value is
* *2
, and the code being tested isa - b
. This expectation will fail, and * the detail message in theTestFailedException
will read, "Expected 2, but got 3." *Forcing failures
* ** If you just need the test to fail, you can write: *
* ** fail() ** ** Or, if you want the test to fail with a message, write: *
* ** fail("I've got a bad feeling about this") ** *Intercepted 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. You can do this in the JUnit 3 style, like this: *
* ** val s = "hi" * try { * s.charAt(-1) * fail() * } * catch { * case _: IndexOutOfBoundsException => // Expected, so continue * } ** ** If
* *charAt
throwsIndexOutOfBoundsException
as expected, control will transfer * to the catch case, which does nothing. If, however,charAt
fails to throw an exception, * the next statement,fail()
, will be run. Thefail
method always completes abruptly with * aTestFailedException
, thereby signaling a failed test. ** To make this common use case easier to express and read, ScalaTest provides an
* *intercept
* method. You use it like this: ** val s = "hi" * intercept[IndexOutOfBoundsException] { * s.charAt(-1) * } ** ** This code behaves much like the previous example. If
* *charAt
throws an instance ofIndexOutOfBoundsException
, *intercept
will return that exception. But ifcharAt
completes normally, or throws a different * exception,intercept
will complete abruptly with aTestFailedException
.intercept
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. *Assumptions
* ** Trait
* *Assertions
also provides methods that allow you to cancel a test. * You would cancel a test if a resource required by the test was unavailable. For example, if a test * requires an external database to be online, and it isn't, the test could be canceled to indicate * it was unable to run because of the missing database. Such a test assumes a database is * available, and you can use theassume
method to indicate this at the beginning of * the test, like this: ** assume(database.isAvailable) ** ** For each overloaded
* *assert
method, traitAssertions
provides an * overloadedassume
method with an identical signature and behavior, except the *assume
methods throwTestCanceledException
whereas the *assert
methods throwTestFailedException
. As withassert
, *assume
hides a Scala method inPredef
that performs a similar * function, but throwsAssertionError
. And just as you can withassert
, * you can optionally provide a clue string, or use===
to get a more detailed * error message. Here are some examples: ** assume(database.isAvailable, "The database was down again") * assume(database.getAllUsers.count === 9) ** *Forcing cancelations
* ** For each overloaded
* *fail
method, there's a correspondingcancel
method * with an identical signature and behavior, except thecancel
methods throw *TestCanceledException
whereas thefail
methods throw *TestFailedException
. Thus if you just need to cancel a test, you can write: ** cancel() ** ** If you want to cancel the test with a message, just place the message in the parentheses: *
* ** cancel("Can't run the test because no internet connection was found") ** *Getting a clue
* ** If you want more information that is provided by default by the methods if this trait, * you can supply a "clue" string in one of several ways. * The extra information (or "clues") you provide will * be included in the detail message of the thrown exception. Both *
* *assert
andexpect
provide a way for a clue to be * included directly,intercept
does not. * Here's an example of clues provided directly inassert
: ** assert(1 + 1 === 3, "this is a clue") ** ** and in
* *expect
: ** expect(3, "this is a clue") { 1 + 1 } ** ** The exceptions thrown by the previous two statements will include the clue * string,
* *"this is a clue"
, in the exception's detail message. * To get the same clue in the detail message of an exception thrown * by a failedintercept
call requires usingwithClue
: ** withClue("this is a clue") { * intercept[IndexOutOfBoundsException] { * "hi".charAt(-1) * } * } ** ** The
* * @author Bill Venners */ trait Assertions extends LegacyTripleEquals { /* * * Class used via an implicit conversion to enable any two objects to be compared with *withClue
method will only prepend the clue string to the detail * message of exception types that mix in theModifiableMessage
trait. * See the documentation forModifiableMessage
for more information. * If you wish to place a clue string after a block of code, see the documentation for *AppendedClues
. *===
in assertions in tests. For example: * ** assert(a === b) ** ** The benefit of using
* *assert(a === b)
rather thanassert(a == b)
is * that aTestFailedException
produced by the former will include the values ofa
andb
* in its detail message. * The implicit method that performs the conversion fromAny
toEqualizer
is *convertToEqualizer
in traitAssertions
. ** In case you're not familiar with how implicit conversions work in Scala, here's a quick explanation. * The
* *convertToEqualizer
method inAssertions
is defined as an "implicit" method that takes an *Any
, which means you can pass in any object, and it will convert it to anEqualizer
. * TheEqualizer
has===
defined. Most objects don't have===
defined as a method * on them. Take two Strings, for example: ** assert("hello" === "world") ** ** Given this code, the Scala compiler looks for an
* *===
method on classString
, because that's the class of *"hello"
.String
doesn't define===
, so the compiler looks for an implicit conversion from *String
to something that does have an===
method, and it finds theconvertToEqualizer
method. It * then rewrites the code to this: ** assert(convertToEqualizer("hello").===("world")) ** ** So inside a
* *Suite
(which mixes inAssertions
,===
will work on anything. The only * situation in which the implicit conversion wouldn't * happen is on types that have an===
method already defined. ** The primary constructor takes one object,
* * @param left An object to convert toleft
, whose type is being converted toEqualizer
. Theleft
* value may be anull
reference, because this is allowed by Scala's==
operator. *Equalizer
, which represents theleft
value * of an assertion. * * @author Bill Venners */ /* final class Equalizer(left: Any) { /** * The===
operation compares thisEqualizer
'sleft
value (passed * to the constructor, usually via an implicit conversion) with the passedright
value * for equality as determined by the expressionleft == right
. * Iftrue
,===
returnsNone
. Else,===
returns * aSome
whoseString
value indicates theleft
andright
values. * ** In its typical usage, the
*/ def ===(right: Any) = if (areEqualComparingArraysStructurally(left, right)) None else { val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) Some(FailureMessages("didNotEqual", leftee, rightee)) } /* def !==(right: Any) = if (left != right) None else { val (leftee, rightee) = Suite.getObjectsForFailureMessage(left, right) Some(FailureMessages("equaled", leftee, rightee)) } */ } */ /** * Assert that a boolean condition is true. * If the condition isOption[String]
returned by===
will be passed to one of two * of traitAssertion
' overloadedassert
methods. IfNone
, * which indicates the assertion succeeded,assert
will return normally. But ifSome
is passed, * which indicates the assertion failed,assert
will throw aTestFailedException
whose detail * message will include theString
contained inside theSome
, which in turn includes the *left
andright
values. ThisTestFailedException
is typically embedded in a *Report
and passed to aReporter
, which can present theleft
andright
* values to the user. *true
, this method returns normally. * Else, it throwsTestFailedException
. * * @param condition the boolean condition to assert * @throws TestFailedException if the condition isfalse
. */ def assert(condition: Boolean) { if (!condition) throw newAssertionFailedException(None, None, 4) } private[scalatest] def newAssertionFailedException(optionalMessage: Option[Any], optionalCause: Option[Throwable], stackDepth: Int): Throwable = (optionalMessage, optionalCause) match { case (None, None) => new TestFailedException(stackDepth) case (None, Some(cause)) => new TestFailedException(cause, stackDepth) case (Some(message), None) => new TestFailedException(message.toString, stackDepth) case (Some(message), Some(cause)) => new TestFailedException(message.toString, cause, stackDepth) } private def newTestCanceledException(optionalMessage: Option[Any], optionalCause: Option[Throwable], stackDepth: Int): Throwable = (optionalMessage, optionalCause) match { case (None, None) => new TestCanceledException(stackDepth) case (None, Some(cause)) => new TestCanceledException(cause, stackDepth) case (Some(message), None) => new TestCanceledException(message.toString, stackDepth) case (Some(message), Some(cause)) => new TestCanceledException(message.toString, cause, stackDepth) } /** * Assert that a boolean condition, described inString
*message
, is true. * If the condition istrue
, this method returns normally. * Else, it throwsTestFailedException
with the *String
obtained by invokingtoString
on the * specifiedclue
as the exception's detail message. * * @param condition the boolean condition to assert * @param clue An objects whosetoString
method returns a message to include in a failure report. * @throws TestFailedException if the condition isfalse
. * @throws NullPointerException ifmessage
isnull
. */ def assert(condition: Boolean, clue: Any) { if (!condition) throw newAssertionFailedException(Some(clue), None, 4) } /** * Assert that anOption[String]
isNone
. * If the condition isNone
, this method returns normally. * Else, it throwsTestFailedException
with theString
* value of theSome
, as well as the *String
obtained by invokingtoString
on the * specifiedclue
, * included in theTestFailedException
's detail message. * ** This form of
* *assert
is usually called in conjunction with an * implicit conversion toEqualizer
, using a===
comparison, as in: ** assert(a === b, "extra info reported if assertion fails") ** ** For more information on how this mechanism works, see the documentation for *
* * @param o theEqualizer
. *Option[String]
to assert * @param clue An objects whosetoString
method returns a message to include in a failure report. * @throws TestFailedException if theOption[String]
isSome
. * @throws NullPointerException ifmessage
isnull
. */ def assert(o: Option[String], clue: Any) { o match { case Some(s) => throw newAssertionFailedException(Some(clue + "\n" + s), None, 4) case None => } } /** * Assert that anOption[String]
isNone
. * If the condition isNone
, this method returns normally. * Else, it throwsTestFailedException
with theString
* value of theSome
included in theTestFailedException
's * detail message. * ** This form of
* *assert
is usually called in conjunction with an * implicit conversion toEqualizer
, using a===
comparison, as in: ** assert(a === b) ** ** For more information on how this mechanism works, see the documentation for *
* * @param o theEqualizer
. *Option[String]
to assert * @throws TestFailedException if theOption[String]
isSome
. */ def assert(o: Option[String]) { o match { case Some(s) => throw newAssertionFailedException(Some(s), None, 4) case None => } } /** * Assume that a boolean condition is true. * If the condition istrue
, this method returns normally. * Else, it throwsTestCanceledException
. * * @param condition the boolean condition to assert * @throws TestCanceledException if the condition isfalse
. */ def assume(condition: Boolean) { if (!condition) throw newTestCanceledException(None, None, 3) } /** * Assume that a boolean condition, described inString
*message
, is true. * If the condition istrue
, this method returns normally. * Else, it throwsTestCanceledException
with the *String
obtained by invokingtoString
on the * specifiedclue
as the exception's detail message. * * @param condition the boolean condition to assume * @param clue An objects whosetoString
method returns a message to include in a failure report. * @throws TestFailedException if the condition isfalse
. * @throws NullPointerException ifmessage
isnull
. */ def assume(condition: Boolean, clue: Any) { if (!condition) throw newTestCanceledException(Some(clue.toString), None, 3) } /** * Assume that anOption[String]
isNone
. * If the condition isNone
, this method returns normally. * Else, it throwsTestCanceledException
with theString
* value of theSome
, as well as the *String
obtained by invokingtoString
on the * specifiedclue
, * included in theTestCanceledException
's detail message. * ** This form of
* *assume
is usually called in conjunction with an * implicit conversion toEqualizer
, using a===
comparison, as in: ** assume(a === b, "extra info reported if assertion fails") ** ** For more information on how this mechanism works, see the documentation for *
* * @param o theEqualizer
. *Option[String]
to assert * @param clue An objects whosetoString
method returns a message to include in a failure report. * @throws TestCanceledException if theOption[String]
isSome
. * @throws NullPointerException ifmessage
isnull
. */ def assume(o: Option[String], clue: Any) { o match { case Some(s) => throw newTestCanceledException(Some(clue + "\n" + s), None, 3) case None => } } /** * Assume that anOption[String]
isNone
. * If the condition isNone
, this method returns normally. * Else, it throwsTestCanceledException
with theString
* value of theSome
included in theTestCanceledException
's * detail message. * ** This form of
* *assume
is usually called in conjunction with an * implicit conversion toEqualizer
, using a===
comparison, as in: ** assert(a === b) ** ** For more information on how this mechanism works, see the documentation for *
* * @param o theEqualizer
. *Option[String]
to assert * @throws TestFailedException if theOption[String]
isSome
. */ // def assume(o: Option[String]) = throwIfSome(o, (a: Any) => newTestCanceledException(Some(a.toString), None, 3)) def assume(o: Option[String]) { o match { case Some(s) => throw newTestCanceledException(Some(s), None, 3) case None => } } /* def throwIfSome(o: Option[String], exception: (Any) => Throwable) { o match { case Some(s) => throw exception(s) case None => } } */ /* * * Implicit conversion fromAny
toEqualizer
, used to enable * assertions with===
comparisons. * ** For more information * on this mechanism, see the documentation for
* Because trait
* *Suite
mixes inAssertions
, this implicit conversion will always be * available by default in ScalaTestSuite
s. This is the only implicit conversion that is in scope by default in every * ScalaTestSuite
. Other implicit conversions offered by ScalaTest, such as those that support the matchers DSL * orinvokePrivate
, must be explicitly invited into your test code, either by mixing in a trait or importing the * members of its companion object. The reason ScalaTest requires you to invite in implicit conversions (with the exception of the * implicit conversion for===
operator) is because if one of ScalaTest's implicit conversions clashes with an * implicit conversion used in the code you are trying to test, your program won't compile. Thus there is a chance that if you * are ever trying to use a library or test some code that also offers an implicit conversion involving a===
operator, * you could run into the problem of a compiler error due to an ambiguous implicit conversion. If that happens, you can turn off * the implicit conversion offered by thisconvertToEqualizer
method simply by overriding the method in your *Suite
subclass, but not marking it as implicit: ** // In your Suite subclass * override def convertToEqualizer(left: Any) = new Equalizer(left) ** * @param left the object whose type to convert toEqualizer
. * @throws NullPointerException ifleft
isnull
. */ // implicit def convertToEqualizer(left: Any) = new Equalizer(left) /* * Intercept and return an instance of the passed exception class (or an instance of a subclass of the * passed class), which is expected to be thrown by the passed function value. This method invokes the passed * function. If it throws an exception that's an instance of the passed class or one of its * subclasses, this method returns that exception. Else, whether the passed function returns normally * or completes abruptly with a different exception, this method throwsTestFailedException
* whose detail message includes theString
obtained by invokingtoString
on the passedclue
. * ** Note that the passed
* * @param message An object whoseClass
may represent any type, not justThrowable
or one of its subclasses. In * Scala, exceptions can be caught based on traits they implement, so it may at times make sense to pass in a class instance for * a trait. If a class instance is passed for a type that could not possibly be used to catch an exception (such asString
, * for example), this method will complete abruptly with aTestFailedException
. *toString
method returns a message to include in a failure report. * @param f the function value that should throw the expected exception * @return the intercepted exception, if it is of the expected type * @throws TestFailedException if the passed function does not result in a value equal to the * passedexpected
value. def intercept[T <: AnyRef](message: Any)(f: => Any)(implicit manifest: Manifest[T]): T = { val clazz = manifest.erasure.asInstanceOf[Class[T]] val messagePrefix = if (message.toString.trim.isEmpty) "" else (message +"\n") val caught = try { f None } catch { case u: Throwable => { if (!clazz.isAssignableFrom(u.getClass)) { val s = Resources("wrongException", clazz.getName, u.getClass.getName) throw newAssertionFailedException(Some(messagePrefix + s), Some(u), 4) } else { Some(u) } } } caught match { case None => val message = messagePrefix + Resources("exceptionExpected", clazz.getName) throw newAssertionFailedException(Some(message), None, 4) case Some(e) => e.asInstanceOf[T] // I know this cast will succeed, becuase iSAssignableFrom succeeded above } } THIS DOESN'T OVERLOAD. I THINK I'LL EITHER NEED TO USE interceptWithMessage OR JUST LEAVE IT OUT. FOR NOW I'LL LEAVE IT OUT. */ /** * Intercept and return an exception that's expected to * be thrown by the passed function value. The thrown exception must be an instance of the * type specified by the type parameter of this method. This method invokes the passed * function. If the function throws an exception that's an instance of the specified type, * this method returns that exception. Else, whether the passed function returns normally * or completes abruptly with a different exception, this method throwsTestFailedException
. * ** Note that the type specified as this method's type parameter may represent any subtype of *
* * @param f the function value that should throw the expected exception * @param manifest an implicitAnyRef
, not justThrowable
or one of its subclasses. In * Scala, exceptions can be caught based on traits they implement, so it may at times make sense * to specify a trait that the intercepted exception's class must mix in. If a class instance is * passed for a type that could not possibly be used to catch an exception (such asString
, * for example), this method will complete abruptly with aTestFailedException
. *Manifest
representing the type of the specified * type parameter. * @return the intercepted exception, if it is of the expected type * @throws TestFailedException if the passed function does not complete abruptly with an exception * that's an instance of the specified type * passedexpected
value. */ def intercept[T <: AnyRef](f: => Any)(implicit manifest: Manifest[T]): T = { val clazz = manifest.erasure.asInstanceOf[Class[T]] val caught = try { f None } catch { case u: Throwable => { if (!clazz.isAssignableFrom(u.getClass)) { val s = Resources("wrongException", clazz.getName, u.getClass.getName) throw newAssertionFailedException(Some(s), Some(u), 4) } else { Some(u) } } } caught match { case None => val message = Resources("exceptionExpected", clazz.getName) throw newAssertionFailedException(Some(message), None, 4) case Some(e) => e.asInstanceOf[T] // I know this cast will succeed, becuase iSAssignableFrom succeeded above } } /* * Intercept and return an instance of the passed exception class (or an instance of a subclass of the * passed class), which is expected to be thrown by the passed function value. This method invokes the passed * function. If it throws an exception that's an instance of the passed class or one of its * subclasses, this method returns that exception. Else, whether the passed function returns normally * or completes abruptly with a different exception, this method throwsTestFailedException
. * ** Note that the passed
* * @param clazz a type to which the expected exception class is assignable, i.e., the exception should be an instance of the type represented byClass
may represent any type, not justThrowable
or one of its subclasses. In * Scala, exceptions can be caught based on traits they implement, so it may at times make sense to pass in a class instance for * a trait. If a class instance is passed for a type that could not possibly be used to catch an exception (such asString
, * for example), this method will complete abruptly with aTestFailedException
. *clazz
. * @param f the function value that should throw the expected exception * @return the intercepted exception, if * @throws TestFailedException if the passed function does not complete abruptly with an exception that is assignable to the * passedClass
. * @throws IllegalArgumentException if the passedclazz
is notThrowable
or * one of its subclasses. */ /* def intercept[T <: AnyRef](clazz: java.lang.Class[T])(f: => Unit): T = { // intercept(clazz)(f)(manifest) "hi".asInstanceOf[T] } */ /* def intercept[T <: AnyRef](clazz: java.lang.Class[T])(f: => Unit)(implicit manifest: Manifest[T]): T = { intercept(clazz)(f)(manifest) } */ /** * Expect that the value passed asexpected
equals the value passed asactual
. * If theactual
equals theexpected
* (as determined by==
),expectResult
returns * normally. Else, ifactual
is not equal toexpected
,expectResult
throws a *TestFailedException
whose detail message includes the expected and actual values, as well as theString
* obtained by invokingtoString
on the passedclue
. * * @param expected the expected value * @param clue An object whosetoString
method returns a message to include in a failure report. * @param actual the actual value, which should equal the passedexpected
value * @throws TestFailedException if the passedactual
value does not equal the passedexpected
value. */ def expectResult(expected: Any, clue: Any)(actual: Any) { if (actual != expected) { val (act, exp) = Suite.getObjectsForFailureMessage(actual, expected) val s = FailureMessages("expectedButGot", exp, act) throw newAssertionFailedException(Some(clue + "\n" + s), None, 4) } } /** * Thisexpect
method has been deprecated; Please useexpectResult
instead. * ** To get rid of the deprecation warning, simply replace
*/ @deprecated("This expect method has been deprecated. Please replace all invocations of expect with an identical invocation of expectResult instead.") def expect(expected: Any, clue: Any)(actual: Any) { if (actual != expected) { val (act, exp) = Suite.getObjectsForFailureMessage(actual, expected) val s = FailureMessages("expectedButGot", exp, act) throw newAssertionFailedException(Some(clue + "\n" + s), None, 4) } } /** * Expect that the value passed asexpect
with *expectResult
. The nameexpect
will be used for a different purposes in * a future version of ScalaTest. *expected
equals the value passed asactual
. * If theactual
value equals theexpected
value * (as determined by==
),expectResult
returns * normally. Else,expect
throws a *TestFailedException
whose detail message includes the expected and actual values. * * @param expected the expected value * @param actual the actual value, which should equal the passedexpected
value * @throws TestFailedException if the passedactual
value does not equal the passedexpected
value. */ def expectResult(expected: Any)(actual: Any) { if (actual != expected) { val (act, exp) = Suite.getObjectsForFailureMessage(actual, expected) val s = FailureMessages("expectedButGot", exp, act) throw newAssertionFailedException(Some(s), None, 4) } } /** * Thisexpect
method has been deprecated; Please useexpectResult
instead. * ** To get rid of the deprecation warning, simply replace
*/ @deprecated("This expect method has been deprecated. Please replace all invocations of expect with an identical invocation of expectResult instead.") def expect(expected: Any)(actual: Any) { if (actual != expected) { val (act, exp) = Suite.getObjectsForFailureMessage(actual, expected) val s = FailureMessages("expectedButGot", exp, act) throw newAssertionFailedException(Some(s), None, 4) } } /* * TODO: Delete this if sticking with Nothing instead of Unit as result type of fail. *expect
with *expectResult
. The nameexpect
will be used for a different purposes in * a future version of ScalaTest. ** The result type of this and the other overloaded
* *fail
methods is *Unit
instead ofNothing
, becauseNothing
* is a subtype of all other types. If the result type offail
were *Nothing
, a block of code that ends in a call tofail()
may * fail to compile if the block being passed as a by-name parameter or function to an * overloaded method. The reason is that the compiler selects which overloaded * method to call based on the static types of the parameters passed. Since *Nothing
is an instance of everything, it can often make the overloaded * method selection ambiguous. ** For a concrete example, the
* *Conductor
class * in packageorg.scalatest.concurrent
has two overloaded variants of the *thread
method: ** def thread[T](fun: => T): Thread * * def thread[T](name: String)(fun: => T): Thread ** ** Given these two overloaded methods, the following code will compile given the result type * of
* *fail
isUnit
, but would not compile if the result type were *Nothing
: ** thread { fail() } ** ** If the result type of
*/ /** * Throwsfail
wereNothing
, the type of the by-name parameter * would be inferred to beNothing
, which is a subtype of bothT
and *String
. Thus the call is ambiguous, because the type matches the first parameter type * of both overloadedthread
methods.Unit
, by constrast, is not * a subtype ofString
, so it only matches one overloaded variant and compiles just fine. *TestFailedException
to indicate a test failed. */ def fail() = { throw newAssertionFailedException(None, None, 4) } /** * ThrowsTestFailedException
, with the passed *String
message
as the exception's detail * message, to indicate a test failed. * * @param message A message describing the failure. * @throws NullPointerException ifmessage
isnull
*/ def fail(message: String) = { if (message == null) throw new NullPointerException("message is null") throw newAssertionFailedException(Some(message), None, 4) } /** * ThrowsTestFailedException
, with the passed *String
message
as the exception's detail * message andThrowable
cause, to indicate a test failed. * * @param message A message describing the failure. * @param cause AThrowable
that indicates the cause of the failure. * @throws NullPointerException ifmessage
orcause
isnull
*/ def fail(message: String, cause: Throwable) = { if (message == null) throw new NullPointerException("message is null") if (cause == null) throw new NullPointerException("cause is null") throw newAssertionFailedException(Some(message), Some(cause), 4) } /** * ThrowsTestFailedException
, with the passed *Throwable
cause, to indicate a test failed. * ThegetMessage
method of the thrownTestFailedException
* will returncause.toString
. * * @param cause aThrowable
that indicates the cause of the failure. * @throws NullPointerException ifcause
isnull
*/ def fail(cause: Throwable) = { if (cause == null) throw new NullPointerException("cause is null") throw newAssertionFailedException(None, Some(cause), 4) } /** * ThrowsTestCanceledException
to indicate a test was canceled. */ def cancel() = { throw newTestCanceledException(None, None, 3) } /** * ThrowsTestCanceledException
, with the passed *String
message
as the exception's detail * message, to indicate a test was canceled. * * @param message A message describing the cancellation. * @throws NullPointerException ifmessage
isnull
*/ def cancel(message: String) = { if (message == null) throw new NullPointerException("message is null") throw newTestCanceledException(Some(message), None, 3) } /** * ThrowsTestCanceledException
, with the passed *String
message
as the exception's detail * message andThrowable
cause, to indicate a test failed. * * @param message A message describing the failure. * @param cause AThrowable
that indicates the cause of the failure. * @throws NullPointerException ifmessage
orcause
isnull
*/ def cancel(message: String, cause: Throwable) = { if (message == null) throw new NullPointerException("message is null") if (cause == null) throw new NullPointerException("cause is null") throw newTestCanceledException(Some(message), Some(cause), 3) } /** * ThrowsTestCanceledException
, with the passed *Throwable
cause, to indicate a test failed. * ThegetMessage
method of the thrownTestCanceledException
* will returncause.toString
. * * @param cause aThrowable
that indicates the cause of the cancellation. * @throws NullPointerException ifcause
isnull
*/ def cancel(cause: Throwable) = { if (cause == null) throw new NullPointerException("cause is null") throw newTestCanceledException(None, Some(cause), 3) } /** * Executes the block of code passed as the second parameter, and, if it * completes abruptly with aModifiableMessage
exception, * prepends the "clue" string passed as the first parameter to the beginning of the detail message * of that thrown exception, then rethrows it. If clue does not end in a white space * character, one space will be added * between it and the existing detail message (unless the detail message is * not defined). * ** This method allows you to add more information about what went wrong that will be * reported when a test fails. Here's an example: *
* ** withClue("(Employee's name was: " + employee.name + ")") { * intercept[IllegalArgumentException] { * employee.getTask(-1) * } * } ** ** If an invocation of
* *intercept
completed abruptly with an exception, the resulting message would be something like: ** (Employee's name was Bob Jones) Expected IllegalArgumentException to be thrown, but no exception was thrown ** * @throws NullPointerException if the passedclue
isnull
*/ def withClue[T](clue: Any)(fun: => T): T = { if (clue == null) throw new NullPointerException("clue was null") def prepend(currentMessage: Option[String]) = currentMessage match { case Some(msg) => if (clue.toString.last.isWhitespace) // TODO: shouldn't I also check if the head of msg isWhite? Some(clue.toString + msg) else Some(clue.toString + " " + msg) case None => Some(clue.toString) } try { fun } catch { case e: org.scalatest.exceptions.ModifiableMessage[_] => if (clue != "") throw e.modifyMessage(prepend) else throw e } } /* Hold off on this for now. See how people do with the simple one that takes an Any. def withClueFunction(sfun: Option[String] => Option[String])(fun: => Unit) { fun } */ } /** * Companion object that facilitates the importing ofAssertions
members as * an alternative to mixing it in. One use case is to importAssertions
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.Assertions._ * import org.scalatest.Assertions._ * * scala> assert(1 === 2) * org.scalatest.TestFailedException: 1 did not equal 2 * at org.scalatest.Assertions$class.assert(Assertions.scala:211) * at org.scalatest.Assertions$.assert(Assertions.scala:511) * at .* * @author Bill Venners */ object Assertions extends Assertions { private[scalatest] def areEqualComparingArraysStructurally(left: Any, right: Any) = { left match { case leftArray: Array[_] => right match { case rightArray: Array[_] => leftArray.deep.equals(rightArray.deep) case _ => left == right } case _ => left == right } } }( :7) * at . ( ) * at RequestResult$. ( :3) * at RequestResult$. ( ) * at RequestResult$result( ) * at sun.reflect.NativeMethodAccessorImpl.invoke... * * scala> expect(3) { 1 + 3 } * org.scalatest.TestFailedException: Expected 3, but got 4 * at org.scalatest.Assertions$class.expect(Assertions.scala:447) * at org.scalatest.Assertions$.expect(Assertions.scala:511) * at . ( :7) * at . ( ) * at RequestResult$. ( :3) * at RequestResult$. ( ) * at RequestResult$result( ) * at sun.reflect.NativeMethodAccessorImpl.in... * * scala> val caught = intercept[StringIndexOutOfBoundsException] { "hi".charAt(-1) } * caught: StringIndexOutOfBoundsException = java.lang.StringIndexOutOfBoundsException: String index out of range: -1 *