Add artefact name contract characterization spec#15998
Conversation
Assisted-by: opencode:gpt-5.6-sol
There was a problem hiding this comment.
Pull request overview
Adds a new Spock characterization spec to lock in the current GrailsClass artefact naming outputs (controllers/services/domains/urlMappings) and stability across repeated accessor reads and wrapper re-construction, to protect future GrailsNameUtils precomputation work.
Changes:
- Introduce
ArtefactNamePrecomputationSpecto assert deterministic naming fields (name,shortName,fullName,packageName,propertyName,logicalPropertyName,naturalName) for representative artefact classes. - Add repeated-read and repeated-wrapper-construction checks to ensure naming accessors remain stable.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| packageName: BASE_PACKAGE, | ||
| propertyName: 'HTMLController', | ||
| logicalPropertyName: 'HTML', | ||
| naturalName: 'HTMLC ontroller' | ||
| ], |
| packageName: BASE_PACKAGE, | ||
| propertyName: 'JSONAPIService', | ||
| logicalPropertyName: 'JSONAPI', | ||
| naturalName: 'JSONAPIS ervice' | ||
| ], |
| packageName: BASE_PACKAGE, | ||
| propertyName: 'URLDomain', | ||
| logicalPropertyName: 'URLDomain', | ||
| naturalName: 'URLD omain' | ||
| ], |
| packageName: BASE_PACKAGE, | ||
| propertyName: 'HTMLController', | ||
| logicalPropertyName: 'HTML', | ||
| naturalName: 'HTMLC ontroller' | ||
| ], |
| packageName: BASE_PACKAGE, | ||
| propertyName: 'JSONAPIService', | ||
| logicalPropertyName: 'JSONAPI', | ||
| naturalName: 'JSONAPIS ervice' | ||
| ] |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 8.0.x #15998 +/- ##
================================================
+ Coverage 0 51.1273% +51.1273%
- Complexity 0 17607 +17607
================================================
Files 0 2041 +2041
Lines 0 95493 +95493
Branches 0 16587 +16587
================================================
+ Hits 0 48823 +48823
- Misses 0 39385 +39385
- Partials 0 7285 +7285 🚀 New features to boost your workflow:
|
✅ All tests passed ✅🏷️ Commit: 2af11ac Learn more about TestLens at testlens.app. |
| ] | ||
| } | ||
|
|
||
| private GrailsClass grailsClassFor(String artifactType, Class<?> wrapperClass) { |
There was a problem hiding this comment.
Constructing DefaultGrailsControllerClass/DefaultGrailsServiceClass/etc. directly bypasses artefact detection entirely — these constructors accept any class (new DefaultGrailsControllerClass(URLDomain) would work just as well). So this spec pins the naming metadata contract, but not the detection contract (ArtefactHandler.isArtefact), which is the part a precomputation refactor is most likely to disturb.
Consider adding cases that exercise the handlers, e.g.:
- an abstract
FooControlleris rejected (ControllerArtefactHandlerpassesallowAbstract=false) URLDomainwithout@Entity/@Artefactis rejected byDomainClassArtefactHandler.isArtefactClass(domain detection is annotation/location-based; the name plays no role)- a suffix match like
HTMLControlleris accepted byControllerArtefactHandler.isArtefactClass
| /** | ||
| * Tests for deterministic GrailsClass naming metadata. | ||
| */ | ||
| class ArtefactNamePrecomputationSpec extends Specification { |
There was a problem hiding this comment.
"Precomputation" in the spec name is aspirational — nothing here asserts precomputation; the repeated-read/repeated-construction tests pin stability only. That's a fine pre-refactor baseline, but consider a name that says what it locks in, e.g. ArtefactNamingContractSpec, so it doesn't read as if precomputed behavior already exists.
| packageName: BASE_PACKAGE, | ||
| propertyName: 'HTMLController', | ||
| logicalPropertyName: 'HTML', | ||
| naturalName: 'HTMLC ontroller' |
There was a problem hiding this comment.
For the record: expectations like 'HTMLC ontroller' / 'JSONAPIS ervice' / 'URLD omain' are correct characterizations — GrailsNameUtils.getNaturalName genuinely splits acronym-prefixed names after the last uppercase letter. Worth a brief code comment noting these pin known-quirky behavior intentionally, so a future reader doesn't "fix" the expectations (or the algorithm) without realizing this spec exists to catch exactly that change.
Summary
Verification
This is an AI-generated starting point that pins the naming contract ahead of any GrailsNameUtils precomputation work.