Как составить Matcher [Iterable[A]] из Matcher[A] с помощью платформы тестирования спецификаций
Если у меня есть Matcher[A], как создать Matcher[Iterable[A]], который удовлетворяет только в том случае, если каждый элемент Iterable удовлетворяет исходному Matcher.
class ExampleSpec extends Specification {
def allSatisfy[A](m: => Matcher[A]): Matcher[Iterable[A]] = error("TODO")
def notAllSatisfy[A](m: => Matcher[A]): Matcher[Iterable[A]] = allSatisfy(m).not
"allSatisfy" should {
"Pass if all elements satisfy the expectation" in {
List(1, 2, 3, 4) must allSatisfy(beLessThan(5))
}
"Fail if any elements do not satisfy the expectation" in {
List(1, 2, 3, 5) must notAllSatisfy(beLessThan(5))
}
}
}
2 ответа:
Я, конечно, не претендую на то, чтобы быть экспертом по спецификациям, поэтому мой код, скорее всего, может быть значительно улучшен. В любом случае, я смог заставить его работать так:
class ExampleSpec extends Specification { def allSatisfy[A](m: Matcher[A]): Matcher[Iterable[A]] = new Matcher[Iterable[A]]() { def apply(v: => Iterable[A]) = { val iterable = v (iterable.forall(e => {println("checking el " + e); m(e)._1}), "all elements match", "not all elements match") } } def notAllSatisfy[A](m: => Matcher[A]): Matcher[Iterable[A]] = allSatisfy(m).not "allSatisfy" should { "Pass if all elements satisfy the expectation" in { List(1, 2, 3, 4) must allSatisfy(beLessThan(5)) } "Fail if any elements do not satisfy the expectation" in { List(1, 2, 3, 5) must notAllSatisfy(beLessThan(5)) } } }
Я думал, что у меня уже есть это из коробки, но это не так. Я планирую добавить это в спецификации в ближайшие дни:
import org.specs._ import org.specs.matcher._ object SeqMatcher extends Specification { implicit def toSeqMatcher[T](m: Matcher[T]) = new ToSeqMatcher(m) class ToSeqMatcher[T](m: Matcher[T]) { def toSeq: Matcher[Seq[T]] = new Matcher[Seq[T]]() { type Res = (Boolean, String, String) def apply(v: =>Seq[T]) = ((true, "", "") /: v) { (res: Res, cur: T) => def append(first: String, separator: String, second: String) = first + (if (first.isEmpty) "" else separator) + second val currentRes = m(cur) if (currentRes._1) (res._1 && currentRes._1, append(res._2, " and ", currentRes._2), append(res._3, " and ", currentRes._2)) else (res._1 && currentRes._1, append(res._2, " and ", currentRes._2), append(res._2, " but ", currentRes._2)) } } } List(1, 2, 6).toSeq must beLessThan(5).toSeq } SeqMatcher.reportSpecs
Что выведет:
x example 1 1 is less than 5 and 2 is less than 5 but 6 is less than 5
Следите за новостями!
Эрик.