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

org.scalatest.AsyncOutcome.scala Maven / Gradle / Ivy


package org.scalatest

import scala.util.{Success, Try, Failure}
import scala.concurrent.{ExecutionContext, Future, Await}
import scala.concurrent.duration._

private[scalatest] trait AsyncOutcome {
  def onComplete(f: Try[Outcome] => Unit)
  def toStatus: Status
  // SKIP-SCALATESTJS-START
  def toOutcome: Outcome // may block
  // SKIP-SCALATESTJS-END
  def toInternalFutureOutcome: Future[Outcome]
  def toFutureOutcome: FutureOutcome
}

private[scalatest] case class PastOutcome(past: Outcome) extends AsyncOutcome {

  def onComplete(f: Try[Outcome] => Unit): Unit = {
    f(new Success(past))
  }
  def toStatus: Status =
    past match {
      case _: Failed => FailedStatus
      case _ => SucceededStatus
    }
  // SKIP-SCALATESTJS-START
  def toOutcome: Outcome = past
  // SKIP-SCALATESTJS-END
  def toInternalFutureOutcome: Future[Outcome] = Future.successful(past)
  def toFutureOutcome: FutureOutcome = FutureOutcome { Future.successful(past) }
}

private[scalatest] case class InternalFutureOutcome(future: Future[Outcome])(implicit ctx: ExecutionContext) extends AsyncOutcome {

  private final val queue = new ConcurrentLinkedQueue[Try[Outcome] => Unit]
  private final val status = new ScalaTestStatefulStatus

  future.onComplete {
    case Success(result) =>
      for (f <- queue.iterator)
        f(Success(result))
      status.setCompleted()

    case Failure(ex) =>
      for (f <- queue.iterator)
        f(Failure(ex))
      status.setFailedWith(ex)
      status.setCompleted()
  } /* fills in ctx here */

  def onComplete(f: Try[Outcome] => Unit): Unit = {
    var executeLocally = false
    synchronized {
      if (!future.isCompleted)
        queue.add(f)
      else
        executeLocally = true
    }
    if (executeLocally) {
      future.value.get match {
        case Success(result) => f(new Success(result))
        case Failure(ex) => f(new Failure(ex))
      }
    }
  }
  def toStatus: Status = status
  // SKIP-SCALATESTJS-START
  def toOutcome: Outcome = Await.result(future, Duration.Inf)
  // SKIP-SCALATESTJS-END
  def toInternalFutureOutcome: Future[Outcome] = future
  def toFutureOutcome: FutureOutcome = FutureOutcome { future }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy