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

org.specs2.specification.FragmentExecution.scala Maven / Gradle / Ivy

The newest version!
package org.specs2
package specification

import control.Exceptions._
import text._
import main.Arguments
import time.SimpleTimer
import StandardFragments._
import execute._
import io.Location
import ResultLogicalCombinators._

/**
 * This trait executes Fragments
 *
 * It provides a function which executes fragments
 * and returns executed fragments
 */
trait FragmentExecution {

  /**
   * This method could be overriden to provide alternate behavior when executing an
   * Example
   */
  def executeBody(body: =>Result)(implicit arguments: Arguments): Result =
    if (arguments.plan)         Success("plan")
    else if (arguments.skipAll) Skipped()
    else                        ResultExecution.execute(body)

  /**
   * execute a Fragment.
   */
  def executeFragment(implicit arguments: Arguments): Function[Fragment, ExecutedFragment] = {
    val timer = new SimpleTimer().start
    (f: Fragment) => catchAllOr(execute(f))((e: Throwable) => ExecutedResult(NoMarkup("Fragment evaluation error"), Error(e), timer.stop, f.location, Stats(Error(e))))
  }

  /**
   * execute a Fragment.
   *
   * A Form is executed separately by executing each row and cell, setting the results on each cell
   */
  def execute(f: Fragment)(implicit arguments: Arguments = Arguments()) = f match {
    case Example(FormMarkup(form), _)     => {
      val timer = new SimpleTimer().start
      val executed = if (arguments.plan) form else form.executeForm
      val result = executed.execute
      ExecutedResult(FormMarkup(executed), result, timer.stop, f.location, Stats(result).copy(timer = timer.stop))
    }
	  case e @ Example(s, _)     => {
      val timer = new SimpleTimer().start
      val result = executeBody(e.execute)
      ExecutedResult(s, result, timer.stop, f.location, Stats(result).copy(timer = timer.stop))
    }
	  case Text(s)                       => ExecutedText(s, f.location)
	  case Br()                          => ExecutedBr(f.location)
    case Tab(n)                        => ExecutedTab(n, f.location)
    case Backtab(n)                    => ExecutedBacktab(n, f.location)
	  case End()                         => ExecutedEnd(f.location)
	  case s @ SpecStart(_,a,_)          => ExecutedSpecStart(s.withArgs(arguments.overrideWith(a)), f.location, Stats().startTimer)
	  case e @ SpecEnd(_,_)              => ExecutedSpecEnd(e, f.location, Stats().startTimer)
    case s @ Step(_,_)                 => executeStep("step", s, f.location)
    case s @ Action(_)                 => executeStep("action", s, f.location)
    case _                             => ExecutedNoText(isAction = true, new SimpleTimer, f.location)
  }

  private def executeStep(stepName: String, s: Executable, location: Location)(implicit args: Arguments) = {
    val timer = new SimpleTimer().start
    executeBody(s.execute) match {
      case err if err.isError  => ExecutedResult(NoMarkup(stepName+" error"), err, timer.stop, location, Stats(err))
      case f   if f.isFailure  => ExecutedResult(NoMarkup(stepName+" failure"), f, timer.stop, location, Stats(f))
      case sk  @ Skipped(_, _) => ExecutedResult(NoMarkup("skipped "+stepName), sk, timer.stop, location, Stats(sk))
      case other               => ExecutedNoText(isAction = stepName == "action", new SimpleTimer, location)
    }
  }

  /** these methods are used in tests */
  private[specs2]
  def executeBodies(exs: Fragments)(implicit arguments: Arguments=Arguments()): Seq[Result] = {
    exs.fragments.map(f => executeFragment(arguments)(f)). collect { case r: ExecutedResult => r.result }
  }

  private[specs2]
  def executeExamples(exs: Fragments)(implicit arguments: Arguments=Arguments()): Seq[ExecutedResult] = {
    exs.fragments.map(f => executeFragment(arguments)(f)). collect { case r: ExecutedResult => r }
  }

  private[specs2]
  def executeExamplesResult(exs: Fragments)(implicit arguments: Arguments=Arguments()): Result =
    executeExamples(exs)(arguments).foldLeft(Success():Result) { (res, cur) => res and cur.result }

  private[specs2]
  def executeSpecificationResult(spec: SpecificationStructure)(implicit arguments: Arguments=Arguments()): Result =
    executeExamplesResult(spec.content)(arguments)
}

private[specs2]
object FragmentExecution extends FragmentExecution





© 2015 - 2025 Weber Informatics LLC | Privacy Policy