Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ByteBuddyMockFactory adds
@Internal
annotation to Groovy MOP methods (
#1729) The Groovy 3 & 4 runtime expects to have the `@Internal` annotation on the MOP methods from `GroovyObject`. That `AbstractCallSite.createGroovyObjectGetPropertySite()` processes it as `GroovyObject`. So the `ByteBuddyMockFactory` now adds the `@Internal` annotation to the intercepted MOP methods. After that the "Unable to access protected constant when spying instances" problems are gone, because we take the normal Groovy route. Also some strange inconsistencies for Groovy 2 <=> 3,4 are now gone, but a new inconsistency appeared Groovy 4 prefers is over get for boolean. But this is not a Spock issue, because in Groovy only code the same thing happens. See tests in JavaMocksForGroovyClasses. This fixes #1501, #1452, #1608 and #1145. Co-authored-by: Björn Kautler <Bjoern@Kautler.net> Co-authored-by: Leonard Brünings <leonard.bruenings@gradle.com>
- Loading branch information
1 parent
7b8863a
commit 12682bb
Showing
10 changed files
with
280 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
102 changes: 102 additions & 0 deletions
102
spock-specs/src/test/groovy/org/spockframework/mock/AccessProtectedPropsSpec.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* Copyright 2023 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.spockframework.mock | ||
|
||
import spock.lang.Issue | ||
import spock.lang.Specification | ||
import spock.lang.Stepwise | ||
|
||
@Stepwise | ||
class AccessProtectedPropsSpec extends Specification { | ||
|
||
/** | ||
* The problem with https://github.com/spockframework/spock/issues/1501 is that the ByteBuddyMockFactory overrides | ||
* the {@code getProperty(String)} method from GroovyObject without having the {@code groovy.transform.Internal} | ||
* annotation. Therefore {@code org.codehaus.groovy.runtime.callsite.AbstractCallSite.createGroovyObjectGetPropertySite(java.lang.Object)} | ||
* takes another code path. | ||
*/ | ||
@Issue("https://github.com/spockframework/spock/issues/1501") | ||
@Issue("https://github.com/spockframework/spock/issues/1608") | ||
def "Access protected const should be accessible in Groovy 3&4 Issue #1501"() { | ||
when: | ||
AccessProtectedSubClass mySpy = Spy() | ||
then: | ||
mySpy.accessStaticFlag() | ||
} | ||
|
||
@Issue("https://github.com/spockframework/spock/issues/1501") | ||
@Issue("https://github.com/spockframework/spock/issues/1608") | ||
def "Access protected should be accessible in Groovy 3&4 Issue #1501"() { | ||
when: | ||
AccessProtectedSubClass mySpy = Spy() | ||
then: | ||
mySpy.accessNonStaticFlag() | ||
} | ||
|
||
/** | ||
* This feature must run after the {@code Access protected const should be accessible in Groovy 3&4 Issue #1501}, | ||
* otherwise the MetaClass gets cached in the GroovyRuntime, therefore we need the {@code @Stepwise}. | ||
*/ | ||
def "Access protected fields via access methods without spy"() { | ||
when: | ||
AccessProtectedSubClass myNonSpy = new AccessProtectedSubClass() | ||
then: | ||
myNonSpy.accessNonStaticFlag() | ||
myNonSpy.accessStaticFlag() | ||
} | ||
|
||
@Issue("https://github.com/spockframework/spock/issues/1501") | ||
def "Access protected fields should be accessible in Groovy 3&4 with Java class Issue #1501"() { | ||
when: | ||
AccessProtectedJavaSubClass mySpy = Spy() | ||
then: | ||
mySpy.accessNonStaticFlag() | ||
} | ||
|
||
@Issue("https://github.com/spockframework/spock/issues/1452") | ||
def "Access protected fields Issue #1452"() { | ||
when: | ||
AccessProtectedSubClass mySpy = Spy() | ||
then: | ||
mySpy.nonStaticFlag | ||
mySpy.staticFlag | ||
} | ||
|
||
def "Access protected fields without spy"() { | ||
when: | ||
AccessProtectedSubClass myNonSpy = new AccessProtectedSubClass() | ||
then: | ||
myNonSpy.nonStaticFlag | ||
myNonSpy.staticFlag | ||
} | ||
} | ||
|
||
class AccessProtectedBaseClass { | ||
protected static boolean staticFlag = true | ||
protected boolean nonStaticFlag = true | ||
} | ||
|
||
class AccessProtectedSubClass extends AccessProtectedBaseClass { | ||
boolean accessNonStaticFlag() { | ||
return nonStaticFlag | ||
} | ||
|
||
@SuppressWarnings('GrMethodMayBeStatic') | ||
boolean accessStaticFlag() { | ||
return staticFlag | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
spock-specs/src/test/groovy/org/spockframework/mock/MockMapDelegateSpec.groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* Copyright 2023 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.spockframework.mock | ||
|
||
import spock.lang.Issue | ||
import spock.lang.Specification | ||
|
||
class MockMapDelegateSpec extends Specification { | ||
|
||
@Issue("https://github.com/spockframework/spock/issues/1145") | ||
def "Mock a Map delegate Issue #1145"() { | ||
given: | ||
MapDelegate ctx = Mock() | ||
|
||
expect: | ||
ctx.size() == 0 | ||
ctx.foo == null | ||
} | ||
} | ||
|
||
class MapDelegate implements Map<String, Object> { | ||
@Delegate | ||
private Map<String, Object> target | ||
|
||
MapDelegate(Map entries) { | ||
this.target = entries | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.