This is an automated email from the ASF dual-hosted git repository.

borinquenkid pushed a commit to branch 
test/document-datamapping-core-transformers
in repository https://gitbox.apache.org/repos/asf/grails-core.git

commit ee5cdd186753e50aced942cf793428aef8978901
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Thu Aug 13 10:56:50 2026 -0500

    Add test coverage for JpaGormEntityTransformation's local transform entry 
point
    
    JpaGormEntityTransformation sat at 14% coverage. The existing spec only
    exercised it indirectly via GlobalJpaEntityTransform, which applies it
    to classes that already carry @jakarta.persistence.Entity - so the
    class's own local, @grails.gorm.annotation.JpaEntity-driven entry point
    (visit(ASTNode[], SourceUnit)) and the branch that actually adds the
    missing @Entity annotation never ran.
    
    Add three specs: a class annotated @JpaEntity without @Entity (proving
    the local path adds the annotation and applies GORM entity
    enhancement), a class already carrying both annotations (proving the
    annotation isn't added twice), and priority() ordering.
    
    Coverage moves 14% -> 60% instruction, ~0% -> 58% branch. The two
    remaining uncovered lines are defensive guards (malformed astNodes
    array, non-matching annotation type) unreachable through any class
    Groovy's own local-transform dispatch would actually produce.
    
    Co-Authored-By: Claude Sonnet 5 <[email protected]>
---
 .../compiler/gorm/JpaEntityTransformSpec.groovy    | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git 
a/grails-datamapping-core/src/test/groovy/org/grails/compiler/gorm/JpaEntityTransformSpec.groovy
 
b/grails-datamapping-core/src/test/groovy/org/grails/compiler/gorm/JpaEntityTransformSpec.groovy
index fbb195b385..227ca43806 100644
--- 
a/grails-datamapping-core/src/test/groovy/org/grails/compiler/gorm/JpaEntityTransformSpec.groovy
+++ 
b/grails-datamapping-core/src/test/groovy/org/grails/compiler/gorm/JpaEntityTransformSpec.groovy
@@ -26,10 +26,22 @@ import spock.lang.Specification
 
 import org.springframework.validation.annotation.Validated
 
+import org.apache.grails.common.compiler.GroovyTransformOrder
 import org.grails.datastore.gorm.GormEntity
 import org.grails.datastore.mapping.model.config.GormProperties
 import org.grails.datastore.mapping.reflect.ClassPropertyFetcher
 
+/**
+ * {@link org.grails.compiler.gorm.GlobalJpaEntityTransform} applies {@link 
JpaGormEntityTransformation}
+ * to every {@code @jakarta.persistence.Entity}-annotated class automatically, 
exercising its
+ * {@code visit(ClassNode, SourceUnit)} entry point - but only ever on a class 
that already carries the
+ * JPA entity annotation, so the branch that adds it never runs that way. The 
local,
+ * {@code @grails.gorm.annotation.JpaEntity}-driven entry point (the other 
{@code visit} overload,
+ * {@code visit(ASTNode[], SourceUnit)}) is a separate, otherwise-untested 
code path: it is what a class
+ * takes when it is annotated {@code @JpaEntity} directly without also being a 
JPA entity, and it is what
+ * actually adds the missing {@code @jakarta.persistence.Entity} annotation 
before delegating to the same
+ * {@code visit(ClassNode, SourceUnit)} logic.
+ */
 class JpaEntityTransformSpec extends Specification {
 
     void 'test the JPA entity transform the entity correctly'() {
@@ -72,5 +84,45 @@ class JpaEntityTransformSpec extends Specification {
         customerClass.getDeclaredMethod('removeFromRelated', Object)
         customerClass.getDeclaredMethod('removeFromRelated', 
Object).isAnnotationPresent(Generated)
     }
+
+    void 'a class annotated with @JpaEntity but not 
@jakarta.persistence.Entity is made a GORM entity and gets the JPA annotation 
added'() {
+        given: 'a class using the local, annotation-driven transform entry 
point instead of the global one'
+        def productClass = new GroovyClassLoader().parseClass('''
+            import grails.gorm.annotation.JpaEntity
+
+            @JpaEntity
+            class Product {
+                Long myId
+                String name
+            }
+        ''')
+
+        expect: 'the transform added the missing @jakarta.persistence.Entity 
annotation itself'
+        productClass.getAnnotation(jakarta.persistence.Entity)
+
+        and: 'the same GORM entity enhancement as the globally-triggered path 
was applied'
+        GormEntity.isAssignableFrom(productClass)
+    }
+
+    void 'a class already annotated with @jakarta.persistence.Entity is not 
annotated a second time'() {
+        given: 'a class carrying both annotations, so the local transform 
entry point runs but the class already has the JPA annotation'
+        def alreadyJpaClass = new GroovyClassLoader().parseClass('''
+            import grails.gorm.annotation.JpaEntity
+
+            @JpaEntity
+            @jakarta.persistence.Entity
+            class AlreadyJpaProduct {
+                Long myId
+            }
+        ''')
+
+        expect:
+        alreadyJpaClass.getDeclaredAnnotations().findAll { it.annotationType() 
== jakarta.persistence.Entity }.size() == 1
+    }
+
+    void 'priority orders the transform relative to the dirty-check 
transform'() {
+        expect:
+        new JpaGormEntityTransformation().priority() == 
GroovyTransformOrder.JPA_GORM_ENTITY_ORDER
+    }
 }
 

Reply via email to