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

org.specs2.execute.ResultImplicits.scala Maven / Gradle / Ivy

The newest version!
package org.specs2
package execute

import Result.ResultFailureMonoid
import text.Quote._
import text.Plural._
import scalaz._
import Scalaz._
/**
 * This trait adds some implicits to easily fold sequences of results
 */
trait ResultImplicits {

  implicit def verifyResultFunction[T, R : AsResult](t: T => R): ResultFunctionVerification[T, R] =
    new ResultFunctionVerification(t)

  class ResultFunctionVerification[T, R : AsResult](t: T => R) {

    /** apply the function to the value and convert to a Result */
    def apply(value: T) = AsResult(t(value))

    /** @return the "and" of all results, stopping after the first failure */
    def forall[S <: Traversable[T]](seq: S) = {
      if (seq.isEmpty) StandardResults.success
      else {
        val (index, r) = seq.drop(1).foldLeft((0, apply(seq.head))) { case ((i, res), cur) =>
          if (res.isSuccess) (i + 1, apply(cur))
          else               (i, res)
        }
        lazy val failingElementMessage = "In the sequence "+qseq(seq)+" the "+(index+1).th+" element is failing: "+r.message

        if (r.isSuccess) Success("All elements of "+qseq(seq)+" are successful")
        else             Failure(failingElementMessage)
      }
    }

    /**
     * @return the aggregation of all results
     */
    def foreach[S <: Traversable[T]](seq: S) = {
      if (seq.isEmpty) StandardResults.success
      else             seq.drop(1).foldLeft(apply(seq.head)) { (res, cur) => res |+| apply(cur) }
    }

    /**
     * @return success if at least one result is a success
     */
    def atLeastOnce[S <: Traversable[T]](seq: S) = {
      if (seq.isEmpty) Failure("no result")
      else seq.drop(1).foldLeft(apply(seq.head)) { (res, cur) => if (res.isSuccess) res else apply(cur) }
    }
  }

  /**
   * Two results r1 and r2 are equivalent if
   * r1.isSuccess == r2.isSuccess
   */
  implicit class resultsEquivalence[R1 : AsResult](r1: =>R1) {
    def <==>[R2 : AsResult](r2: =>R2): Result = {
      val (result1, result2) = (AsResult(r1), AsResult(r2))
      ResultLogicalCombinators.combineResult(Success()).iff(result1.isSuccess == result2.isSuccess).mapMessage { _ =>
        result1.message+"\nis not equivalent to\n"+result2.message
      }
    }
  }

}

object ResultImplicits extends ResultImplicits




© 2015 - 2024 Weber Informatics LLC | Privacy Policy