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 io.{DirectoryPath, FilePath}
import main.Arguments
import specification.core._
import specification.process._
import execute._
import text.NotNullStrings._
import scala.xml.NodeSeq
import matcher._
import form._
import control._
import ExecuteActions._
import org.specs2.concurrent.ExecutionEnv
import org.specs2.control.producer.{Transducer, Transducers}
import org.specs2.text.AnsiColors
import origami._
import org.specs2.time.SimpleTimer
/**
* Create the body of an html file reporting a specification execution
*/
trait HtmlBodyPrinter {
/**
* Make the body of the Html file based on all the specification fragments
*/
def makeBody(spec: SpecStructure, stats: Stats, timer: SimpleTimer, options: HtmlOptions, arguments: Arguments, pandoc: Boolean)(ee: ExecutionEnv): Operation[String] = {
val title = spec.name
type HtmlState = (String, Level)
// Br (new line) fragment's description is meant for console output but
// in html output examples are embedded in tags and
// there is no need to render additional blank line between them
val deleteLineBetweenExamples: Transducer[ActionStack, Fragment, Fragment] = producer =>
producer.pipe(Transducers.zipWithPreviousAndNext).filter {
case (Some(f1), f2, Some(f3)) if Fragment.isExample(f1) && Fragment.isBr(f2) && Fragment.isExample(f3) => false
case _ => true
}.map {
case (_, f, _) => f
}
val htmlFold = fold.fromFoldLeft[Action, Fragment, HtmlState](("", Level())) { case ((htmlString, level), fragment) =>
fragment.executionResult.map { result =>
(htmlString + printFragment(fragment, result, arguments, level, options.outDir, pandoc),
Levels.fold(fragment, level))
}
}
Operations.delayed(spec.fragments.contents.pipe(deleteLineBetweenExamples).fold(htmlFold).runOption(ee)).map {
case Some((html, _)) =>
html +
s"""${printStatistics(title, stats, timer, options)}"""
case None =>
s""
}
}
/**
* Print a Fragment as a piece of Html
*
* If pandoc is true we make sure that text is not parsed in order to be correctly rendered as Markdown
*/
def printFragment(fragment: Fragment, result: Result, arguments: Arguments, level: Level, baseDir: DirectoryPath, pandoc: Boolean): NodeSeq = {
fragment match {
case t if Fragment.isText(t) =>
// remove Ansi colors in case some of them are present in the text
val text = AnsiColors.removeColors(t.description.show)
if (text.trim.nonEmpty) {
if (pandoc)
scala.xml.Unparsed(text)
else {
// remove additional newlines and replace with just one when there is no markdown formatting
val brStart = if (text.filterNot(_ == ' ').startsWith("\n")) else NodeSeq.Empty
val brEnd = if (text.filterNot(_ == ' ').endsWith("\n")) else NodeSeq.Empty
{brStart}{scala.xml.Unparsed(text.trim)}{brEnd}
}
} else NodeSeq.Empty
case Fragment(form @ FormDescription(_),_,_) =>
form.xml(arguments)
case e if Fragment.isExample(e) =>
val example =
result match {
case r: Success =>
{show(e)}
case f1 @ Failure(m, e1, st, details) =>
failureElement("example", f1, show(e), m, arguments.failtrace, details, arguments)
case er @ Error(m, e1) =>
errorElement("example", er, show(e), m, arguments)
case r: Skipped =>
{show(e)} {r.message}
case r: Pending =>
{show(e)} {r.message}
// if it is a data table as an auto-example
case DecoratedResult(table: DataTable, res) if Description.isCode(fragment.description) =>
{Form(table).toXml(arguments)}
// if it is a failed data table
case DecoratedResult(table: DataTable, res) if !res.isSuccess =>
{show(e)}
{Form(table).toXml(arguments)}
case DecoratedResult(table: DataTable, res) =>
{show(e)}
case r =>
{show(e)} {r.message}
}
if (level.incrementNext)
{example}
else example
case f if Fragment.isStepOrAction(f) =>
result match {
case f1 @ Failure(m, e1, st, details) =>
failureElement("step", f1, Failed step!, m, arguments.failtrace, details, arguments)
case er @ Error(m, e1) =>
errorElement("step", er, Error in a step!, m, arguments)
case other => NodeSeq.Empty
}
case Fragment(ref: SpecificationRef,x,_) if !ref.hidden =>
if (ref.muted) {
{ref.linkText}
} else {
val status = result.statusName(arguments)+" ok"
val image = if (fragment.isExecutable) else NodeSeq.Empty
{image} {ref.linkText}
}
case Fragment(Br,_,_) =>
case other => NodeSeq.Empty
}
}
def toggleElement(a: Any) = "toggleImage(this); showHide('"+id(a)+"')"
def id(a: Any) = System.identityHashCode(a).toString
def show(f: Fragment) =
f.description match {
case Code(text) => {text}
case other =>
val d = f.description.show
{if (Seq("*", "-").exists(d.trim.startsWith)) d.trim.drop(1) else d}
}
def showStacktrace(id: String, st: List[StackTraceElement], klass: String, arguments: Arguments) =
{ arguments.traceFilter(st).map(t => {t.toString.replace("$", ".")} ).foldLeft(NodeSeq.Empty)(_ ++ _) }
def failureElement(element: String, f: Result with ResultStackTrace, description: Any, m: String, showTrace: Boolean, details: Details, arguments: Arguments) = {
val message = {m.notNull+" ("+f.location(arguments.traceFilter)+")"}
val detailedFailure = details match {
case FailureDetails(expected, actual) if arguments.diffs.show(expected, actual) =>
"\nExpected:\n"{expected}"\nActual:\n"{actual}
case FailureSeqDetails(expected, actual) if arguments.diffs.showSeq(expected, actual, ordered = true) =>
val (added, missing) = arguments.diffs.showSeqDiffs(actual, expected, ordered = true)
val addedValues = makeDifferencesMessage("Added", added)
val missingValues = makeDifferencesMessage("Missing", missing)
val details = List(addedValues, missingValues).mkString("\n")
{details}
case FailureSetDetails(expected, actual) if arguments.diffs.showSeq(expected.toSeq, actual.toSeq, ordered = false) =>
val (added, missing) = arguments.diffs.showSeqDiffs(actual.toSeq, expected.toSeq, ordered = true)
val addedValues = makeDifferencesMessage("Added", added)
val missingValues = makeDifferencesMessage("Missing", missing)
val details = List(addedValues, missingValues).mkString("\n")
{details}
case FailureMapDetails(expected, actual) if arguments.diffs.showMap(actual, expected)=>
val (added, missing, different) = arguments.diffs.showMapDiffs(actual, expected)
val addedValues = makeDifferencesMessage("Added", added)
val missingValues = makeDifferencesMessage("Missing", missing)
val differentValues = makeDifferencesMessage("Different", different)
val details = List(addedValues, missingValues, differentValues).mkString("\n")
{details}
case _ => NodeSeq.Empty
}
val fullMessage =
if (showTrace)
{message}{detailedFailure}
else
{message}{detailedFailure}
val trace =
if (showTrace) showStacktrace(id(f), f.stackTrace, "failure", arguments)
else NodeSeq.Empty
{description}
{fullMessage}
{trace}
}
def errorElement(element: String, er: Result with ResultStackTrace, description: Any, m: String, arguments: Arguments) = {