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

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

package org.specs2
package reporter

import scalaz.{ Scalaz, Monoid, Reducer }
import Scalaz._
import collection.Seqx._
import specification._
import scala.collection.mutable.ArrayBuffer

/**
 * This trait computes the statistics of a Specification by mapping each ExecutedFragment
 * to a Stats object
 * 
 * Some stats objects embed their corresponding ExecutedSpecStart or ExecutedSpecEnd
 * fragment to be able to determine when the total Stats corresponding to all executed
 * specifications must be displayed
 * 
 * @see Stats.isEnd
 *
 */
private[specs2]
trait Statistics {

  import Stats._
  implicit def SpecsStatisticsMonoid  = new Monoid[SpecsStatistics] {
    def append(s1: SpecsStatistics, s2: =>SpecsStatistics): SpecsStatistics = {
      SpecsStatistics(s1.fragments ++ s2.fragments)
    }
    val zero = SpecsStatistics() 
  }

  def foldAll(fs: Seq[ExecutingFragment]) = fs.foldMap(StatisticsReducer.unit)
  
  val StatisticsReducer: Reducer[ExecutingFragment, SpecsStatistics]  = Reducer.unitReducer {
    f: ExecutingFragment => SpecsStatistics(f)
  }

  val ExecutedStatisticsReducer: Reducer[ExecutedFragment, SpecsStatistics]  = Reducer.unitReducer {
    f: ExecutedFragment => SpecsStatistics(f)
  }

  /**
   * The SpecsStatistics class stores the result of a specification execution, with the
   * a list of 'current' stats for each fragment execution and the total statistics 
   * for the whole specification
   */
  case class SpecsStatistics(fragments: Seq[ExecutingFragment] = ArrayBuffer()) {
    private val statsMonoid = Stats.StatsMonoid
    
    /** @return the list of all current stats, with the total on each line */
    lazy val totals: Seq[Stats] = {
      import NestedBlocks._

      def toBlock(f: ExecutingFragment) = f.get match {
        case ExecutedSpecStart(_,_,s)  => BlockStart(s)
        case ExecutedSpecEnd(_,_,s)    => BlockEnd(s)
        case other                     => BlockBit(other.stats)
      }
      totalContext(fragments.map(toBlock))(statsMonoid)
    }
    lazy val total = totals.lastOption.getOrElse(Stats())
  }
  case object SpecsStatistics {
    def apply(current: ExecutingFragment) = new SpecsStatistics(ArrayBuffer(current))
    def apply(current: ExecutedFragment) = new SpecsStatistics(ArrayBuffer(FinishedExecutingFragment(current)))
  }

  /**
   * The SpecsStats class just stores a list of stats, each one corresponding to a Fragment
   */
  case class SpecStats(stats: Seq[Stats] = ArrayBuffer()) {
    def last = stats.lastOption.getOrElse(Stats())
  }
  implicit def SpecStatsMonoid  = new Monoid[SpecStats] {
    def append(s1: SpecStats, s2: =>SpecStats): SpecStats = {
      SpecStats(s1.stats ++ s2.stats)
    }
    val zero = SpecStats()
  }

  val StatsReducer: Reducer[ExecutingFragment, SpecStats] = Reducer.unitReducer {
    f: ExecutingFragment => SpecStats(ArrayBuffer(f.get.stats))
  }

  val StatsReducer2: Reducer[ExecutingFragment, Stats] = Reducer.unitReducer {
    f: ExecutingFragment => f.get.stats
  }
}
private [specs2]
object Statistics extends Statistics




© 2015 - 2024 Weber Informatics LLC | Privacy Policy