testLogging.displayGranularity -1 is broken

When I specify a displayGranularity of -1, the defaultValue 2 is used, instead of -1. This is NOT a problem of the check in AbstractTestLogger that is supposed to find the highest granularity automatically. I did a really short debugging and found that when setting displayGranularity to 1, the method DefaultTestLogging.setDisplayGranularity(1) is called exactly one time, when setting displayGranularity to -1, DefaultTestLogging.getDisplayGranularity() is called INSTEAD. The StackTrace was too dynamic and my available time too short to dig further where this comes from.

Works fine for me for regular JUnit tests, where -1 becomes 3. Can you give a concrete and self-contained example where this is not working as expected?

Ah, I almost wrote that I’m not possible to provide that, but found the difference between my showcase project and the real project.

Does work:

test {
    testLogging {
        events 'started'
        displayGranularity = -1
    }
}

Does not work:

test {
    testLogging {
        events 'started'
        displayGranularity -1
    }
}

Does ‘displayGranularity(-1)’ work?

Yes

As does setDisplayGranularity(-1)

Turns out that Groovy parses ‘displayGranularity -1’ as ‘getDisplayGranularity() - 1’, rather than ‘displayGranularity(-1)’. In other words, the ‘=’ cannot be omitted in this case.

Wow, that’s strange. But that also explains my observation while debugging, that the getter is called INSTEAD of the setter. Do you know why this is the case and whether this changes with Gradle 2.0 and thus Groovy 2?

Btw. how is that DSL magic made anyway? In the DefaultTestLogging class I see getter and setter methods, but no method displayGranularity() and as far as I remember, Groovy translates “displayGranularity = 1” to “setDisplayGranularity(1)”, but not “displayGranularity 1”

The ‘displayGranularity’ method is auto-generated by Gradle based on the getter. The idea is to allow the equals sign to be omitted, but it doesn’t work out in this edge case. I don’t think Groovy 2 will make a difference here.

Do you have a starting point where to look at for this auto-generation? I’m curious how this is realized and didn’t find the right spot to look at.

‘org.gradle.api.internal.AsmBackedClassGenerator’ is probably where it happens.