From 675cd94c89326cc422da6e82bf44300d7100998a Mon Sep 17 00:00:00 2001 From: martinfrancois Date: Tue, 11 Aug 2026 20:07:18 +0200 Subject: [PATCH 1/2] Avoid duplicate Truth migration comments --- .../truth/TruthAssertToAssertThat.java | 7 +- .../truth/TruthCustomSubjectsToAssertJ.java | 8 +-- .../truth/TruthAssertToAssertThatTest.java | 62 +++++++++++++++++ .../TruthCustomSubjectsToAssertJTest.java | 66 +++++++++++++++++++ 4 files changed, 134 insertions(+), 9 deletions(-) create mode 100644 src/test/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThatTest.java create mode 100644 src/test/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJTest.java diff --git a/src/main/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThat.java b/src/main/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThat.java index 32466ec37..71a383522 100644 --- a/src/main/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThat.java +++ b/src/main/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThat.java @@ -24,11 +24,12 @@ import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.search.UsesMethod; import org.openrewrite.java.tree.J; -import org.openrewrite.marker.SearchResult; +import org.openrewrite.trait.Comments; public class TruthAssertToAssertThat extends Recipe { private static final MethodMatcher ASSERT_MATCHER = new MethodMatcher("com.google.common.truth.Truth assert_()"); + private static final String MANUAL_REVIEW = " Truth's assert_() requires manual review for migration to AssertJ "; @Getter final String displayName = "Convert Truth `assert_()` to AssertJ"; @@ -44,9 +45,7 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu J.MethodInvocation mi = super.visitMethodInvocation(method, ctx); if (ASSERT_MATCHER.matches(mi)) { - // Truth's assert_() returns a StandardSubjectBuilder which is used differently - // For now, we'll mark this as needing manual review - return SearchResult.found(mi, "Truth's assert_() requires manual review for migration to AssertJ"); + return Comments.of(updateCursor(mi)).multilineComment(MANUAL_REVIEW); } return mi; diff --git a/src/main/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJ.java b/src/main/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJ.java index 45cd9bf97..f2594a446 100644 --- a/src/main/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJ.java +++ b/src/main/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJ.java @@ -24,11 +24,12 @@ import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.search.UsesMethod; import org.openrewrite.java.tree.J; -import org.openrewrite.marker.SearchResult; +import org.openrewrite.trait.Comments; public class TruthCustomSubjectsToAssertJ extends Recipe { private static final MethodMatcher ASSERT_ABOUT = new MethodMatcher("com.google.common.truth.Truth assertAbout(..)"); + private static final String MANUAL_REVIEW = " Truth's assertAbout() with custom subjects requires manual migration to AssertJ custom assertions "; @Getter final String displayName = "Migrate Truth custom subjects to AssertJ"; @@ -44,10 +45,7 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu J.MethodInvocation mi = super.visitMethodInvocation(method, ctx); if (ASSERT_ABOUT.matches(mi)) { - // Truth's assertAbout() is used for custom subjects - // AssertJ uses a different pattern with custom assertion classes - // This requires manual migration to create custom AssertJ assertion classes - return SearchResult.found(mi, "Truth's assertAbout() with custom subjects requires manual migration to AssertJ custom assertions"); + return Comments.of(updateCursor(mi)).multilineComment(MANUAL_REVIEW); } return mi; diff --git a/src/test/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThatTest.java b/src/test/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThatTest.java new file mode 100644 index 000000000..1d5a566ba --- /dev/null +++ b/src/test/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThatTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.testing.truth; + +import org.junit.jupiter.api.Test; +import org.openrewrite.InMemoryExecutionContext; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +class TruthAssertToAssertThatTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.recipe(new TruthAssertToAssertThat()) + .parser(JavaParser.fromJavaVersion() + .classpathFromResources(new InMemoryExecutionContext(), "guava", "truth")); + } + + @Test + void addsCommentOnce() { + rewriteRun( + spec -> spec.cycles(2).expectedCyclesThatMakeChanges(1), + //language=java + java( + """ + import static com.google.common.truth.Truth.assert_; + + class Test { + void test() { + assert_().fail(); + } + } + """, + """ + import static com.google.common.truth.Truth.assert_; + + class Test { + void test() { + /* Truth's assert_() requires manual review for migration to AssertJ */assert_().fail(); + } + } + """ + ) + ); + } +} diff --git a/src/test/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJTest.java b/src/test/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJTest.java new file mode 100644 index 000000000..7bbcd7c9b --- /dev/null +++ b/src/test/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Moderne Source Available License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://docs.moderne.io/licensing/moderne-source-available-license + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.testing.truth; + +import org.junit.jupiter.api.Test; +import org.openrewrite.InMemoryExecutionContext; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +class TruthCustomSubjectsToAssertJTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.recipe(new TruthCustomSubjectsToAssertJ()) + .parser(JavaParser.fromJavaVersion() + .classpathFromResources(new InMemoryExecutionContext(), "guava", "truth")); + } + + @Test + void addsCommentOnce() { + rewriteRun( + spec -> spec.cycles(2).expectedCyclesThatMakeChanges(1), + //language=java + java( + """ + import com.google.common.truth.Subject; + + import static com.google.common.truth.Truth.assertAbout; + + class Test { + void test(Subject.Factory factory) { + assertAbout(factory).that(new Object()); + } + } + """, + """ + import com.google.common.truth.Subject; + + import static com.google.common.truth.Truth.assertAbout; + + class Test { + void test(Subject.Factory factory) { + /* Truth's assertAbout() with custom subjects requires manual migration to AssertJ custom assertions */assertAbout(factory).that(new Object()); + } + } + """ + ) + ); + } +} From 1a5d348451efe8748cb04c9db4b57c2906302a0d Mon Sep 17 00:00:00 2001 From: martinfrancois Date: Sun, 16 Aug 2026 23:42:13 +0200 Subject: [PATCH 2/2] Extract the comment padding into an explaining method --- .../java/testing/truth/TruthAssertToAssertThat.java | 7 ++++++- .../java/testing/truth/TruthCustomSubjectsToAssertJ.java | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThat.java b/src/main/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThat.java index 71a383522..940bc2f3d 100644 --- a/src/main/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThat.java +++ b/src/main/java/org/openrewrite/java/testing/truth/TruthAssertToAssertThat.java @@ -29,7 +29,7 @@ public class TruthAssertToAssertThat extends Recipe { private static final MethodMatcher ASSERT_MATCHER = new MethodMatcher("com.google.common.truth.Truth assert_()"); - private static final String MANUAL_REVIEW = " Truth's assert_() requires manual review for migration to AssertJ "; + private static final String MANUAL_REVIEW = asCommentText("Truth's assert_() requires manual review for migration to AssertJ"); @Getter final String displayName = "Convert Truth `assert_()` to AssertJ"; @@ -52,4 +52,9 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu } }); } + + // Pad the text so the comment renders as `/* text */` rather than `/*text*/` + private static String asCommentText(String message) { + return " " + message + " "; + } } diff --git a/src/main/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJ.java b/src/main/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJ.java index f2594a446..32a3d8a77 100644 --- a/src/main/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJ.java +++ b/src/main/java/org/openrewrite/java/testing/truth/TruthCustomSubjectsToAssertJ.java @@ -29,7 +29,7 @@ public class TruthCustomSubjectsToAssertJ extends Recipe { private static final MethodMatcher ASSERT_ABOUT = new MethodMatcher("com.google.common.truth.Truth assertAbout(..)"); - private static final String MANUAL_REVIEW = " Truth's assertAbout() with custom subjects requires manual migration to AssertJ custom assertions "; + private static final String MANUAL_REVIEW = asCommentText("Truth's assertAbout() with custom subjects requires manual migration to AssertJ custom assertions"); @Getter final String displayName = "Migrate Truth custom subjects to AssertJ"; @@ -52,4 +52,9 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu } }); } + + // Pad the text so the comment renders as `/* text */` rather than `/*text*/` + private static String asCommentText(String message) { + return " " + message + " "; + } }