Add proxy package test coverage and fix IntelliJ inspections in grails-datamapping-core - #16155
Add proxy package test coverage and fix IntelliJ inspections in grails-datamapping-core#16155borinquenkid wants to merge 5 commits into
Conversation
GroovyProxyFactory and ProxyInstanceMetaClass had no tests in this module despite implementing the core Groovy-based proxy contract used outside Hibernate/Neo4j. Also picks up a CodeNarc auto-fix replacing a fully-qualified @CompileDynamic annotation with an import. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Mark instance-state-free helper methods static and replace the deprecated Class.newInstance() with getDeclaredConstructor().newInstance(). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Make the never-reassigned session/key fields final, suppress the unchecked-generics warning inherent to MetaClass.getTheClass()'s raw Class return type, fill in missing Javadoc tag descriptions on invokeMethod, and switch to switch-expressions for getProperty/ setProperty/getAttribute. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR improves grails-datamapping-core’s Groovy proxy support by adding missing unit coverage for the proxy implementation and applying a set of code adjustments aimed at addressing IntelliJ inspection warnings.
Changes:
- Added new Spock specs covering
GroovyProxyFactoryandProxyInstanceMetaClassbehavior (lazy resolution, proxy metadata, delegation paths). - Refactored
ProxyInstanceMetaClass(final fields, Javadoc tag descriptions, switch expressions, warning suppression) to reduce inspection noise and modernize code. - Refactored
GroovyProxyFactoryto replace deprecated instantiation and adjust helper methods/annotations (with a potential API-compatibility concern noted in comments).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/proxy/ProxyInstanceMetaClassSpec.groovy | Adds focused unit coverage for proxy metaclass behavior (method/property/attribute resolution semantics). |
| grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/proxy/GroovyProxyFactorySpec.groovy | Adds unit coverage for proxy factory creation/unwrap/identifier/initialization paths. |
| grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/proxy/ProxyInstanceMetaClass.java | Cleans up implementation details (final fields, switch refactor, warning suppression, Javadoc completeness). |
| grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/proxy/GroovyProxyFactory.groovy | Updates proxy factory internals (constructor instantiation, annotation import usage) and changes helper methods to static (flagged). |
Suppressed comments (2)
grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/proxy/GroovyProxyFactory.groovy:128
- Same concern here: making a
protectedmethodstaticbreaks subclasses that might override it to customize proxy metaClass installation. Consider keeping it non-static and suppressing IntelliJ’s “method may be static” inspection instead.
@CompileDynamic
protected static void setMetaClassDynamic(Object proxy, MetaClass proxyMc) {
proxy.setMetaClass(proxyMc)
}
grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/proxy/GroovyProxyFactory.groovy:170
- Making this
protectedmethodstaticis also a potential breaking change for subclasses (cannot be overridden). If the goal is just to satisfy IntelliJ’s inspection, keep it as an instance method and suppressGrMethodMayBeStaticon the method.
protected static MetaClass unwrapHandleMetaClass(MetaClass mc) {
if (mc instanceof HandleMetaClass) {
return ((HandleMetaClass) mc).getAdaptee()
}
return mc
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
The concern regarding the conversion of If these changes were made solely to satisfy static analysis inspections, it is recommended to revert them to instance methods and suppress the inspection, consistent with existing patterns in the repository. grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/proxy/GroovyProxyFactory.groovy |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 8.1.x #16155 +/- ##
==================================================
+ Coverage 53.1444% 53.1846% +0.0402%
- Complexity 19371 19406 +35
==================================================
Files 2080 2080
Lines 99000 98991 -9
Branches 17363 17355 -8
==================================================
+ Hits 52613 52648 +35
+ Misses 38828 38792 -36
+ Partials 7559 7551 -8
🚀 New features to boost your workflow:
|
Making protected getIdDynamic/setMetaClassDynamic/unwrapHandleMetaClass static would silently break binary compatibility for any subclass overriding them, since static methods aren't polymorphic. Suppress the IntelliJ inspection instead, matching the existing @SuppressWarnings('GrMethodMayBeStatic') convention used elsewhere in the repo. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Cover the previously-untested target property/attribute cases in getProperty/getAttribute, the already-initiated branch of the class/domainClass ternary, and the remaining argument-shape branches of the setMetaClass special case in invokeMethod/setProperty. File is now fully line- and branch-covered. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (1)
grails-datamapping-core/src/test/groovy/org/grails/datastore/gorm/proxy/ProxyInstanceMetaClassSpec.groovy:103
- The test name says the call “delegates” for getTarget/initialize, but ProxyInstanceMetaClass.invokeMethod returns getProxyTarget() directly for those method names (no delegate.invokeMethod call). Removing the unused delegate stub and renaming the test avoids misleading future readers.
void "invokeMethod resolves the target and delegates for getTarget/initialize"() {
given:
ProxyInstanceMetaClass metaClass = newMetaClass()
session.retrieve(ProxyInstanceTestTarget, 11L) >> target
delegate.invokeMethod(target, methodName, [] as Object[]) >> target
✅ All tests passed ✅Test SummaryCI / Build Grails-Core (macOS JDK 21) > :grails-wrapper:test
🏷️ Commit: 55d4b81 Learn more about TestLens at testlens.app. |
Summary
GroovyProxyFactoryandProxyInstanceMetaClassingrails-datamapping-core, which previously had none in this module despite implementing the core Groovy-based proxy contract used outside Hibernate/Neo4j.static, replaces deprecatedClass.newInstance()withgetDeclaredConstructor().newInstance(), makes never-reassigned fieldsfinal, suppresses the unchecked-generics warning inherent toMetaClass.getTheClass()'s raw return type, and fills in missing Javadoc tag descriptions.Test plan
./gradlew :grails-datamapping-core:test --tests "org.grails.datastore.gorm.proxy.*"— 29 tests pass./gradlew :grails-datamapping-core:test— full module suite passes./gradlew :grails-datamapping-core:codeStyle— no Checkstyle/CodeNarc violations🤖 Generated with Claude Code