As a Kotlin/Java programmer who does not speak Groovy, I wonder what language feature the Spock framework uses for its "condition testing" or in other words, what is missing in Kotlin to archive the same. I'm referring to this
def test() {
// ...
then:
foo == 3
bar == "a"
}
My guess is that the code block with the assertions is passed as an argument to the function then()
which somehow accesses the Groovy interpreter to run the block statement by statement so that it can check if the result is true
before continuing with the next statement. Or is there a Groovy language feature that makes it easier?
Spock syntax is valid Groovy syntax. For example, then:
is just a label. The way Spock works its magic is by - and I am going to simplify here - registering itself in the Groovy compiler in order to apply AST (abstract syntax tree) transformations on Spock specs.
Groovy compilation has several phases of AST transformations. Basically, developers can hook into each one of them, registering transformers. AFAIK, Spock only focuses on a single phase named SEMANTIC_ANALYSIS
, see here:
@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
public class SpockTransform implements ASTTransformation {
// ...
}
By transforming Groovy code into a way more sophisticated series of annotations, (nested) method calls and other language elements, it implements its magic and transforms the Spock DSL into something which can be executed in a JVM with Groovy runtime. If you are interested, just look in the target/test-classes directory of your Maven or Gradle Spock module and open some class files with a good decompiler like the one integrated in IntelliJ IDEA, called Fernflower. But do expect your head to explode when first looking at it. I only have taken a few cursory glances at it and am amazed, not pretending to even begin to understand most of it in depth. But hey - you asked, and I am replying. 😉
I do not speak Kotlin, but it seems as if in Kotlin you mostly use lambdas and extension functions instead of AST transformations in order to create a DSL.