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

org.specs2.reporter.JUnitXmlPrinter.scala Maven / Gradle / Ivy

There is a newer version: 4.10.6
Show newest version
package org.specs2
package reporter

import foldm._, FoldM._, FoldableM._, stream._, FoldProcessM._
import scalaz.{Failure => _, _}, Scalaz._
import org.junit.runner.Description
import java.net.InetAddress
import main.Arguments
import execute._
import io.FileName
import scalaz.concurrent.Task
import control._
import io._
import scala.collection.JavaConversions._
import Exceptions._
import specification.core._
import specification.process._
import text.NotNullStrings._
import JUnitDescriptions._

/**
 * The JUnitXmlPrinter creates an xml file with the specification execution results
 */
trait JUnitXmlPrinter extends Printer {
  def prepare(env: Env, specs: List[SpecStructure]): Action[Unit]  = Actions.unit
  def finalize(env: Env, specs: List[SpecStructure]): Action[Unit] = Actions.unit

  def sink(env: Env, spec: SpecStructure): SinkTask[Fragment] =
    (Statistics.fold zip FoldId.list[Fragment]).into[Task].
      mapFlatten(saveResults(env, spec))

  def saveResults(env: Env, spec: SpecStructure): ((Stats, List[Fragment])) =>  Task[Unit] = { case (stats, fs) =>
    val suite = descriptionFold(spec, stats, env).run(descriptions(spec, fs).toList)
    env.fileSystem.writeFileTask(outputDirectory(env) | FileName.unsafe(spec.specClassName+".xml"), suite.xml)
  }

  def descriptionFold(spec: SpecStructure, stats: Stats, env: Env): Fold[(Fragment, Description), TestSuite] = {
    val suite = TestSuite(specDescription(spec), spec.specClassName, stats.errors, stats.failures, stats.skipped, stats.timer.totalMillis)
    fromFoldLeft[(Fragment, Description), TestSuite](suite) { case (res, (f, d)) =>
      if (Fragment.isExample(f)) res.addTest(new TestCase(d, f.executionResult, f.execution.executionTime.totalMillis)(env.arguments))
      else                       res
    }
  }

  def descriptions(spec: SpecStructure, fragments: List[Fragment]) =
    JUnitDescriptions.fragmentDescriptions(spec.setFragments(Fragments(fragments:_*)))

  def outputDirectory(env: Env): DirectoryPath =
    env.arguments.commandLine.directoryOr("junit.outdir", "target" / "test-reports")

  case class TestSuite(description: Description, className: String, errors: Int, failures: Int, skipped: Int, time: Long = 0, tests: Seq[TestCase] = Seq()) {
    def addTest(t: TestCase) = copy(tests = tests :+ t)

    def xml =
      s"""|
          |
          |  $properties
          |  ${tests.map(_.xml).mkString("\n")}
          |  
          |  
          |""".stripMargin

    /**
     * output properties
     */
    def properties =
      s"""
            ${System.getProperties.entrySet.toSeq.map(p => s"""""").mkString("\n")}
          """
  }

  case class TestCase(desc: Description, result: Result, time: Long)(implicit args: Arguments) {
    def xml =
      s"""
            $testError$testFailure$testSkipped$testPending
          """

    def testError = result match {
      case er @ Error(m, e) => s"""${escape(args.traceFilter(er.stackTrace).mkString("\n"))}"""
      case _ => ""
    }

    def testFailure = result match {
      case f @ Failure(m, e, st, d) => s"""${escape(args.traceFilter(st).mkString("\n"))}"""
      case _ => ""
    }

    def testPending = result match {
      case Pending(m) => ""
      case _ => ""
    }

    def testSkipped = result match {
      case Skipped(m, e) => """"""
      case _ => ""
    }
  }

  private def escape(s: =>String): String =
    scala.xml.Utility.escape(s.notNull)

  private def formatTime(t: Long) = "%.3f" format (t / 1000.0)
}

object JUnitXmlPrinter extends JUnitXmlPrinter




© 2015 - 2024 Weber Informatics LLC | Privacy Policy