Hi,
Given the following:
def hackyMatcher[T](res: T => MatchResult[Any]): Matcher[T] = new Matcher[T] {
override def apply[S <: T](t: Expectable[S]): MatchResult[S] =
res(t.value).asInstanceOf[MatchResult[S]] // Is the cast here problematic?
}
I can write matchers like:
def beCool = hackyMatcher[Int] {i =>
val str = i.hashCode.toString
str.length must_== 12
str.charAt(3) must_== 'z'
}
I find the matcher above to be really to-the-point.
Without the hacky matcher, you'd have to do something like the following (is there a better way?):
def beCoolWithoutHacks: Matcher[Int] =
be_==(12) ^^ {(_: Int).hashCode.toString.length} and
be_==('z') ^^ {(_: Int).hashCode.toString.charAt(3)}
Or:
def beCoolWithoutHacks2: Matcher[Int] = (
be_==(12) ^^ {(_: String).length} and
be_==('z') ^^ {(_: String).charAt(3)}
) ^^ {(_: Int).hashCode.toString}
Both of the above are way less readable than the hacky matcher, as the logic is reversed, and you need type annotations everywhere.
My question is, should we add hackyMatcher to specs2, or is it just too hacky? Is there an existing, better way to accomplish this in specs2?
Thanks,
Pouria