Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Code constraint argument verification fails when a closure is used inside #994

Open
mutyonok opened this issue Apr 25, 2019 · 4 comments

Comments

Projects
None yet
3 participants
@mutyonok
Copy link

commented Apr 25, 2019

Issue description

After upgrade to spock 1.3-groovy-2.5 and changing argument verification code constraint blocks according to docs (a check per line without assert or &&), tests with closures inside constraint blocks are failing.

How to reproduce

  • add mock interaction check with argument code constraint
  • add a check with a closure inside that code constraint block
    Result:
  • invocation is not found (see gist output)

Link to a gist or similar (optional)

https://gist.github.com/mutyonok/609373367161a0281a494863f4778a2a

Additional Environment information

Java/JDK

1.8.0_201

Groovy version

2.5.3

Build tool version

Gradle

5.3.1

Operating System

macOS X Mojave

IDE

IntelliJ IDEA 2019.1 (Ultimate Edition)
Build #IU-191.6183.87, built on March 27, 2019
JRE: 1.8.0_152-release-991-b1 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
macOS 10.14.4

Build-tool dependencies used

Gradle/Grails

testCompile "org.spockframework:spock-core:1.3-groovy-2.5"

@mutyonok mutyonok changed the title Code constraint argument verification fails when a closure is used inside [Bug] Code constraint argument verification fails when a closure is used inside Apr 25, 2019

@leonard84 leonard84 added the bug label Apr 25, 2019

@leonard84

This comment has been minimized.

Copy link
Member

commented Apr 25, 2019

  def "match code argument with inner closure"() {
    List list = Mock()

    when:
    list.add(['foo'])
    then:
    1 * list.add({ outer -> outer.any{ it.length() > 1 } })
  }

The problem seems to be that the inner closure is also treated as a condition closure, which in turn causes it to return null. This becomes even more obvious if the inner condition actually fails, since then it renders as a Condition not satisfied.

@mutyonok

This comment has been minimized.

Copy link
Author

commented Apr 25, 2019

Nice example. Any ideas how hard would it be to fix?

@tommyli

This comment has been minimized.

Copy link

commented Apr 26, 2019

Also verified code from leonard84 fails only in Spock 1.3 on both Groovy 2.4. and 2.5 (1.3-groovy-2.4 and 1.3-groovy-2.5 respectively). Passes on 1.2-groovy-2.4 and 1.2-groovy-2.5.

Here's a workaround (which also proves the issue has something to do with using closures inside a closure argument constraint.):

  def "match code argument with inner closure"() {
    List list = Mock()
    def innerPredicate = { it.length() > 1 }

    when:
    list.add(['foo'])

    then:
//    1 * list.add({ outer -> outer.any { it.length() > 1 } })
    1 * list.add({ outer -> outer.any(innerPredicate) })
  }
@leonard84

This comment has been minimized.

Copy link
Member

commented Apr 26, 2019

I don't really know how hard it will be, but it's in a tricky part of the https://github.com/spockframework/spock/blob/master/spock-core/src/main/java/org/spockframework/compiler/DeepBlockRewriter.java introduced by 1a84301
It will be complicated to get it to work right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.