Search code examples
scalaspecs2

Combining forall and ^^^ in specs2 matchers


In Specs2, the forall and foreach methods can be used to convert a matcher for a single item into a matcher on a sequence of items of the original type, and ^^^ can be used to preprocess the actual and expected values before matching them. But how can I combine the two?

I've tried

((s must myMatcher(x)) ^^^ (_.toLowerCase)).forall(collection)

but that doesn't compile.


Solution

  • The problem actually has nothing to do with forall. After moving the forall to the front to increase readability (which isn't necessary), the code can be made to compile by rewriting it as follows:

    forall(collection) ((_: String) must myMatcher(x) ^^^ (_.toLowerCase))
    

    and this can be worked out by reading the specs2 documentation in the section headed "With sequences", and looking at the types involved.

    Also, the matcher needs to be a subclass of org.specs2.matcher.AdaptableMatcher. If you're writing your own matcher you'll need to manually subclass this class yourself, because specs2 can't know what your matcher is doing and magically adapt it automatically. An example of a class subclassing AdaptableMatcher is org.specs2.matcher.BeTypedEqualTo.

    In the particular case of

    myMatcher(x) ^^^ (_.toLowerCase)
    

    this fragment can be shortened and made more readable and declarative by replacing it with:

    (myMatcher(x) ignoreCase)
    

    if myMatcher(x) has type AdaptableMatcher[Any] and converts its values to compare to strings.