3

如果我有一个 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))
    }
  }
}
4

2 回答 2

5

我当然不会声称自己是 Specs 专家,因此我的代码很可能会得到很大改进。无论如何,我都能让它像这样工作:


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))
    }
  }
}
于 2010-06-05T07:23:36.640 回答
1

我以为我已经开箱即用了,但事实并非如此。我计划在接下来的几天将其添加到规格中:

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 

敬请关注!

埃里克。

于 2010-06-07T00:25:23.473 回答