This is an automated email from the ASF dual-hosted git repository.
borinquenkid pushed a commit to branch test/artefact-name-precomputation
in repository https://gitbox.apache.org/repos/asf/grails-core.git
The following commit(s) were added to
refs/heads/test/artefact-name-precomputation by this push:
new bfe84593dd Address jdaugherty review feedback on artefact naming
characterization spec
bfe84593dd is described below
commit bfe84593dd2ab8a1808372781fdbae39363ccaf0
Author: Walter Duque de Estrada <[email protected]>
AuthorDate: Mon Jul 27 12:33:16 2026 -0500
Address jdaugherty review feedback on artefact naming characterization spec
Copilot's 5 inline comments claiming the acronym naturalName expectations
were wrong (e.g. 'HTMLC ontroller') are false positives - verified by
running the spec: GrailsNameUtils.getNaturalName genuinely produces those
values, and jdaugherty's review already confirmed this. No change needed
there.
jdaugherty's own feedback was substantive and is addressed here:
- Rename ArtefactNamePrecomputationSpec -> ArtefactNamingContractSpec:
"precomputed" was aspirational, since nothing in the spec exercises
actual precomputation, only naming stability.
- Add a comment above the acronym-heavy naturalName assertions explaining
the quirky-but-intentional GrailsNameUtils splitting behavior they pin,
so a future reader doesn't "fix" the expectations or the algorithm
without realizing this spec exists to catch exactly that change.
- Add three cases exercising the artefact detection contract
(ArtefactHandler#isArtefactClass), which the original spec bypassed
entirely by constructing GrailsClass wrappers directly: an abstract
controller is rejected (ControllerArtefactHandler's allowAbstract is
false), a suffix-matching concrete controller is accepted, and a
domain-named class with no @Entity/@Artefact annotation is rejected by
DomainClassArtefactHandler - this is the part a naming precomputation
refactor is most likely to disturb, and the prior spec gave it no
coverage at all.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
---
...ec.groovy => ArtefactNamingContractSpec.groovy} | 33 ++++++++++++++++++++--
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git
a/grails-core/src/test/groovy/org/grails/core/ArtefactNamePrecomputationSpec.groovy
b/grails-core/src/test/groovy/org/grails/core/ArtefactNamingContractSpec.groovy
similarity index 83%
rename from
grails-core/src/test/groovy/org/grails/core/ArtefactNamePrecomputationSpec.groovy
rename to
grails-core/src/test/groovy/org/grails/core/ArtefactNamingContractSpec.groovy
index 4c383dea6d..f04c7bae60 100644
---
a/grails-core/src/test/groovy/org/grails/core/ArtefactNamePrecomputationSpec.groovy
+++
b/grails-core/src/test/groovy/org/grails/core/ArtefactNamingContractSpec.groovy
@@ -19,21 +19,31 @@
package org.grails.core
import grails.core.GrailsClass
+import org.grails.core.artefact.ControllerArtefactHandler
+import org.grails.core.artefact.DomainClassArtefactHandler
import spock.lang.Specification
import spock.lang.Unroll
/**
- * Tests for deterministic GrailsClass naming metadata.
+ * Tests for deterministic GrailsClass naming metadata, and for the artefact
detection
+ * contract (ArtefactHandler#isArtefactClass) that a naming precomputation
refactor is
+ * most likely to disturb.
*/
-class ArtefactNamePrecomputationSpec extends Specification {
+class ArtefactNamingContractSpec extends Specification {
private static final String BASE_PACKAGE = 'org.grails.core'
@Unroll
- void "naming contract for #entry.label is precomputed"() {
+ void "#entry.label naming metadata matches the observed contract"() {
given:
GrailsClass grailsClass = grailsClassFor(entry.artifactType,
entry.wrapperClass)
+ // GrailsNameUtils.getNaturalName splits into words at each
lower-to-upper case
+ // transition, but an acronym run (HTML, JSONAPI, URL) absorbs the
first letter
+ // of the following word before that transition triggers - hence
'HTMLC ontroller'
+ // (not 'HTML Controller') and 'JSONAPIS ervice' (not 'JSONAPI
Service') below.
+ // These are pinned intentionally: don't "fix" these expectations, or
the
+ // algorithm, without knowing this spec exists to catch exactly that
change.
expect:
grailsClass.name == entry.name
grailsClass.shortName == entry.shortName
@@ -186,6 +196,21 @@ class ArtefactNamePrecomputationSpec extends Specification
{
]
}
+ void "ControllerArtefactHandler accepts a concrete class whose name ends
with the controller suffix"() {
+ expect:
+ new ControllerArtefactHandler().isArtefactClass(HTMLController)
+ }
+
+ void "ControllerArtefactHandler rejects an abstract class even when the
name matches the controller suffix"() {
+ expect:
+ !new ControllerArtefactHandler().isArtefactClass(AbstractFooController)
+ }
+
+ void "DomainClassArtefactHandler rejects a class named like a domain class
but carrying no domain annotation"() {
+ expect:
+ !new DomainClassArtefactHandler().isArtefactClass(URLDomain)
+ }
+
private GrailsClass grailsClassFor(String artifactType, Class<?>
wrapperClass) {
switch (artifactType) {
case 'controller':
@@ -204,6 +229,8 @@ class ArtefactNamePrecomputationSpec extends Specification {
class HTMLController {}
+abstract class AbstractFooController {}
+
class PayRollController {}
class JSONAPIService {}