Skip to content

Commit 6d4d3f1

Browse files
committed
Skip recipe validation for imperative recipes in assertRecipesConfigure()
Recipes with optional parameters and a custom validate() requiring at least one to be present fail assertRecipesConfigure() because they are loaded with no arguments, leaving all optional params null. Declarative recipes (from YAML) should still be validated since their options are explicitly configured. Imperative recipes loaded with no user-provided arguments are inherently unconfigured and validation failures are expected. Add a recipeValidation flag to RecipeSpec (following the existing serializationValidation pattern) and gate validateAll() on it. In assertRecipesConfigure(), disable validation for non-DeclarativeRecipe instances. Fixes #6840
1 parent 33ac75a commit 6d4d3f1

2 files changed

Lines changed: 27 additions & 6 deletions

File tree

rewrite-test/src/main/java/org/openrewrite/test/RecipeSpec.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ public static RecipeSpec defaults() {
9292

9393
boolean serializationValidation = true;
9494

95+
boolean recipeValidation = true;
96+
9597
PrintOutputCapture.@Nullable MarkerPrinter markerPrinter;
9698

9799
List<UncheckedConsumer<List<SourceFile>>> beforeRecipes = new ArrayList<>();
@@ -258,6 +260,11 @@ public RecipeSpec validateRecipeSerialization(boolean validate) {
258260
return this;
259261
}
260262

263+
public RecipeSpec validateRecipe(boolean validate) {
264+
this.recipeValidation = validate;
265+
return this;
266+
}
267+
261268
public RecipeSpec sourceSet(Function<List<SourceFile>, LargeSourceSet> sourceSetBuilder) {
262269
this.sourceSet = sourceSetBuilder;
263270
return this;

rewrite-test/src/main/java/org/openrewrite/test/RewriteTest.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.jspecify.annotations.Nullable;
2020
import org.openrewrite.*;
2121
import org.openrewrite.config.CompositeRecipe;
22+
import org.openrewrite.config.DeclarativeRecipe;
2223
import org.openrewrite.config.Environment;
2324
import org.openrewrite.config.OptionDescriptor;
2425
import org.openrewrite.internal.*;
@@ -90,10 +91,21 @@ default void assertRecipesConfigure(String packageName) {
9091
// scanRuntimeClasspath picks up all recipes in META-INF/rewrite regardless of whether their
9192
// names start with the package we intend to filter on here
9293
if (recipe.getName().startsWith(packageName)) {
94+
// Imperative recipes are loaded with no user-provided arguments, so all optional
95+
// parameters are null. Skip recipe validation for these since custom validate()
96+
// methods (e.g. requiring at least one of several optional parameters) would
97+
// fail on an unconfigured instance. Declarative recipes have their options
98+
// configured from YAML and should still be validated.
99+
boolean skipValidation = !(recipe instanceof DeclarativeRecipe);
93100
softly.assertThatCode(() -> {
94101
try {
95102
rewriteRun(
96-
spec -> spec.recipe(recipe),
103+
spec -> {
104+
spec.recipe(recipe);
105+
if (skipValidation) {
106+
spec.validateRecipe(false);
107+
}
108+
},
97109
new SourceSpecs[0]
98110
);
99111
} catch (Throwable t) {
@@ -226,11 +238,13 @@ default void rewriteRun(Consumer<RecipeSpec> spec, SourceSpec<?>... sourceSpecs)
226238
for (SourceSpec<?> s : sourceSpecs) {
227239
s.customizeExecutionContext.accept(ctx);
228240
}
229-
List<Validated<Object>> validations = new ArrayList<>();
230-
recipe.validateAll(ctx, validations);
231-
assertThat(validations.stream().filter(Validated::isInvalid))
232-
.as("Recipe validation must have no failures")
233-
.isEmpty();
241+
if (testClassSpec.recipeValidation && testMethodSpec.recipeValidation) {
242+
List<Validated<Object>> validations = new ArrayList<>();
243+
recipe.validateAll(ctx, validations);
244+
assertThat(validations.stream().filter(Validated::isInvalid))
245+
.as("Recipe validation must have no failures")
246+
.isEmpty();
247+
}
234248

235249
Map<Parser.Builder, List<SourceSpec<?>>> sourceSpecsByParser = new HashMap<>();
236250
List<Parser.Builder> methodSpecParsers = testMethodSpec.parsers;

0 commit comments

Comments
 (0)