trait Waiters extends PatienceConfiguration
Trait that facilitates performing assertions outside the main test thread, such as assertions in callback methods that are invoked asynchronously.
Trait Waiters provides a Waiter class that you can use to orchestrate the inter-thread
communication required to perform assertions outside the main test thread, and a means to configure it.
To use Waiter, create an instance of it in the main test thread:
val w = new Waiter // Do this in the main test thread
At some point later, call await on the waiter:
w.await() // Call await() from the main test thread
The await call will block until it either receives a report of a failed assertion from a different thread, at which
point it will complete abruptly with the same exception, or until it is dismissed by a different thread (or threads), at
which point it will return normally. You can optionally specify a timeout and/or a number
of dismissals to wait for. Here's an example:
import org.scalatest.time.SpanSugar._
w.await(timeout(300 millis), dismissals(2))
The default value for timeout, provided via an implicit PatienceConfig parameter, is 150 milliseconds. The default value for
dismissals is 1. The await method will block until either it is dismissed a sufficient number of times by other threads or
an assertion fails in another thread. Thus if you just want to perform assertions in just one other thread, only that thread will be
performing a dismissal, so you can use the default value of 1 for dismissals.
Waiter contains four overloaded forms of await, two of which take an implicit
PatienceConfig parameter. To change the default timeout configuration, override or hide
(if you imported the members of Waiters companion object instead of mixing in the
trait) patienceConfig with a new one that returns your desired configuration.
To dismiss a waiter, you just invoke dismiss on it:
w.dismiss() // Call this from one or more other threads
You may want to put dismiss invocations in a finally clause to ensure they happen even if an exception is thrown.
Otherwise if a dismissal is missed because of a thrown exception, an await call will wait until it times out.
Note that if a Waiter receives more than the expected number of dismissals, it will not report
this as an error: i.e., receiving greater than the number of expected dismissals without any failed assertion will simply
cause the the test to complete, not to fail. The only way a Waiter will cause a test to fail is if one of the
asynchronous assertions to which it is applied fails.
Finally, to perform an assertion in a different thread, you just apply the Waiter to the assertion code. Here are
some examples:
w { assert(1 + 1 === 3) } // Can use assertions
w { 1 + 1 should equal (3) } // Or matchers
w { "hi".charAt(-1) } // Any exceptions will be forwarded to await
Here's a complete example:
import org.scalatest._ import concurrent.Waiters import scala.actors.Actor
class ExampleSuite extends FunSuite with Matchers with Waiters {
case class Message(text: String)
class Publisher extends Actor {
@volatile private var handle: Message => Unit = { (msg) => }
def registerHandler(f: Message => Unit) { handle = f }
def act() { var done = false while (!done) { react { case msg: Message => handle(msg) case "Exit" => done = true } } } }
test("example one") {
val publisher = new Publisher val message = new Message("hi") val w = new Waiter
publisher.start()
publisher.registerHandler { msg => w { msg should equal (message) } w.dismiss() }
publisher ! message w.await() publisher ! "Exit" } }
- Source
- Waiters.scala
- Alphabetic
- By Inheritance
- Waiters
- PatienceConfiguration
- AbstractPatienceConfiguration
- ScaledTimeSpans
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Type Members
-
final
case class
PatienceConfig(timeout: Span = scaled(Span(150, Millis)), interval: Span = scaled(Span(15, Millis))) extends Product with Serializable
Configuration object for asynchronous constructs, such as those provided by traits
EventuallyandWaiters.Configuration object for asynchronous constructs, such as those provided by traits
EventuallyandWaiters.The default values for the parameters are:
Configuration Parameter Default Value timeoutscaled(150 milliseconds)intervalscaled(15 milliseconds)- timeout
the maximum amount of time to wait for an asynchronous operation to complete before giving up and throwing
TestFailedException.- interval
the amount of time to sleep between each check of the status of an asynchronous operation when polling
- Definition Classes
- AbstractPatienceConfiguration
-
final
case class
Dismissals(value: Int) extends Product with Serializable
A configuration parameter that specifies the number of dismissals to wait for before returning normally from an
awaitcall on aWaiter.A configuration parameter that specifies the number of dismissals to wait for before returning normally from an
awaitcall on aWaiter.- value
the number of dismissals for which to wait
- Exceptions thrown
IllegalArgumentExceptionif specifiedvalueis less than or equal to zero.
-
class
Waiter extends AnyRef
Class that facilitates performing assertions outside the main test thread, such as assertions in callback methods that are invoked asynchronously.
Class that facilitates performing assertions outside the main test thread, such as assertions in callback methods that are invoked asynchronously.
To use
Waiter, create an instance of it in the main test thread:val w = new Waiter // Do this in the main test thread
At some point later, call
awaiton the waiter:w.await() // Call await() from the main test threadThe
awaitcall will block until it either receives a report of a failed assertion from a different thread, at which point it will complete abruptly with the same exception, or until it is dismissed by a different thread (or threads), at which point it will return normally. You can optionally specify a timeout and/or a number of dismissals to wait for. Here's an example:import org.scalatest.time.SpanSugar._
w.await(timeout(300 millis), dismissals(2))The default value for
timeout, provided via an implicitPatienceConfigparameter, is 150 milliseconds. The default value fordismissalsis 1. Theawaitmethod will block until either it is dismissed a sufficient number of times by other threads or an assertion fails in another thread. Thus if you just want to perform assertions in just one other thread, only that thread will be performing a dismissal, so you can use the default value of 1 fordismissals.Waitercontains four overloaded forms ofawait, two of which take an implicitPatienceConfigparameter. To change the default timeout configuration, override or hide (if you imported the members ofWaiterscompanion object instead of mixing in the trait)patienceConfigwith a new one that returns your desired configuration.To dismiss a waiter, you just invoke
dismisson it:w.dismiss() // Call this from one or more other threadsYou may want to put
dismissinvocations in a finally clause to ensure they happen even if an exception is thrown. Otherwise if a dismissal is missed because of a thrown exception, anawaitcall will wait until it times out.Finally, to perform an assertion in a different thread, you just apply the
Waiterto the assertion code. Here are some examples:w { assert(1 + 1 === 3) } // Can use assertions w { 1 + 1 should equal (3) } // Or matchers w { "hi".charAt(-1) } // Any exceptions will be forwarded to awaitHere's a complete example:
import org.scalatest._ import concurrent.Waiters import scala.actors.Actor
class ExampleSuite extends FunSuite with Matchers with Waiters {
case class Message(text: String)
class Publisher extends Actor {
@volatile private var handle: Message => Unit = { (msg) => }
def registerHandler(f: Message => Unit) { handle = f }
def act() { var done = false while (!done) { react { case msg: Message => handle(msg) case "Exit" => done = true } } } }
test("example one") {
val publisher = new Publisher val message = new Message("hi") val w = new Waiter
publisher.start()
publisher.registerHandler { msg => w { msg should equal (message) } w.dismiss() }
publisher ! message w.await() publisher ! "Exit" } }
Value Members
-
final
def
!=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
##(): Int
- Definition Classes
- AnyRef → Any
-
final
def
==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
asInstanceOf[T0]: T0
- Definition Classes
- Any
-
def
clone(): AnyRef
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @native() @throws( ... )
-
def
dismissals(value: Int): Dismissals
Returns a
Dismissalsconfiguration parameter containing the passed value, which specifies the number of dismissals to wait for before returning normally from anawaitcall on aWaiter. -
final
def
eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
equals(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
finalize(): Unit
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( classOf[java.lang.Throwable] )
-
final
def
getClass(): Class[_]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
def
hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
def
interval(value: Span): Interval
Returns an
Intervalconfiguration parameter containing the passed value, which specifies the amount of time to sleep after a retry.Returns an
Intervalconfiguration parameter containing the passed value, which specifies the amount of time to sleep after a retry.- Definition Classes
- PatienceConfiguration
-
final
def
isInstanceOf[T0]: Boolean
- Definition Classes
- Any
-
final
def
ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
final
def
notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
final
def
notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
implicit
def
patienceConfig: PatienceConfig
Implicit
PatienceConfigvalue providing default configuration values.Implicit
PatienceConfigvalue providing default configuration values.To change the default configuration, override or hide this
defwith another implicitPatienceConfigcontaining your desired default configuration values.- Definition Classes
- PatienceConfiguration → AbstractPatienceConfiguration
-
final
def
scaled(span: Span): Span
Scales the passed
Spanby theDoublefactor returned byspanScaleFactor.Scales the passed
Spanby theDoublefactor returned byspanScaleFactor.The
Spanis scaled by invoking itsscaledBymethod, thus this method has the same behavior: The value returned byspanScaleFactorcan be any positive number or zero, including a fractional number. A number greater than one will scale theSpanup to a larger value. A fractional number will scale it down to a smaller value. A factor of 1.0 will cause the exact sameSpanto be returned. A factor of zero will causeSpan.ZeroLengthto be returned. If overflow occurs,Span.Maxwill be returned. If underflow occurs,Span.ZeroLengthwill be returned.- Definition Classes
- ScaledTimeSpans
- Exceptions thrown
IllegalArgumentExceptionif the value returned fromspanScaleFactoris less than zero
-
def
spanScaleFactor: Double
The factor by which the
scaledmethod will scaleSpans.The factor by which the
scaledmethod will scaleSpans.The default implementation of this method will return the span scale factor that was specified for the run, or 1.0 if no factor was specified. For example, you can specify a span scale factor when invoking ScalaTest via the command line by passing a
-Fargument toRunner.- Definition Classes
- ScaledTimeSpans
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
-
def
timeout(value: Span): Timeout
Returns a
Timeoutconfiguration parameter containing the passed value, which specifies the maximum amount to wait for an asynchronous operation to complete.Returns a
Timeoutconfiguration parameter containing the passed value, which specifies the maximum amount to wait for an asynchronous operation to complete.- Definition Classes
- PatienceConfiguration
-
def
toString(): String
- Definition Classes
- AnyRef → Any
-
final
def
wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @throws( ... )