Illiax
Illiax

Reputation: 992

ScalaTest own matcher, use of word not

So at start i had

def parseB(string : String)(implicit context : Context) : Float = parseAll(gexp, string).get.eval(context).left.get

and then in the test

implicit var context = Context()
parseB("False") should be(false)
parseB("False") should not be(true)

then i wrote a custom matcher

case class ReflectBooleanMatcher(value : Boolean)(implicit context : Context) extends Matcher[String] with ExpressionParser{
  def parseB(string : String) : Boolean = parseAll(gexp, string).get.eval(context).right.get
  def apply (string : String) : MatchResult = 
      MatchResult(parseB(string) == value, "", "")
}

so my test turned to

"False" should reflectBoolean(false)

but

"False" should not reflectBoolean(true)

Breaks- Of course, i never said it could match negative. So how do i say it?

Upvotes: 3

Views: 872

Answers (3)

Mikaël Mayer
Mikaël Mayer

Reputation: 10701

The trick is to declare an implicit class to consider "reflect" as a method of the result of ("False"shouldnot) of type ResultOfNotWordForAny[String].

def parseB(string : String)(implicit context : Context) : Float = parseAll(gexp, string).get.eval(context).left.get

implicit var context = Context()
parseB("False") should be(false)
parseB("False") should not be(true)

// Declares an implicit class for applying after not. Note the use of '!='
implicit class ReflectShouldMatcher(s: ResultOfNotWordForAny[String]) {
  def reflect(value: Boolean) = s be(BeMatcher[String] {
    left => MatchResult(parseB(left) != value, "", "")
  })
}
// Declares an explicit method for applying after should. Note the use of '=='
def reflect(right: Boolean) = Matcher[String]{ left =>
            MatchResult(parseB(left) == right, "", "")}

// Now it works. Note that the second example can be written with or wo parentheses.
"False" should reflect(false)
"False" should not reflect true

Upvotes: 4

Noah
Noah

Reputation: 13959

You don't need to change your matcher, I think you just need some parentheses:

"False" should ReflectBooleanMatcher(false)
"False" should not(ReflectBooleanMatcher(true)) //works!

UPDATE

Per @Vidya's comments if you define reflectBoolean as:

def reflectBoolean(value: Boolean) = new ReflectBooleanMatcher(value)

Then you can use 'BDD' style syntax, and the parentheses make this work:

"False" should reflectBoolean(false)
"False" should not(reflectBoolean(true))

Upvotes: 5

Vidya
Vidya

Reputation: 30310

I'm just going to rip off the documentation:

trait CustomMatchers {    
  class ReflectBooleanMatcher(value: Boolean)(implicit context : Context) extends Matcher[String] with ExpressionParser {
     def parseB(string: String) : Boolean = parseAll(gexp, string).get.eval(context).right.get
     def apply(string: String) : MatchResult = MatchResult(parseB(string) == value, "", "")      
  }

  def reflectBoolean(value: Boolean) = new ReflectBooleanMatcher(value)
}

Now try using the reflectBoolean method.

Upvotes: 1

Related Questions