Skip to content

Instantly share code, notes, and snippets.

@ymasory
Created December 1, 2012 00:16
Show Gist options
  • Save ymasory/4179699 to your computer and use it in GitHub Desktop.
Save ymasory/4179699 to your computer and use it in GitHub Desktop.
specs2 matchers for scalaz 6's Validation typeclass
package org.specs2
package matcher
import text.Quote._
import execute.{ Failure => SpecsFailure, Result }
import scalaz.{ Failure, Success, Validation }
/** scalaz 6 Validation matchers created by exact analogy to specs2's
* built-in Either/Left/Right matchers.
* You can't change the package of this file from org.specs2.matcher or
* it won't compile. */
trait ValidationMatchers extends SuccessMatcher with FailureMatcher
object ValidationMatchers extends ValidationMatchers
object SuccessMatcher extends SuccessMatcher
trait SuccessMatcher {
def beSuccess[T](t: => T) = new Matcher[Validation[_, T]] {
def apply[S <: Validation[_, T]](value: Expectable[S]) = {
val expected = t
result(
value.value == Success(t),
value.description + " is Success with value" + q(expected),
value.description + " is not Success with value" + q(expected),
value
)
}
}
def beSuccess[T] = new SuccessMatcher[T]
class SuccessMatcher[T] extends Matcher[Validation[_, T]] {
def apply[S <: Validation[_, T]](value: Expectable[S]) = {
result(
value.value.isSuccess,
value.description + " is Success",
value.description + " is not Success",
value
)
}
def like(f: PartialFunction[T, MatchResult[_]]) = this and partialMatcher(f)
private def partialMatcher(f: PartialFunction[T, MatchResult[_]]) =
new Matcher[Validation[_, T]] {
def apply[S <: Validation[_, T]](value: Expectable[S]) = {
val res: Result = value.value match {
case Success(t) if f.isDefinedAt(t) => f(t).toResult
case Success(t) if !f.isDefinedAt(t) => SpecsFailure("function undefined")
case other => SpecsFailure("no match")
}
result(
res.isSuccess,
value.description + " is Success[T] and " + res.message,
value.description + " is Success[T] but " + res.message,
value
)
}
}
}
def success[T](t: => T) = beSuccess(t)
def success[T] = beSuccess
}
object FailureMatcher extends FailureMatcher
trait FailureMatcher {
def beFailure[T](t: => T) = new Matcher[Validation[T, _]] {
def apply[S <: Validation[T, _]](value: Expectable[S]) = {
val expected = t
result(
value.value == Failure(t),
value.description + " is Failure with value" + q(expected),
value.description + " is not Failure with value" + q(expected),
value
)
}
}
def beFailure[T] = new FailureMatcher[T]
class FailureMatcher[T] extends Matcher[Validation[T, _]] {
def apply[S <: Validation[T, _]](value: Expectable[S]) = {
result(
value.value.isFailure,
value.description + " is Failure",
value.description + " is not Failure",
value
)
}
def like(f: PartialFunction[T, MatchResult[_]]) = this and partialMatcher(f)
private def partialMatcher(f: PartialFunction[T, MatchResult[_]]) =
new Matcher[Validation[T, _]] {
def apply[S <: Validation[T, _]](value: Expectable[S]) = {
val res: Result = value.value match {
case Failure(t) if f.isDefinedAt(t) => f(t).toResult
case Failure(t) if !f.isDefinedAt(t) => SpecsFailure("function undefined")
case other => SpecsFailure("no match")
}
result(
res.isFailure,
value.description + " is Failure[T] and " + res.message,
value.description + " is Failure[T] but " + res.message,
value
)
}
}
}
def failure[T](t: => T) = beFailure(t)
def failure[T] = beFailure
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment