Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.specs2
package reporter
import _root_.org.junit.runner.notification.RunNotifier
import _root_.org.junit._
import _root_.org.junit.runner._
import scalaz.{Reducer, Scalaz}
import Scalaz._
import main.{SystemProperties, Arguments}
import execute._
import specification._
import text.AnsiColors
import control.{ExecutionOrigin, Throwablex}
import junit.framework.AssertionFailedError
import text.NotNullStrings._
/**
* The JUnitReporter reports a specification by using a JUnit RunNotifier
*
* To do so, it uses most of the execution pipeline of a normal reporter but overrides the fragments execution so as
* to notify JUnit of the appropriate events
*/
trait JUnitReporter extends ExecutionOrigin with DefaultReporter with Exporters {
/** the selected fragments to report */
def selected: SpecificationStructure
/** map providing a description for each fragment */
def descriptions: Map[Fragment, Description]
/** arguments for the specification */
implicit def args: Arguments
/** system properties */
implicit def properties: SystemProperties
/** the junit notifier to use */
def notifier: RunNotifier
/**
* run the suite by executing each fragment related to a description:
* - execute all fragments (including Steps which are reported as steps)
* - for each result, report the failure/error/skipped or pending message as a
* junit failure or ignored event on the RunNotifier
*/
def report = {
selected |> sequence |> execute |> store |> export
}
override def executeFragment(implicit arguments: Arguments): Function[Fragment, ExecutedFragment] = (fragment: Fragment) => {
def execute(aFragment: Fragment) = super.executeFragment(arguments)(aFragment)
// the description for a given fragment. It *should* always be found by construction
val desc = descriptions(fragment)
fragment match {
case f: Example => {
notifier.fireTestStarted(desc)
val result = execute(f)
notifyResult(desc, result)
result
}
case f: Step => notifyResult(desc, execute(f))
case f: Action => notifyResult(desc, execute(f))
case f: SpecStart => notifier.fireTestRunStarted(desc); execute(f)
case f: SpecEnd => notifier.fireTestRunFinished(new org.junit.runner.Result); execute(f)
case other => execute(other)
}
}
/**
* notify JUnit of a new result
*/
private def notifyResult(desc: Description, result: ExecutedFragment): ExecutedFragment = {
result match {
case ExecutedResult(_, r, timer, _, _) => {
r match {
case f @ Failure(m, e, st, d) => failWith(desc, junitFailure(f))
case e @ Error(m, st) => failWith(desc, args.traceFilter(e.exception))
case DecoratedResult(_, f @ Failure(m, e, st, d)) => failWith(desc, junitFailure(f))
case DecoratedResult(_, e @ Error(m, st)) => failWith(desc, args.traceFilter(e.exception))
case Pending(_) | Skipped(_, _) => notifier.fireTestIgnored(desc)
case Success(_, _) | DecoratedResult(_, _) => notifier.fireTestFinished(desc)
}
}
case other => ()
}
result
}
private def failWith(desc: Description, failure: Throwable) = {
notifier.fireTestFailure(new notification.Failure(desc, failure))
notifier.fireTestFinished(desc)
}
def export(implicit args: Arguments) = (executing: ExecutingSpecification) => {
def exportTo = (name: String) => properties.isDefined(name) || args.contains(name)
exportAll(args, exportTo)(executing)
executing.executed
}
/** @return a Throwable expected by JUnit Failure object */
private def junitFailure(f: Failure)(implicit args: Arguments): Throwable = f match {
case Failure(m, e, st, NoDetails) =>
new SpecFailureAssertionFailedError(Throwablex.exception(AnsiColors.removeColors(m), args.traceFilter(st)))
case Failure(m, e, st, FromNotImplementedError) =>
new SpecFailureAssertionFailedError(Throwablex.exception(AnsiColors.removeColors(m), args.traceFilter(st)))
case Failure(m, e, st, FromJUnitAssertionError) =>
new SpecFailureAssertionFailedError(Throwablex.exception(AnsiColors.removeColors(m), args.traceFilter(st)))
case Failure(m, e, st, FailureDetails(actual, expected)) => new ComparisonFailure(AnsiColors.removeColors(m), expected, actual) {
private val e = args.traceFilter(f.exception)
override def getStackTrace = e.getStackTrace
override def getCause = e.getCause
override def printStackTrace() { e.printStackTrace() }
override def printStackTrace(w: java.io.PrintStream) { e.printStackTrace(w) }
override def printStackTrace(w: java.io.PrintWriter) { e.printStackTrace(w) }
}
case Failure(m, e, st, FailureSeqDetails(actual, expected)) =>
val details =
if (args.diffs.showSeq(actual, expected, ordered = true)) {
val (added, missing) = args.diffs.showSeqDiffs(actual, expected, ordered = true)
List(showValues("Added", added), showValues("Missing", missing)).mkString(" / ")
} else ""
new ComparisonFailure(AnsiColors.removeColors(m+details), expected.mkString("\n"), actual.mkString("\n")) {
private val e = args.traceFilter(f.exception)
override def getStackTrace = e.getStackTrace
override def getCause = e.getCause
override def printStackTrace() { e.printStackTrace() }
override def printStackTrace(w: java.io.PrintStream) { e.printStackTrace(w) }
override def printStackTrace(w: java.io.PrintWriter) { e.printStackTrace(w) }
}
case Failure(m, e, st, details @ FailureSetDetails(actual, expected)) =>
val details =
if (args.diffs.showSeq(actual.toSeq, expected.toSeq, ordered = false)) {
val (added, missing) = args.diffs.showSeqDiffs(actual.toSeq, expected.toSeq, ordered = false)
List(showValues("Added", added.toSeq), showValues("Missing", missing.toSeq)).mkString(" / ")
} else ""
new ComparisonFailure(AnsiColors.removeColors(m+details), expected.mkString("\n"), actual.mkString("\n")) {
private val e = args.traceFilter(f.exception)
override def getStackTrace = e.getStackTrace
override def getCause = e.getCause
override def printStackTrace() { e.printStackTrace() }
override def printStackTrace(w: java.io.PrintStream) { e.printStackTrace(w) }
override def printStackTrace(w: java.io.PrintWriter) { e.printStackTrace(w) }
}
case Failure(m, e, st, details @ FailureMapDetails(actual, expected)) =>
val details =
if (args.diffs.showMap(actual, expected)) {
val (added, missing, different) = args.diffs.showMapDiffs(actual, expected)
List(showValues("Added", added), showValues("Missing", missing), showValues("Different", different)).mkString(" / ")
} else ""
new ComparisonFailure(AnsiColors.removeColors(m+details), expected.mkString("\n"), actual.mkString("\n")) {
private val e = args.traceFilter(f.exception)
override def getStackTrace = e.getStackTrace
override def getCause = e.getCause
override def printStackTrace() { e.printStackTrace() }
override def printStackTrace(w: java.io.PrintStream) { e.printStackTrace(w) }
override def printStackTrace(w: java.io.PrintWriter) { e.printStackTrace(w) }
}
}
/** show values as a string with a description */
def showValues(description: String, values: Seq[Any]): String =
if (values.nonEmpty) s"$description ${values.map(notNullPair).mkString("\n", "\n", "\n\n")}" else ""
}
/**
* Descriptions for a seq of Fragments to execute
*/
class JUnitDescriptionsFragments(className: String) extends JUnitDescriptions[Fragment](className)(Levels.FragmentLevelsReducer) {
def initialFragment(className: String) = Text(className)
/**
* This function is used to map each node in a Tree[Fragment] to a pair of
* (Description, Fragment)
*
* The Int argument is the numeric label of the current TreeNode being mapped.
* It is used to create a unique description of the example to executed which is required
* by JUnit
*/
def mapper(className: String): (Fragment, Seq[DescribedFragment], Int) => Option[DescribedFragment] =
(f: Fragment, parentNodes: Seq[DescribedFragment], nodeLabel: Int) => f match {
case s: SpecStart => Some(f -> createDescription(className, suiteName=testName(s.name)))
case t: Text if t.text.raw.trim.nonEmpty => Some(f -> createDescription(className, suiteName=testName(t.text.raw)))
case t: Text => None
case t: Example => Some(f -> createDescription(className, label=nodeLabel.toString, testName=testName(t.desc.toString, parentPath(parentNodes))))
case t: Step => Some(f -> createDescription(className, label=nodeLabel.toString, testName="step"))
case t: Action => Some(f -> createDescription(className, label=nodeLabel.toString, testName="action"))
case other => None
}
}
/**
* This class refines the `AssertionFailedError` from junit
* and provides the stackTrace of an exception which occurred during the specification execution
*/
class SpecFailureAssertionFailedError(e: Exception) extends AssertionFailedError(e.getMessage.notNull) {
override def toString = e.toString
override def getStackTrace = e.getStackTrace
override def getCause = e.getCause
override def printStackTrace() { e.printStackTrace() }
override def printStackTrace(w: java.io.PrintStream) { e.printStackTrace(w) }
override def printStackTrace(w: java.io.PrintWriter) { e.printStackTrace(w) }
}