Packages

  • package root
    Definition Classes
    root
  • package org
    Definition Classes
    root
  • package scalatest

    ScalaTest's main traits, classes, and other members, including members supporting ScalaTest's DSL for the Scala interpreter.

    ScalaTest's main traits, classes, and other members, including members supporting ScalaTest's DSL for the Scala interpreter.

    Definition Classes
    org
  • package concurrent

    Classes, traits, and objects related to testing asynchronous and multi-threaded behavior.

    Classes, traits, and objects related to testing asynchronous and multi-threaded behavior.

    This package is released as part of the scalatest-core module.

    Definition Classes
    scalatest
  • 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 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" } }

    Definition Classes
    concurrent
  • Dismissals
  • PatienceConfig
  • Waiter

class Waiter extends AnyRef

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 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.

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
Linear Supertypes
AnyRef, Any
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. Waiter
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Instance Constructors

  1. new Waiter()

Value Members

  1. final def !=(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  2. final def ##(): Int
    Definition Classes
    AnyRef → Any
  3. final def ==(arg0: Any): Boolean
    Definition Classes
    AnyRef → Any
  4. def apply(fun: => Unit): Unit

    Executes the passed by-name, and if it throws an exception, forwards it to the thread that calls await, unless a by-name passed during a previous invocation of this method threw an exception.

    Executes the passed by-name, and if it throws an exception, forwards it to the thread that calls await, unless a by-name passed during a previous invocation of this method threw an exception.

    This method returns normally whether or not the passed function completes abruptly. If called multiple times, only the first invocation that yields an exception will "win" and have its exception forwarded to the thread that calls await. Any subsequent exceptions will be "swallowed." This method may be invoked by multiple threads concurrently, in which case it is a race to see who wins and has their exception forwarded to await. The await call will eventually complete abruptly with the winning exception, or return normally if that instance of Waiter is dismissed. Any exception thrown by a by-name passed to apply after the Waiter has been dismissed will also be "swallowed."

    fun

    the by-name function to execute

  5. final def asInstanceOf[T0]: T0
    Definition Classes
    Any
  6. def await(timeout: Timeout, dismissals: Dismissals)(implicit pos: Position): Unit

    Wait for an exception to be produced by the by-name passed to apply, or the specified number of dismissals, timing out after the specified timeout and sleeping an interval between checks configured by an implicit PatienceConfig.

    Wait for an exception to be produced by the by-name passed to apply, or the specified number of dismissals, timing out after the specified timeout and sleeping an interval between checks configured by an implicit PatienceConfig.

    This method may only be invoked by the thread that created the Waiter. Each time this method completes, its internal dismissal count is reset to zero, so it can be invoked multiple times. However, once await has completed abruptly with an exception produced during a call to apply, it will continue to complete abruptly with that exception.

    The timeout parameter allows you to specify a timeout after which a TestFailedException will be thrown with a detail message indicating the await call timed out. If no calls to apply have produced an exception and an insufficient number of dismissals has been received by the time the timeout has expired, await will complete abruptly with TestFailedException.

    As used here, a "check" is checking to see whether an exception has been thrown by a by-name passed to apply or the specified number of dismissals has occurred. The "interval" is the amount of time the thread that calls await will sleep between "checks."

  7. def await(dismissals: Dismissals)(implicit config: Waiters.PatienceConfig, pos: Position): Unit

    Wait for an exception to be produced by the by-name passed to apply, or the specified number of dismissals, sleeping an interval between checks and timing out after a timeout, both configured by an implicit PatienceConfig.

    Wait for an exception to be produced by the by-name passed to apply, or the specified number of dismissals, sleeping an interval between checks and timing out after a timeout, both configured by an implicit PatienceConfig.

    This method may only be invoked by the thread that created the Waiter. Each time this method completes, its internal dismissal count is reset to zero, so it can be invoked multiple times. However, once await has completed abruptly with an exception produced during a call to apply, it will continue to complete abruptly with that exception.

    The timeout parameter allows you to specify a timeout after which a TestFailedException will be thrown with a detail message indicating the await call timed out. If no calls to apply have produced an exception and an insufficient number of dismissals has been received by the time the timeout has expired, await will complete abruptly with TestFailedException.

    As used here, a "check" is checking to see whether an exception has been thrown by a by-name passed to apply or the specified number of dismissals has occurred. The "interval" is the amount of time the thread that calls await will sleep between "checks."

    config

    the PatienceConfig object containing the timeout parameter

  8. def await(timeout: Timeout)(implicit pos: Position): Unit

    Wait for an exception to be produced by the by-name passed to apply, or one dismissal, timing out after the specified timeout and sleeping an interval between checks configured by an implicit PatienceConfig.

    Wait for an exception to be produced by the by-name passed to apply, or one dismissal, timing out after the specified timeout and sleeping an interval between checks configured by an implicit PatienceConfig.

    This method may only be invoked by the thread that created the Waiter. Each time this method completes, its internal dismissal count is reset to zero, so it can be invoked multiple times. However, once await has completed abruptly with an exception produced during a call to apply, it will continue to complete abruptly with that exception.

    The timeout parameter allows you to specify a timeout after which a TestFailedException will be thrown with a detail message indicating the await call timed out. If no calls to apply have produced an exception and an insufficient number of dismissals has been received by the time the timeout has expired, await will complete abruptly with TestFailedException.

    As used here, a "check" is checking to see whether an exception has been thrown by a by-name passed to apply or a dismissal has occurred. The "interval" is the amount of time the thread that calls await will sleep between "checks."

  9. def await()(implicit config: Waiters.PatienceConfig, pos: Position): Unit

    Wait for an exception to be produced by the by-name passed to apply, or one dismissal, sleeping an interval between checks and timing out after a timeout, both configured by an implicit PatienceConfig.

    Wait for an exception to be produced by the by-name passed to apply, or one dismissal, sleeping an interval between checks and timing out after a timeout, both configured by an implicit PatienceConfig.

    This method may only be invoked by the thread that created the Waiter. Each time this method completes, its internal dismissal count is reset to zero, so it can be invoked multiple times. However, once await has completed abruptly with an exception produced during a call to apply, it will continue to complete abruptly with that exception.

    The timeout parameter allows you to specify a timeout after which a TestFailedException will be thrown with a detail message indicating the await call timed out. If no calls to apply have produced an exception and an insufficient number of dismissals has been received by the time the timeout has expired, await will complete abruptly with TestFailedException.

    As used here, a "check" is checking to see whether an exception has been thrown by a by-name passed to apply or a dismissal has occurred. The "interval" is the amount of time the thread that calls await will sleep between "checks."

    config

    the PatienceConfig object containing the timeout parameter

  10. def clone(): AnyRef
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.CloneNotSupportedException]) @native()
  11. def dismiss(): Unit

    Increases the dismissal count by one.

    Increases the dismissal count by one.

    Once the dismissal count has reached the value passed to await (and no prior invocations of apply produced an exception), await will return normally.

  12. final def eq(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  13. def equals(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef → Any
  14. def finalize(): Unit
    Attributes
    protected[lang]
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.Throwable])
  15. final def getClass(): Class[_ <: AnyRef]
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  16. def hashCode(): Int
    Definition Classes
    AnyRef → Any
    Annotations
    @native()
  17. final def isInstanceOf[T0]: Boolean
    Definition Classes
    Any
  18. final def ne(arg0: AnyRef): Boolean
    Definition Classes
    AnyRef
  19. final def notify(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  20. final def notifyAll(): Unit
    Definition Classes
    AnyRef
    Annotations
    @native()
  21. final def synchronized[T0](arg0: => T0): T0
    Definition Classes
    AnyRef
  22. def toString(): String
    Definition Classes
    AnyRef → Any
  23. final def wait(): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  24. final def wait(arg0: Long, arg1: Int): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException])
  25. final def wait(arg0: Long): Unit
    Definition Classes
    AnyRef
    Annotations
    @throws(classOf[java.lang.InterruptedException]) @native()

Inherited from AnyRef

Inherited from Any

Ungrouped