Skip to content

Add artefact name contract characterization spec#15998

Open
jamesfredley wants to merge 1 commit into
8.0.xfrom
test/artefact-name-precomputation
Open

Add artefact name contract characterization spec#15998
jamesfredley wants to merge 1 commit into
8.0.xfrom
test/artefact-name-precomputation

Conversation

@jamesfredley

Copy link
Copy Markdown
Contributor

Summary

  • add a test-only characterization spec locking in public GrailsClass artefact naming behavior
  • cover controllers, services, domains, and url-mappings, including acronym-heavy names, repeated accessor reads, and repeated wrapper construction
  • assert the framework's actual observed names; no production changes and no timing thresholds

Verification

  • :grails-core:test --tests ArtefactNamePrecomputationSpec
  • :grails-core:test
  • git diff --check

This is an AI-generated starting point that pins the naming contract ahead of any GrailsNameUtils precomputation work.

Assisted-by: opencode:gpt-5.6-sol

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ArtefactNamePrecomputationSpec to 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.

Comment on lines +55 to +59
packageName: BASE_PACKAGE,
propertyName: 'HTMLController',
logicalPropertyName: 'HTML',
naturalName: 'HTMLC ontroller'
],
Comment on lines +79 to +83
packageName: BASE_PACKAGE,
propertyName: 'JSONAPIService',
logicalPropertyName: 'JSONAPI',
naturalName: 'JSONAPIS ervice'
],
Comment on lines +91 to +95
packageName: BASE_PACKAGE,
propertyName: 'URLDomain',
logicalPropertyName: 'URLDomain',
naturalName: 'URLD omain'
],
Comment on lines +136 to +140
packageName: BASE_PACKAGE,
propertyName: 'HTMLController',
logicalPropertyName: 'HTML',
naturalName: 'HTMLC ontroller'
],
Comment on lines +148 to +152
packageName: BASE_PACKAGE,
propertyName: 'JSONAPIService',
logicalPropertyName: 'JSONAPI',
naturalName: 'JSONAPIS ervice'
]
@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 51.1273%. Comparing base (b980413) to head (2af11ac).

Additional details and impacted files

Impacted file tree graph

@@               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     

see 2041 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@testlens-app

testlens-app Bot commented Jul 17, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 2af11ac
▶️ Tests: 7424 executed
⚪️ Checks: 61/61 completed


Learn more about TestLens at testlens.app.

]
}

private GrailsClass grailsClassFor(String artifactType, Class<?> wrapperClass) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 FooController is rejected (ControllerArtefactHandler passes allowAbstract=false)
  • URLDomain without @Entity/@Artefact is rejected by DomainClassArtefactHandler.isArtefactClass (domain detection is annotation/location-based; the name plays no role)
  • a suffix match like HTMLController is accepted by ControllerArtefactHandler.isArtefactClass

/**
* Tests for deterministic GrailsClass naming metadata.
*/
class ArtefactNamePrecomputationSpec extends Specification {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"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'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants