groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Leonard Brünings <groovy-...@bruenings-it.net>
Subject Get reference to enclosing closure
Date Mon, 20 Nov 2017 20:27:27 GMT
Hi,

I'm Leonard from the Spock framework team. Guillaume suggested that I 
write to the dev-list with this problem.

Some context:

Spock has a method `with(Object, Closure)` in its Specification class 
that sets the object as the delegate of the closure and transforms,
every call inside the closure to an implicit assertion.

given:
       def person = new Person(name: "Peter", age: 28)

expect:
       with(person) {
           name == 'Peter'
           age == 28
       }

This worked fine for properties, however for single methods like 
`contains` it didn't work.

The initial problem is described here 
https://github.com/spockframework/spock/pull/606

Here is the gist:

This snippet

d|ef list = [1, 2] with(list) { contains(1) } |

transforms in AST (simplified) to

|def list = [1, 2] with(list) { SpockRuntime.verifyMethodCondition(this, 
"contains", [1]) } |

then when the AST is written to bytecode it gets transformed again

|def list = [1, 2] with(list) { 
SpockRuntime.verifyMethodCondition(this.getThisObject(), "contains", [1]) }|

The problem is that the `contains` is now invoked on the containing 
`Specification` instead of the `List`.

With the aforementioned PR it was changed to this

|def list = [1, 2] with(list) { 
SpockRuntime.verifyMethodCondition(this.each(groovy.lang.Closure.IDENTITY), 
"contains", [1]) } |

This "fix" now broke the nesting of `with` blocks as described here: 
https://github.com/spockframework/spock/pull/782

Do you have any ideas on how to fix this elegantly?

- Cheers
Leonard

||||||

||


Mime
View raw message