Unfortunately Java restricts the design of matcher libraries by not allowing operator overloading and new infix operators. In Scala it is possible to improve the readability of assertions a lot. The following code shows some assertions in Scala:
import matcher.Assertion._;
object MatcherTest {
def main(args : Array[String]) : Unit = {
val x = 5;
val varX = variable("x", x);
assertThat(varX.==(5));
assertThat((varX == 6).or(varX == 5));
assertThat((varX == 6) or (varX == 7) or (varX == 8));
val s = "test";
val varS = variable("s", s);
assertThat(varS.==("t"));
assertThat((varS == "tz") or (varS == "rd"));
assertThat((varS == "t") or ((varX == 5) and (varX == 8)));
}
}
This is all valid Scala code. In Scala it is allowed to use regular methods as infix operators.
Actually instead of raising an exception assertThat just prints the error message:
Expected that (((x == 6) or (x == 7)) or (x == 8))
Expected that (s == t)
Expected that ((s == tz) or (s == rd))
Expected that ((s == t) or ((x == 5) and (x == 8)))
The following code block is a basic implementation. Every expression subclass implements a method to pretty print itself and a method to evaluate whether the expectation is met.
object Assertion {
def assertThat(expression : Expression) = {
if (!expression.evaluate) {
println("Expected that "+expression.text);
}
}
def variable[T](name : String, x : T) = new Variable[T](name, x)
protected abstract class Expression {
def evaluate : boolean
def text : String = "("+textInternal+")"
def textInternal : String
def or(expression : Expression) = new Or(this, expression);
}
protected class Variable[T](name : String, x : T) {
def ==(y:T) = new Equals(this, y);
def getX = x;
def text = name;
}
protected class Equals[T](v : Variable[T], x : T) extends Expression {
def evaluate = v.getX == x;
def textInternal = v.text + " == " + x;
}
protected class Or(e1 : Expression, e2 : Expression) extends Expression {
def evaluate = e1.evaluate || e2.evaluate;
def textInternal = e1.text + " or " + e2.text;
}
}
There is still a piece of RY (Repeat Yourself) in the code. In fact I had no idea how to avoid the construction of the named variable. Perhaps some Scala gurus can give me a hint.
No comments:
Post a Comment