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

org.scalatest.concurrent.ConductorFixture.scala Maven / Gradle / Ivy

/*
  * Copyright 2001-2013 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.concurrent

import org.scalatest._
import org.scalatest.fixture
import org.scalatest.OutcomeOf.outcomeOf

/**
 * Trait that can pass a new Conductor fixture into tests.
 *
 * 

* Here's an example of the use of this trait to test the ArrayBlockingQueue * class from java.util.concurrent: *

* *
 * import org.scalatest.fixture
 * import org.scalatest.concurrent.ConductorFixture
 * import org.scalatest.matchers.Matchers
 * import java.util.concurrent.ArrayBlockingQueue
 *
 * class ArrayBlockingQueueSuite extends fixture.FunSuite with ConductorFixture with Matchers {
 * 
 *   test("calling put on a full queue blocks the producer thread") { conductor => import conductor._
 *
 *     val buf = new ArrayBlockingQueue[Int](1)
 * 
 *     thread("producer") {
 *       buf put 42
 *       buf put 17
 *       beat should be (1)
 *     }
 * 
 *     thread("consumer") {
 *       waitForBeat(1)
 *       buf.take should be (42)
 *       buf.take should be (17)
 *     }
 * 
 *     whenFinished {
 *       buf should be ('empty)
 *     }
 *   }
 *
 *   test("calling take on an empty queue blocks the consumer thread") { conductor => import conductor._
 *
 *     val buf = new ArrayBlockingQueue[Int](1)
 *
 *     thread("producer") {
 *       waitForBeat(1)
 *       buf put 42
 *       buf put 17
 *     }
 *
 *     thread("consumer") {
 *       buf.take should be (42)
 *       buf.take should be (17)
 *       beat should be (1)
 *     }
 *
 *     whenFinished {
 *       buf should be ('empty)
 *     }
 *   }
 * }
 * 
* *

* For an explanation of how these tests work, see the documentation for Conductors. *

* * @author Bill Venners */ trait ConductorFixture extends TestSuiteMixin with Conductors { this: fixture.TestSuite => /** * Defines type Fixture to be Conductor. */ type FixtureParam = Conductor /** * Creates a new Conductor, passes the Conductor to the * specified test function, and ensures that conduct gets invoked * on the Conductor. * *

* After the test function returns (so long as it returns normally and doesn't * complete abruptly with an exception), this method will determine whether the * conduct method has already been called (by invoking * conductingHasBegun on the Conductor). If not, * this method will invoke conduct to ensure that the * multi-threaded scenario is actually conducted. *

* *

* This trait is stackable with other traits that override withFixture(NoArgTest), because * instead of invoking the test function directly, it delegates responsibility for invoking the test * function to withFixture(NoArgTest). *

*/ def withFixture(test: OneArgTest): Outcome = { val conductor = new Conductor withFixture(test.toNoArgTest(conductor)) match { case Succeeded if !conductor.conductingHasBegun => outcomeOf { conductor.conduct() } case other => other } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy