test: raise coverage in grails-data-hibernate7 - #16278
Open
borinquenkid wants to merge 7 commits into
Open
Conversation
AbstractMultipleDataSourceAggregatePersistenceContextInterceptor had no dedicated Spec and sat at 24.5% line coverage despite fanning out lifecycle calls (init/destroy/flush/clear/isOpen/setReadOnly/ setReadWrite/disconnect/reconnect) across every configured data source. New Spec drives its concrete AggregatePersistenceContextInterceptor subclass through a two-datasource HibernateDatastore, raising coverage to 86.8%. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QAjfckcY4EJsxranv1RyGV
HibernateCriteriaBuilder sat at 72.7% line coverage and PredicateGenerator at 83.2%, with several DSL methods (createAlias, exists/notExists with an inline closure, join/lock/cache/readOnly/select hints, eqAll/gtSome/geSome/ ltSome/leSome, notIn, inList, ignoreCase eq) never exercised through the criteria DSL. Adds targeted cases to the existing "for low-level method coverage (JaCoCo line hits)" Direct spec, plus a case driving the documented PredicateGenerator.registerCriterionHandler extension point. HibernateCriteriaBuilder: 72.7% -> 89.6%. PredicateGenerator: 83.2% -> 85.2%. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QAjfckcY4EJsxranv1RyGV
DetachedAssociationFunction (50%) never had a case for the recursive Query.Junction-flattening branch. IdentityEnumType (65.6%) was missing its error/fallback paths in setParameterValues (unloadable class, Class-attribute fallback, missing enumClass), the BIGINT/VARCHAR jdbc type selection branches, getBidiEnumMap's reflection-failure and duplicate-id-warning paths, disassemble/assemble, and nullSafeSet's null branch — all exercised directly through IdentityEnumType's public UserType/ParameterizedType contract methods. DetachedAssociationFunction: 50% -> 100%. IdentityEnumType: 65.6% -> 91.8% (BidiEnumMap: 88.9% -> 100%). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QAjfckcY4EJsxranv1RyGV
setObjectToReadyOnly/setObjectToReadWrite's HibernateProxy-unwrap branches were never hit: canModifyReadWriteState requires the target to already be initialized, and prior tests fetched proxies via getReference() while the entity was still session-managed from an earlier statement, so Hibernate handed back the real instance instead of a proxy. Clearing the session before getReference() forces a genuine lazy proxy, which is then explicitly initialized while remaining a HibernateProxy reference, reaching the unwrap branch in both methods. Also adds cases for the single-argument unwrapProxy/getAssociationProxy/isInitialized/ unwrapIfProxy convenience overloads that delegate to the default proxy handler. GrailsHibernateUtil: 77.9% -> 85.3%. The remaining gap is the annotation-name-string branch in isDomainClass (grails.persistence.Entity and JPA @entity classes compiled in this project already implement GormEntity via the GORM AST transform before that branch is reached) and two TRACE-level log lines — not reachable through this module's public Groovy-compiled surface. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QAjfckcY4EJsxranv1RyGV
prepareCircularManyToMany's composite-identity branch (building join table keys for a self-referential many-to-many owned by an entity with a composite identity) was untested: neither the "reuse existing matching join keys" path nor the "derive keys from property names via the naming strategy" path was exercised. ManyToOneBinder: 78.2% -> 100%. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QAjfckcY4EJsxranv1RyGV
…ectHqlQuery
ChildHibernateDatastore: destroy() (marking destroyed without closing the
parent's shared session factory) had no case.
JpaQueryContext: the aliases-only/parent-only constructor overloads, the
forRoot(aliases, root) static factory, setParent, getAliasedExpression's
parent-delegation when not realized locally, the "{alias}" and
"{alias}.path" token-resolution delegation to a parent context, and
clone() were all untested.
SelectHqlQuery: the max/offset builder-method-set fields branch in
applyQuerySettings/getMax/getOffset (as opposed to the query-args-map
branch already covered), the no-op setReadOnly compatibility method, and
executeQuery's delegation to list() were untested.
ChildHibernateDatastore: 80% -> 100%. SelectHqlQuery: 82.9% -> 100%.
JpaQueryContext: 78.5% -> 95.4%.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QAjfckcY4EJsxranv1RyGV
HibernateGrailsPlugin.doWithSpring() (the plugin descriptor's Spring bean-wiring closure) had 0% coverage. Following the existing repo pattern for testing Plugin subclasses in isolation (see QuartzGrailsPluginSpec), the closure is driven directly through a BeanBuilder against a plain DefaultGrailsApplication and GenericApplicationContext, with no plugin manager or full application bootstrap required. Covers bean-definition registration, the dataSourceNames side effect, the PropertySourcesConfig conversion-service installation branch (including invoking the registered String->Class converter), the domain-class artefact collection, and the no-op onChange() override. HibernateGrailsPlugin (and its doWithSpring closure / anonymous Converter): 0% -> 100%. grails-plugin module overall: 63.7% -> 77.8%. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QAjfckcY4EJsxranv1RyGV
🚨 TestLens detected 1 failed test 🚨Here is what you can do:
Test SummaryCI / Functional Tests (Java 25, indy=false, shard 1) > :grails-test-examples-gsp-sitemesh3:integrationTest
🏷️ Commit: 7fce7d8 Test FailuresEndToEndSpec > async multiple levels of layouts (:grails-test-examples-gsp-sitemesh3:integrationTest in CI / Functional Tests (Java 25, indy=false, shard 1))
Rerun ControlsSelect tests to mute in this pull request:
Reuse successful test results:
Click the checkbox to trigger a rerun:
Learn more about TestLens at testlens.app/docs. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 8.1.x #16278 +/- ##
=============================================
Coverage 29.8834% 29.8834%
Complexity 509 509
=============================================
Files 79 79
Lines 4715 4715
Branches 814 814
=============================================
Hits 1409 1409
Misses 3063 3063
Partials 243 243 🚀 New features to boost your workflow:
|
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
grails-data-hibernate7(both thecoreandgrails-pluginsubprojects) — no production code changes, tests only.AggregatePersistenceContextInterceptor: 24.5% → 86.8% (no dedicated Spec existed for the multi-datasource lifecycle fan-out).HibernateCriteriaBuilder: 72.7% → 89.6%,PredicateGenerator: 83.2% → 85.2% (extended the existing "low-level method coverage" Direct spec: createAlias, exists/notExists closures, eqAll/gtSome/geSome/ltSome/leSome, notIn, inList, ignoreCase eq, plus the documentedPredicateGenerator.registerCriterionHandlerextension point).DetachedAssociationFunction: 50% → 100%,IdentityEnumType: 65.6% → 91.8% (BidiEnumMap→ 100%).GrailsHibernateUtil: 77.9% → 85.3% (proxy-unwrap branches reached by explicitly initializing a Hibernate proxy after clearing the session, plus the single-arg delegate overloads).ManyToOneBinder: 78.2% → 100% (composite-identity join-key derivation for circular many-to-many associations).ChildHibernateDatastore: 80% → 100%,SelectHqlQuery: 82.9% → 100%,JpaQueryContext: 78.5% → 95.4%.HibernateGrailsPlugin: 0% → 100% — added a newHibernateGrailsPluginSpecthat drivesdoWithSpring()through aBeanBuilder, following the existingQuartzGrailsPluginSpecpattern (no plugin manager or full app bootstrap needed).Module totals:
core93.6% → 94.9%,grails-plugin63.7% → 77.8%.A couple of items were deliberately left alone and are not part of this PR:
HibernateQueryConstantsandProjectionPredicateare unreferenced/deprecated dead code — flagged as removal candidates rather than given tests to inflate coverage on code nothing calls.GrailsHibernateUtil/PredicateGeneratoraren't reachable through the public Groovy-compiled API surface in this module.Test plan
./gradlew :grails-data-hibernate7-core:test— full suite green (3101 tests)./gradlew :grails-data-hibernate7:test— full suite green (28 tests)./gradlew :grails-data-hibernate7-core:codeStyle :grails-data-hibernate7:codeStyle— clean🤖 Generated with Claude Code
https://claude.ai/code/session_01QAjfckcY4EJsxranv1RyGV