Search code examples
scalacompositionspecsmatcher

How to compose a Matcher[Iterable[A]] from a Matcher[A] with specs testing framework


If I have a Matcher[A] how do create a Matcher[Iterable[A]] that is satisfied only if each element of the Iterable satisfies the original 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))
    }
  }
}

Solution

  • I certainly don't claim to be a Specs expert, so my code very likely can be much improved upon. In any case, I was able make it work like this:

    
    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))
        }
      }
    }