Skip to content

Run unconditional sub-recipes from getRecipeList() and keep cleanups local to the changed element - #1230

Merged
timtebeek merged 3 commits into
mainfrom
tim/unconditional-sub-recipes
Oct 25, 2026
Merged

timtebeek merged 3 commits into
mainfrom
tim/unconditional-sub-recipes

Conversation

@timtebeek

@timtebeek timtebeek commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Several recipes queued ChangeType-style sub-recipes through doAfterVisit for every file they visited, or ran whole-file cleanups (LambdaBlockToExpression, RemoveUnusedImports) that also rewrote code the recipe never touched. Sub-recipes that only act on their own matches belong in getRecipeList(), and cleanups should stay limited to the element the recipe changed.

Moved to getRecipeList(). Each of these sub-recipes is gated on the same type the recipe's precondition checks, so the scope stays the same:

  • UpdateBeforeAfterAnnotations: the four lifecycle ChangeTypes. The visitor is now just RemoveRedundantJUnit4LifecycleAnnotations, which still runs first because a recipe's own visitor runs before its recipe list.
  • UseWiremockExtension: ChangeType(WireMockRule, WireMockExtension).
  • ReplaceArquillianInSequenceAnnotation: ChangeType(InSequence, Order).
  • MockUtilsToStatic: ChangeMethodTargetToStatic. It used to run from visitCompilationUnit, so Java files only.

Local instead of whole-file.

  • AssertThrowsOnLastStatement and ExpectedExceptionToAssertThrows run LambdaBlockToExpression only on the assertThrows call they produced. JMockitMockUpToMockito runs it only on the method it rewrote. AssertThrowsOnLastStatement keeps the old Java-only behaviour, because LambdaBlockToExpression's JavaFileChecker does not apply when its visitor runs on a subtree.
  • JUnitFailToAssertJFail uses maybeRemoveImport on org.junit.jupiter.api.Assertions instead of RemoveUnusedImports.
  • RemoveDoNothingForDefaultMocks calls maybeRemoveImport for each type, method owner and field owner that the removed stubbing referenced, instead of RemoveUnusedImports.
  • RemoveObsoleteRunners and JUnitParamsRunnerToParameterized remove the @RunWith annotation from the class they visit, instead of queuing a file-wide RemoveAnnotation visitor per class. RemoveObsoleteRunners stays a visitor, because MockitoJUnitRunnerToExtension calls its getVisitor().
  • AssertToAssertions used to queue one ChangeMethodTargetToStatic per Assert call. It now collects the method names and queues one per distinct name at the end of the file.

Skipped

  • MigrateJUnitTestCase: its precondition excludes TestCases that override run(TestResult). Its ChangeTypes and UseStaticImports would also run on those files, and on any file using Jupiter Assertions, from the recipe list.
  • TestRuleToTestInfo: ChangeType(org.junit.Before, BeforeEach) would then run on every file using @Before, not just those with a TestName rule.
  • AnyToNullable: the sub-recipes are gated on the scanning recipe's accumulator (a mockito-all dependency somewhere), which a recipe list cannot see.
  • AssertToAssertions matchUnknownTypes = true: kept on purpose. missingTypeInfo and migratesAssertStatementsWithMissingTypeInfo rely on it for unresolved JUnit 4 types.

Verified with ./gradlew test on the tests of every touched recipe and the composites that include them: JUnit5MigrationTest, Mockito1to{3,4,5}MigrationTest, JunitMockitoUpgradeIntegrationTest, MockitoJUnitRunnerToExtensionTest, ArquillianJUnit4ToArquillianJunit5Test, the wiremock and jmockit packages. The first run had 330 tests (1 skipped) and the separate jmockit package run had 92, all passing, with no test changes needed.

Fixes item N4 of #1211.

…-recipes-v1

# Conflicts:
#	src/main/java/org/openrewrite/java/testing/arquillian/ReplaceArquillianInSequenceAnnotation.java
…-recipes-v1

# Conflicts:
#	src/main/java/org/openrewrite/java/testing/junit5/AssertToAssertions.java
#	src/main/java/org/openrewrite/java/testing/junit5/RemoveObsoleteRunners.java
@timtebeek
timtebeek merged commit 345ed9c into main Oct 25, 2026
2 checks passed
@timtebeek
timtebeek deleted the tim/unconditional-sub-recipes branch October 25, 2026 13:58
@github-project-automation github-project-automation Bot moved this from In Progress to Done in OpenRewrite Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

1 participant