However there was one feature of Concordion that gave us some trouble. Java Concordion fixtures can return objects with public variables that Concordion can use to make assertions. But in Scala you cant really create public class variables. Scala creates public getter and setter methods with the name of the variable and keeps the variable private. This is all done under the hood of Scala so you don't notice it. Now when the Java code of Concordion tries to access those variables it instead finds the getter / setter methods and fails to make the assertion, throwing a very confusing error having found the method of the name of the variable that you were expecting.
Heres an example of the Concordion spec from the Concordion tutorial page, which calls the "split()" method returning the "result" object which has the public variables "firstName" and "lastName". This works fine from Java.
As a work around to this problem the accordion-scala project was created by Tom Malone and is supported by the Concordion creates linking to it from the Concordion website.<span concordion:execute="#result = split(#TEXT)">John Smith</span>
will be broken into first name
<span concordion:assertEquals="#result.firstName">John</span>
and last name
<span concordion:assertEquals="#result.lastName">Smith</span>.
However my collogue, Jun Yamog, a true Scala guru, thought of a much simpler solution.
In the concordion fixture you can specify that the object value that your accessing is in fact a method, and it should be treated as such by simply adding the parenthesise to the end of the call, like so.
Which will work with the following Scala case class.<span concordion:execute="#result = split(#TEXT)">John Smith</span>
will be broken into first name
<span concordion:assertEquals="#result.firstName()">John</span>
and last name
<span concordion:assertEquals="#result.lastName()">Smith</span>.
case class result(firstName: String, lastName: String)
This is a ridiculously subtle work around, using the Scala generated getter/setter methods from Concordion in a way that was not documented to be possible. Thus the use of the accordion-scala port can be avoided.
For some complete code examples checkout this github repo https://github.com/stephennancekivell/concordion_scala_samples
Edit: It can also be done using Java bean properties. Thanks Tom Malone for explaining this. ognl converts the #result.firstName to #result.getFirstName(). That wasnt clear while debugging.
So like this ..
<span concordion:execute="#result = split(#TEXT)">John Smith</span>
will be broken into first name
<span concordion:assertEquals="#result.firstName">John</span>
and last name
<span concordion:assertEquals="#result.lastName">Smith</span>.
Which will work with the following Scala case class.case class result(@BeanProperty firstName:String, @BeanProperty lastName:String)