Skip to content

Allow declaring mock interactions in @SelfType(Specification) traits#2377

Draft
leonard84 wants to merge 1 commit into
external-mock-interactions-2-interactions-annotationfrom
external-mock-interactions-3-self-type-traits
Draft

Allow declaring mock interactions in @SelfType(Specification) traits#2377
leonard84 wants to merge 1 commit into
external-mock-interactions-2-interactions-annotationfrom
external-mock-interactions-3-self-type-traits

Conversation

@leonard84

Copy link
Copy Markdown
Member

Add a third external-interaction mechanism: a Groovy trait annotated with
@groovy.transform.SelfType(Specification). The self-type guarantees that
this is a Specification wherever the trait is mixed in, so the trait's methods
may declare interactions and create mocks exactly as inside a spec, becoming
reusable helpers that any spec inherits by implementing the trait.

SpockTransform (a global transform) runs before Groovy's trait transform, so it
sees the trait as a plain class with instance-method bodies and rewrites them
against this. Groovy's trait transform then relocates each body into the
$Trait$Helper and rewrites this to the $self parameter (the real spec
instance at runtime). Detection is Traits.isTrait plus a @SelfType value
assignable to Specification; the trait rewriter reuses the external SPI with
guardSpecNotNull=false (the receiver is non-null by construction). The
self-type may be a subclass of Specification; static trait methods cannot
declare interactions (no instance to reach the spec through).

Adds the trait detection and processSpecificationTrait in SpockTransform, the
SelfType AST node, behaviour tests (cardinality, stubbing, mock creation,
self-type subclass, static-method error), and an AST snapshot showing the
relocated $self-based output.

Add a third external-interaction mechanism: a Groovy trait annotated with
`@groovy.transform.SelfType(Specification)`. The self-type guarantees that
`this` is a Specification wherever the trait is mixed in, so the trait's methods
may declare interactions and create mocks exactly as inside a spec, becoming
reusable helpers that any spec inherits by implementing the trait.

SpockTransform (a global transform) runs before Groovy's trait transform, so it
sees the trait as a plain class with instance-method bodies and rewrites them
against `this`. Groovy's trait transform then relocates each body into the
`$Trait$Helper` and rewrites `this` to the `$self` parameter (the real spec
instance at runtime). Detection is `Traits.isTrait` plus a `@SelfType` value
assignable to `Specification`; the trait rewriter reuses the external SPI with
`guardSpecNotNull=false` (the receiver is non-null by construction). The
self-type may be a subclass of `Specification`; static trait methods cannot
declare interactions (no instance to reach the spec through).

Adds the trait detection and `processSpecificationTrait` in `SpockTransform`, the
`SelfType` AST node, behaviour tests (cardinality, stubbing, mock creation,
self-type subclass, static-method error), and an AST snapshot showing the
relocated `$self`-based output.
@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5d09ff23-ede0-4647-b954-e3801f50c3e2

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Member Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@codecov

codecov Bot commented Jun 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 69.23077% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.51%. Comparing base (63a28b9) to head (02937a1).

Files with missing lines Patch % Lines
...va/org/spockframework/compiler/SpockTransform.java 65.21% 5 Missing and 3 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@                                    Coverage Diff                                     @@
##             external-mock-interactions-2-interactions-annotation    #2377      +/-   ##
==========================================================================================
- Coverage                                                   82.53%   82.51%   -0.03%     
- Complexity                                                   4936     4940       +4     
==========================================================================================
  Files                                                         481      481              
  Lines                                                       15454    15478      +24     
  Branches                                                     1990     1999       +9     
==========================================================================================
+ Hits                                                        12755    12771      +16     
- Misses                                                       1993     1998       +5     
- Partials                                                      706      709       +3     
Files with missing lines Coverage Δ
...java/org/spockframework/compiler/AstNodeCache.java 100.00% <100.00%> (ø)
...ramework/compiler/ExternalInteractionRewriter.java 98.07% <100.00%> (ø)
...va/org/spockframework/compiler/SpockTransform.java 86.13% <65.21%> (-4.22%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@testlens-app

testlens-app Bot commented Jun 13, 2026

Copy link
Copy Markdown

✅ All tests passed ✅

🏷️ Commit: 02937a1
▶️ Tests: 96018 executed
⚪️ Checks: 33/33 completed


Learn more about TestLens at testlens.app.

@leonard84 leonard84 self-assigned this Jun 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant