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

org.specs2.form.Effect.scala Maven / Gradle / Ivy

package org.specs2
package form

import control.Exceptions._
import control.Property
import execute._
import DecoratedProperties._

/**
 * An Effect is a property which is used to display names corresponding to side-effects.
 *
 * If the side effect throws an exception, the Effect will display it alongside to the label. Otherwise only the label
 * is displayed.
 * 
 * The apply method can be used to execute the Effect effect and possibly get a value out of it (but usually not displayed):
 *   `Effect(label, 1).apply() must_== 1`
 * 
 * The value is stored in a Property object so it will not be evaluated until explicitly queried.
 */
case class Effect[T](label: String, value: Property[T], decorator: Decorator = Decorator()) extends Executable with StandardResults
  with DecoratedProperty[Effect[T]] {
  /** executing an effect execute the value and returns success unless there is an Error */
  override def execute = {
    valueOrResult match {
      case Left(e)  => e
      case Right(v) => success
    }
  }
  def valueOrResult: Either[Result, T] = {
    trye(value.get)(Error(_))
  }
  /**
   * set a new value on the effect.
   */
  def apply(v: =>T) = new Effect(label, value(v), decorator)
  /** @return the effect value */
  def apply(): T = value.get
  /** alias for apply() */
  def get: T = apply()
  /** @return "label" */
  override def toString = label
  /** set a new Decorator */
  def decoratorIs(d: Decorator) = copy(decorator = d)
  /** use this Effect as a header in a table */
  def header = this.center.bold.bkGrey

  override def equals(a: Any) = a match {
    case Effect(l, v, _) => label == l && value == v
    case other          => false
  }
  override def hashCode = label.hashCode + value.hashCode
}
/**
 * Factory methods for creating Effects. Effects values can also be concatenated to produce
 * "summary" effects.
 * 
 * val e1 = Effect("hello", print("hello"))
 * val e2 = Effect("world", print("world"))
 * val concatenatedEffects = Effect(e1, e2)
 * concatenatedEffects.toString == hello/world
 * 
 * val concatenatedEffect = Effect(", ", e1, e2)
 * concatenatedEffects2.toString == hello, world
 */
case object Effect {
  def apply[T](value: =>T): Effect[T] = new Effect("", Property(value))
  def apply[T](label: String, value: =>T): Effect[T] = new Effect(label, Property(value))
  def apply(e1: Effect[_], es: Effect[_]*): Effect[Any] = Effect("/", e1, es:_*)
  def apply(separator: String, e1: Effect[_], es: Effect[_]*): Effect[Any] = {
    Effect((e1 :: es.toList).map(_.label).mkString(separator), (e1 :: es.toList) foreach identity)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy