Skip to content

Commit 58a608d

Browse files
Recipe testing best practices (#7094)
* Recipe testing best practices Use this link to re-run the recipe: https://app.moderne.io/builder/9uwIjLvVE?organizationId=QUxML01vZGVybmUvTW9kZXJuZSArIE9wZW5SZXdyaXRl Co-authored-by: Moderne <team@moderne.io> * Fix RenameVariableTest: wrap .toList() in ArrayList for mutability The prior commit replaced .collect(toList()) with .toList(), but the resulting immutable list is later mutated via addAll(), causing UnsupportedOperationException in all 19 RenameVariableTest cases. --------- Co-authored-by: Moderne <team@moderne.io>
1 parent 9fa3a92 commit 58a608d

57 files changed

Lines changed: 349 additions & 330 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

rewrite-core/src/test/java/org/openrewrite/AddToGitignoreTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ void doNotChangeWhenEntriesExistInDifferentOrder() {
315315

316316
@Test
317317
void rootOnlyTargetingByDefault() {
318-
AddToGitignore recipe = new AddToGitignore("*.log", null);
318+
var recipe = new AddToGitignore("*.log", null);
319319
rewriteRun(
320320
spec -> spec.recipe(recipe),
321321
text(
@@ -340,7 +340,7 @@ void rootOnlyTargetingByDefault() {
340340

341341
@Test
342342
void targetSpecificSubdirectory() {
343-
AddToGitignore recipe = new AddToGitignore("*.log", "src/.gitignore");
343+
var recipe = new AddToGitignore("*.log", "src/.gitignore");
344344
rewriteRun(
345345
spec -> spec.recipe(recipe),
346346
text(
@@ -365,7 +365,7 @@ void targetSpecificSubdirectory() {
365365

366366
@Test
367367
void targetAllGitignoreFiles() {
368-
AddToGitignore recipe = new AddToGitignore("*.log", "**/.gitignore");
368+
var recipe = new AddToGitignore("*.log", "**/.gitignore");
369369
rewriteRun(
370370
spec -> spec.recipe(recipe),
371371
text(
@@ -406,7 +406,7 @@ void targetAllGitignoreFiles() {
406406

407407
@Test
408408
void createGitignoreInSpecificLocation() {
409-
AddToGitignore recipe = new AddToGitignore("*.log", "src/.gitignore");
409+
var recipe = new AddToGitignore("*.log", "src/.gitignore");
410410
rewriteRun(
411411
spec -> spec.recipe(recipe),
412412
text(
@@ -421,7 +421,7 @@ void createGitignoreInSpecificLocation() {
421421

422422
@Test
423423
void createRootGitignoreWhenPatternIsWildcard() {
424-
AddToGitignore recipe = new AddToGitignore("*.log", "**/.gitignore");
424+
var recipe = new AddToGitignore("*.log", "**/.gitignore");
425425
rewriteRun(
426426
spec -> spec.recipe(recipe),
427427
text(

rewrite-core/src/test/java/org/openrewrite/RecipeRunTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
import java.nio.file.Path;
2727
import java.util.List;
28-
import java.util.stream.Collectors;
2928

3029
import static org.assertj.core.api.Assertions.assertThat;
3130
import static org.openrewrite.test.SourceSpecs.text;
@@ -81,7 +80,7 @@ void dataTableWithMultilineValue() {
8180

8281
// Verify the row has multiline content
8382
List<?> rows = store.getRows(parseFailuresDt.getName(), parseFailuresDt.getGroup())
84-
.collect(java.util.stream.Collectors.toList());
83+
.toList();
8584
assertThat(rows).hasSize(1);
8685
}),
8786
text(

rewrite-core/src/test/java/org/openrewrite/RecipeSchedulerTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ void recipeRunExceptionDuringGenerate() {
111111

112112
@Test
113113
void suppliedWorkingDirectoryRoot(@TempDir Path path) {
114-
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
114+
var ctx = new InMemoryExecutionContext();
115115
WorkingDirectoryExecutionContextView.view(ctx).setRoot(path);
116-
AtomicInteger cycle = new AtomicInteger(0);
116+
var cycle = new AtomicInteger(0);
117117
rewriteRun(
118118
spec -> spec.executionContext(ctx).recipe(toRecipe(() -> new TreeVisitor<>() {
119119
@Override
@@ -139,7 +139,7 @@ public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
139139

140140
@Test
141141
void managedWorkingDirectoryWithRecipe(@TempDir Path path) {
142-
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
142+
var ctx = new InMemoryExecutionContext();
143143
WorkingDirectoryExecutionContextView.view(ctx).setRoot(path);
144144
rewriteRun(
145145
spec -> spec.executionContext(ctx).recipe(new RecipeWritingToFile(0)),
@@ -150,9 +150,9 @@ void managedWorkingDirectoryWithRecipe(@TempDir Path path) {
150150

151151
@Test
152152
void managedWorkingDirectoryWithMultipleRecipes(@TempDir Path path) {
153-
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
153+
var ctx = new InMemoryExecutionContext();
154154
WorkingDirectoryExecutionContextView.view(ctx).setRoot(path);
155-
DeclarativeRecipe recipe = new DeclarativeRecipe(
155+
var recipe = new DeclarativeRecipe(
156156
"root",
157157
"Root recipe",
158158
"Root recipe.",
@@ -176,7 +176,7 @@ void managedWorkingDirectoryWithMultipleRecipes(@TempDir Path path) {
176176
void verifyCycleInvariantsDuringMultipleCycles() {
177177
List<Integer> cyclesFromFactory = new java.util.ArrayList<>();
178178
List<Integer> cyclesFromContext = new java.util.ArrayList<>();
179-
AtomicInteger visitCount = new AtomicInteger(0);
179+
var visitCount = new AtomicInteger(0);
180180

181181
RecipeScheduler trackingScheduler = new RecipeScheduler() {
182182
@Override
@@ -205,7 +205,7 @@ public PlainText visitText(PlainText text, ExecutionContext ctx) {
205205
}
206206
}).withCausesAnotherCycle(true);
207207

208-
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
208+
var ctx = new InMemoryExecutionContext();
209209
List<SourceFile> sources = List.of(PlainText.builder().text("v").sourcePath(Path.of("test.txt")).build());
210210
trackingScheduler.scheduleRun(multiCycleRecipe, new InMemoryLargeSourceSet(sources), ctx, 5, 1);
211211

@@ -252,7 +252,7 @@ public PlainText visitText(PlainText text, ExecutionContext ctx) {
252252
}
253253
});
254254

255-
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
255+
var ctx = new InMemoryExecutionContext();
256256
List<SourceFile> sources = List.of(
257257
PlainText.builder().text("a").sourcePath(Path.of("a.txt")).build(),
258258
PlainText.builder().text("b").sourcePath(Path.of("b.txt")).build()
@@ -292,7 +292,7 @@ protected void recordSourceFileResultAndSearchResults(
292292

293293
Recipe generatingRecipe = new GeneratingRecipe();
294294

295-
InMemoryExecutionContext ctx = new InMemoryExecutionContext();
295+
var ctx = new InMemoryExecutionContext();
296296
List<SourceFile> sources = List.of(PlainText.builder().text("existing").sourcePath(Path.of("existing.txt")).build());
297297
trackingScheduler.scheduleRun(generatingRecipe, new InMemoryLargeSourceSet(sources), ctx, 3, 1);
298298

rewrite-core/src/test/java/org/openrewrite/TreeTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public String afterSyntax(Marker marker, Cursor cursor, UnaryOperator<String> co
6363
})
6464
@ParameterizedTest
6565
void printBomHandling(boolean charsetBomMarked, String expected) {
66-
PlainText sourceFile = new PlainText(
66+
var sourceFile = new PlainText(
6767
Tree.randomId(),
6868
Paths.get("test.txt"),
6969
Markers.EMPTY,
@@ -82,7 +82,7 @@ void printBomHandling(boolean charsetBomMarked, String expected) {
8282

8383
@Test
8484
void printQuarkDoesNotThrowOnBomRestoration() {
85-
Quark quark = new Quark(
85+
var quark = new Quark(
8686
Tree.randomId(),
8787
Paths.get("unknown.file"),
8888
Markers.EMPTY,

rewrite-core/src/test/java/org/openrewrite/config/DeclarativeRecipeTest.java

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void precondition() {
6060
rewriteRun(
6161
spec -> {
6262
spec.validateRecipeSerialization(false);
63-
DeclarativeRecipe dr = new DeclarativeRecipe("test", "test", "test", emptySet(),
63+
var dr = new DeclarativeRecipe("test", "test", "test", emptySet(),
6464
null, URI.create("null"), true, emptyList());
6565
dr.addPrecondition(
6666
toRecipe(() -> new PlainTextVisitor<>() {
@@ -89,7 +89,7 @@ public PlainText visitText(PlainText text, ExecutionContext ctx) {
8989

9090
@Test
9191
void addingPreconditionsWithOptions() {
92-
DeclarativeRecipe dr = new DeclarativeRecipe("test", "test", "test", emptySet(),
92+
var dr = new DeclarativeRecipe("test", "test", "test", emptySet(),
9393
null, URI.create("dummy"), true, emptyList());
9494
dr.addPrecondition(
9595
toRecipe(() -> new PlainTextVisitor<>() {
@@ -119,7 +119,7 @@ public PlainText visitText(PlainText text, ExecutionContext ctx) {
119119

120120
@Test
121121
void preconditionDescriptorsIncludedInDescriptor() {
122-
DeclarativeRecipe dr = new DeclarativeRecipe("test", "test", "test", emptySet(),
122+
var dr = new DeclarativeRecipe("test", "test", "test", emptySet(),
123123
null, URI.create("dummy"), true, emptyList());
124124
dr.addPrecondition(new Find("precondition-marker", null, null, null, null, null, null, null));
125125
dr.addUninitialized(new ChangeText("2"));
@@ -138,7 +138,7 @@ void preconditionDescriptorsIncludedInDescriptor() {
138138

139139
@Test
140140
void uninitializedFailsValidation() {
141-
DeclarativeRecipe dr = new DeclarativeRecipe("test", "test", "test", emptySet(),
141+
var dr = new DeclarativeRecipe("test", "test", "test", emptySet(),
142142
null, URI.create("dummy"), true, emptyList());
143143
dr.addUninitializedPrecondition(
144144
toRecipe(() -> new PlainTextVisitor<>() {
@@ -165,7 +165,7 @@ public PlainText visitText(PlainText text, ExecutionContext ctx) {
165165

166166
@Test
167167
void uninitializedWithInitializedRecipesPassesValidation() {
168-
DeclarativeRecipe dr = new DeclarativeRecipe("test", "test", "test", emptySet(),
168+
var dr = new DeclarativeRecipe("test", "test", "test", emptySet(),
169169
null, URI.create("dummy"), true, emptyList());
170170
dr.setPreconditions(
171171
List.of(
@@ -364,7 +364,7 @@ void preconditionOnNestedDeclarative() {
364364

365365
@Test
366366
void exposesUnderlyingDataTables() {
367-
DeclarativeRecipe dr = new DeclarativeRecipe("org.openrewrite.DeclarativeDataTable", "declarative with data table",
367+
var dr = new DeclarativeRecipe("org.openrewrite.DeclarativeDataTable", "declarative with data table",
368368
"test", emptySet(), null, URI.create("dummy"), true, emptyList());
369369
dr.addUninitialized(new Find("sam", null, null, null, null, null, null, null));
370370
dr.initialize(List.of());
@@ -373,17 +373,17 @@ void exposesUnderlyingDataTables() {
373373

374374
@Test
375375
void getDataTableDescriptorsThreadSafe() throws Exception {
376-
DeclarativeRecipe dr = new DeclarativeRecipe("org.openrewrite.ConcurrentTest", "concurrent test",
376+
var dr = new DeclarativeRecipe("org.openrewrite.ConcurrentTest", "concurrent test",
377377
"test", emptySet(), null, URI.create("dummy"), true, emptyList());
378378
dr.addUninitialized(new Find("sam", null, null, null, null, null, null, null));
379379
dr.initialize(List.of());
380380

381381
int threadCount = 10;
382382
int iterations = 100;
383383
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
384-
CountDownLatch startLatch = new CountDownLatch(1);
385-
CountDownLatch doneLatch = new CountDownLatch(threadCount);
386-
ConcurrentLinkedQueue<Throwable> errors = new ConcurrentLinkedQueue<>();
384+
var startLatch = new CountDownLatch(1);
385+
var doneLatch = new CountDownLatch(threadCount);
386+
var errors = new ConcurrentLinkedQueue<Throwable>();
387387

388388
for (int i = 0; i < threadCount; i++) {
389389
final int threadIdx = i;
@@ -418,7 +418,7 @@ void getDataTableDescriptorsThreadSafe() throws Exception {
418418

419419
@Test
420420
void concurrentInitializeDoesNotDuplicateRecipes() throws Exception {
421-
DeclarativeRecipe dr = new DeclarativeRecipe("org.openrewrite.ConcurrentInitTest", "concurrent init test",
421+
var dr = new DeclarativeRecipe("org.openrewrite.ConcurrentInitTest", "concurrent init test",
422422
"test", emptySet(), null, URI.create("dummy"), true, emptyList());
423423
dr.addUninitialized(new Find("sam", null, null, null, null, null, null, null));
424424
dr.addUninitialized(new ChangeText("hello"));
@@ -428,9 +428,9 @@ void concurrentInitializeDoesNotDuplicateRecipes() throws Exception {
428428

429429
int threadCount = 20;
430430
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
431-
CountDownLatch startLatch = new CountDownLatch(1);
432-
CountDownLatch doneLatch = new CountDownLatch(threadCount);
433-
ConcurrentLinkedQueue<Throwable> errors = new ConcurrentLinkedQueue<>();
431+
var startLatch = new CountDownLatch(1);
432+
var doneLatch = new CountDownLatch(threadCount);
433+
var errors = new ConcurrentLinkedQueue<Throwable>();
434434

435435
for (int i = 0; i < threadCount; i++) {
436436
executor.submit(() -> {
@@ -469,7 +469,7 @@ void maxCycles() {
469469

470470
@Test
471471
void maxCyclesNested() {
472-
AtomicInteger cycleCount = new AtomicInteger();
472+
var cycleCount = new AtomicInteger();
473473
Recipe root = new MaxCycles(
474474
100,
475475
List.of(new MaxCycles(
@@ -540,7 +540,7 @@ public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
540540
@Test
541541
void selfReferencingRecipeDetectedAsCycle() {
542542
// Test that a recipe referencing itself is detected as a cycle
543-
DeclarativeRecipe selfReferencing = new DeclarativeRecipe(
543+
var selfReferencing = new DeclarativeRecipe(
544544
"org.openrewrite.SelfReferencing",
545545
"Self Referencing Recipe",
546546
"A recipe that references itself",
@@ -564,7 +564,7 @@ void selfReferencingRecipeDetectedAsCycle() {
564564
@Test
565565
void mutuallyRecursiveRecipesDetectedAsCycle() {
566566
// Test that mutually recursive recipes are detected as a cycle
567-
DeclarativeRecipe recipeA = new DeclarativeRecipe(
567+
var recipeA = new DeclarativeRecipe(
568568
"org.openrewrite.RecipeA",
569569
"Recipe A",
570570
"Recipe A that references Recipe B",
@@ -575,7 +575,7 @@ void mutuallyRecursiveRecipesDetectedAsCycle() {
575575
emptyList()
576576
);
577577

578-
DeclarativeRecipe recipeB = new DeclarativeRecipe(
578+
var recipeB = new DeclarativeRecipe(
579579
"org.openrewrite.RecipeB",
580580
"Recipe B",
581581
"Recipe B that references Recipe A",
@@ -785,7 +785,7 @@ void multipleNestedOrPreconditionsWithSameScanningRecipe() {
785785
@Test
786786
void deeperCyclicReferencesDetectedAsCycle() {
787787
// Test that deeper cyclic references (A -> B -> C -> A) are detected as a cycle
788-
DeclarativeRecipe recipeA = new DeclarativeRecipe(
788+
var recipeA = new DeclarativeRecipe(
789789
"org.openrewrite.RecipeA",
790790
"Recipe A",
791791
"Recipe A that references Recipe B",
@@ -796,7 +796,7 @@ void deeperCyclicReferencesDetectedAsCycle() {
796796
emptyList()
797797
);
798798

799-
DeclarativeRecipe recipeB = new DeclarativeRecipe(
799+
var recipeB = new DeclarativeRecipe(
800800
"org.openrewrite.RecipeB",
801801
"Recipe B",
802802
"Recipe B that references Recipe C",
@@ -807,7 +807,7 @@ void deeperCyclicReferencesDetectedAsCycle() {
807807
emptyList()
808808
);
809809

810-
DeclarativeRecipe recipeC = new DeclarativeRecipe(
810+
var recipeC = new DeclarativeRecipe(
811811
"org.openrewrite.RecipeC",
812812
"Recipe C",
813813
"Recipe C that references Recipe A",
@@ -842,7 +842,7 @@ void deeperCyclicReferencesDetectedAsCycle() {
842842
// This can't be tested via rewriteRun() which uses a single RecipeRunCycle per cycle.
843843
@Test
844844
void scanningRecipeAccumulatorSurvivesAcrossRecipeRunCycles() {
845-
DeclarativeRecipe recipe = new DeclarativeRecipe(
845+
var recipe = new DeclarativeRecipe(
846846
"test.WithPrecondition", "With precondition", "Test with precondition.",
847847
emptySet(), null, URI.create("test"), true, emptyList()
848848
);
@@ -855,12 +855,12 @@ void scanningRecipeAccumulatorSurvivesAcrossRecipeRunCycles() {
855855
PlainText.builder().id(Tree.randomId()).sourcePath(Paths.get("file2.txt")).text("world").build()
856856
);
857857

858-
Cursor rootCursor = new Cursor(null, Cursor.ROOT_VALUE);
859-
WatchableExecutionContext ctx = new WatchableExecutionContext(new InMemoryExecutionContext());
858+
var rootCursor = new Cursor(null, Cursor.ROOT_VALUE);
859+
var ctx = new WatchableExecutionContext(new InMemoryExecutionContext());
860860
Recipe noop = Recipe.noop();
861861

862862
// Cycle 1: scan (simulates first yield batch on the platform)
863-
RecipeRunCycle<LargeSourceSet> scanCycle = new RecipeRunCycle<>(
863+
var scanCycle = new RecipeRunCycle<LargeSourceSet>(
864864
recipe, 1, rootCursor, ctx,
865865
new RecipeRunStats(noop), new SearchResults(noop),
866866
new SourcesFileResults(noop), new SourcesFileErrors(noop),
@@ -870,7 +870,7 @@ void scanningRecipeAccumulatorSurvivesAcrossRecipeRunCycles() {
870870
scanCycle.scanSources(new InMemoryLargeSourceSet(sources));
871871

872872
// Cycle 2: edit (simulates new RecipeRunCycle after worker yield — new RecipeStack, fresh getRecipeList() calls)
873-
RecipeRunCycle<LargeSourceSet> editCycle = new RecipeRunCycle<>(
873+
var editCycle = new RecipeRunCycle<LargeSourceSet>(
874874
recipe, 1, rootCursor, ctx,
875875
new RecipeRunStats(noop), new SearchResults(noop),
876876
new SourcesFileResults(noop), new SourcesFileErrors(noop),

rewrite-core/src/test/java/org/openrewrite/rpc/RewriteRpcTest.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,15 @@ class RewriteRpcTest implements RewriteTest {
6464

6565
@BeforeEach
6666
void before() throws IOException {
67-
PipedOutputStream serverOut = new PipedOutputStream();
68-
PipedOutputStream clientOut = new PipedOutputStream();
69-
PipedInputStream serverIn = new PipedInputStream(clientOut);
70-
PipedInputStream clientIn = new PipedInputStream(serverOut);
67+
var serverOut = new PipedOutputStream();
68+
var clientOut = new PipedOutputStream();
69+
var serverIn = new PipedInputStream(clientOut);
70+
var clientIn = new PipedInputStream(serverOut);
7171

7272
marketplace = env.toMarketplace(runtimeClasspath());
7373

74-
JsonMessageFormatter clientFormatter = new JsonMessageFormatter(new ParameterNamesModule());
75-
JsonMessageFormatter serverFormatter = new JsonMessageFormatter(new ParameterNamesModule());
74+
var clientFormatter = new JsonMessageFormatter(new ParameterNamesModule());
75+
var serverFormatter = new JsonMessageFormatter(new ParameterNamesModule());
7676

7777
client = new RewriteRpc(new JsonRpc(new HeaderDelimitedMessageHandler(clientFormatter, clientIn, clientOut)), marketplace)
7878
.batchSize(1);
@@ -239,7 +239,7 @@ void prepareRecipe() {
239239
@Disabled("Disabled until https://github.com/openrewrite/rewrite/pull/5260 is complete")
240240
@Test
241241
void runRecipe() {
242-
CountDownLatch latch = new CountDownLatch(1);
242+
var latch = new CountDownLatch(1);
243243
rewriteRun(
244244
spec -> spec
245245
.recipe(client.prepareRecipe("org.openrewrite.text.Find",
@@ -415,9 +415,9 @@ void singleRpcRecipeNoBatch() {
415415

416416
@Test
417417
void getCursor() {
418-
Cursor parent = new Cursor(null, Cursor.ROOT_VALUE);
419-
Cursor c1 = new Cursor(parent, 0);
420-
Cursor c2 = new Cursor(c1, 1);
418+
var parent = new Cursor(null, Cursor.ROOT_VALUE);
419+
var c1 = new Cursor(parent, 0);
420+
var c2 = new Cursor(c1, 1);
421421

422422
Cursor clientC2 = server.getCursor(client.getCursorIds(c2), null);
423423
assertThat(clientC2.<Integer>getValue()).isEqualTo(1);

0 commit comments

Comments
 (0)