From dbd7ce8e17fa577510952c225979f223bd73fc2e Mon Sep 17 00:00:00 2001 From: Jonathan Schneider Date: Sun, 25 Dec 2022 20:54:20 -0500 Subject: [PATCH] Move rewrite-core tests from Kotlin to Java --- .../benchmarks/java/JavaFiles.java | 4 +- rewrite-core/build.gradle.kts | 2 - .../src/main/java/org/openrewrite/Recipe.java | 13 +- .../org/openrewrite/config/CategoryTree.java | 2 +- .../org/openrewrite/ApplicabilityTest.java | 118 +++++++ .../test/java/org/openrewrite/CursorTest.java | 67 ++++ .../org/openrewrite/ExecutionContextTest.java | 50 +++ .../org/openrewrite/RecipeBasicsTest.java | 7 + .../org/openrewrite/RecipeLifecycleTest.java | 312 ++++++++++++++++++ .../org/openrewrite/RecipeSchedulerTest.java | 81 +++++ .../test/java/org/openrewrite/ResultTest.java | 219 ++++++++++++ .../org/openrewrite/TreeObserverTest.java | 62 ++++ .../openrewrite/internal/ListUtilsTest.java | 60 ++++ .../internal/NameCaseConventionTest.java | 138 ++++++++ .../PropertyPlaceholderHelperTest.java} | 25 +- .../openrewrite/internal/StringUtilsTest.java | 126 +++++++ .../internal/lang/NullUtilsTest.java | 54 +++ .../openrewrite/marker/GitProvenanceTest.java | 234 +++++++++++++ .../openrewrite/quark/QuarkParserTest.java | 117 +++++++ .../org/openrewrite/quark/QuarkTest.java | 0 .../openrewrite/semver/CaretRangeTest.java | 120 +++++++ .../semver/DependencyMatcherTest.java} | 11 +- .../openrewrite/semver/HyphenRangeTest.java} | 83 ++--- .../openrewrite/semver/LatestPatchTest.java | 106 ++++++ .../openrewrite/semver/LatestReleaseTest.java | 123 +++++++ .../org/openrewrite/semver/SemverTest.java | 38 +++ .../openrewrite/semver/TildeRangeTest.java | 96 ++++++ .../org/openrewrite/semver/XRangeTest.java | 108 ++++++ .../text/AppendToTextFileTest.java | 188 +++++++++++ .../org/openrewrite/ApplicabilityTest.kt | 84 ----- .../test/kotlin/org/openrewrite/CursorTest.kt | 68 ---- .../org/openrewrite/ExecutionContextTest.kt | 55 --- .../org/openrewrite/RecipeLifecycleTest.kt | 265 --------------- .../org/openrewrite/RecipeSchedulerTest.kt | 60 ---- .../test/kotlin/org/openrewrite/ResultTest.kt | 251 -------------- .../org/openrewrite/TreeObserverTest.kt | 66 ---- .../org/openrewrite/internal/ListUtilsTest.kt | 76 ----- .../internal/NameCaseConventionTest.kt | 153 --------- .../internal/RecipeIntrospectionUtilsTest.kt | 41 --- .../openrewrite/internal/StringUtilsTest.kt | 238 ------------- .../internal/lang/NullUtilsTest.kt | 53 --- .../openrewrite/marker/GitProvenanceTest.kt | 225 ------------- .../org/openrewrite/quark/.editorconfig | 5 - .../org/openrewrite/quark/QuarkParserTest.kt | 94 ------ .../org/openrewrite/semver/CaretRangeTest.kt | 111 ------- .../org/openrewrite/semver/LatestPatchTest.kt | 104 ------ .../openrewrite/semver/LatestReleaseTest.kt | 124 ------- .../org/openrewrite/semver/SemverTest.kt | 37 --- .../org/openrewrite/semver/TildeRangeTest.kt | 89 ----- .../org/openrewrite/semver/XRangeTest.kt | 100 ------ .../openrewrite/text/AppendToTextFileTest.kt | 209 ------------ rewrite-java-tck/README.md | 6 +- .../maven/MavenDependencyFailuresTest.java | 8 +- .../org/openrewrite/test/AdHocRecipe.java | 50 ++- .../org/openrewrite/test/RewriteTest.java | 9 +- .../AddOwaspDateBoundSuppressions.java | 2 +- .../xml/security/IsOwaspSuppressionsFile.java | 62 ++-- .../xml/security/RemoveOwaspSuppressions.java | 2 +- .../security/UpdateOwaspSuppressionDate.java | 2 +- .../security/IsOwaspSuppressionsFileTest.java | 3 +- 60 files changed, 2599 insertions(+), 2617 deletions(-) create mode 100644 rewrite-core/src/test/java/org/openrewrite/ApplicabilityTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/CursorTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/ExecutionContextTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/RecipeLifecycleTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/RecipeSchedulerTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/ResultTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/TreeObserverTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/internal/ListUtilsTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/internal/NameCaseConventionTest.java rename rewrite-core/src/test/{kotlin/org/openrewrite/internal/PropertyPlaceholderHelperTest.kt => java/org/openrewrite/internal/PropertyPlaceholderHelperTest.java} (58%) create mode 100644 rewrite-core/src/test/java/org/openrewrite/internal/StringUtilsTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/internal/lang/NullUtilsTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/marker/GitProvenanceTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/quark/QuarkParserTest.java rename rewrite-core/src/test/{kotlin => java}/org/openrewrite/quark/QuarkTest.java (100%) create mode 100644 rewrite-core/src/test/java/org/openrewrite/semver/CaretRangeTest.java rename rewrite-core/src/test/{kotlin/org/openrewrite/semver/DependencyMatcherTest.kt => java/org/openrewrite/semver/DependencyMatcherTest.java} (80%) rename rewrite-core/src/test/{kotlin/org/openrewrite/semver/HyphenRangeTest.kt => java/org/openrewrite/semver/HyphenRangeTest.java} (54%) create mode 100644 rewrite-core/src/test/java/org/openrewrite/semver/LatestPatchTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/semver/LatestReleaseTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/semver/SemverTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/semver/TildeRangeTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/semver/XRangeTest.java create mode 100644 rewrite-core/src/test/java/org/openrewrite/text/AppendToTextFileTest.java delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/ApplicabilityTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/CursorTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/ExecutionContextTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/RecipeLifecycleTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/RecipeSchedulerTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/ResultTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/TreeObserverTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/internal/ListUtilsTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/internal/NameCaseConventionTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/internal/RecipeIntrospectionUtilsTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/internal/StringUtilsTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/internal/lang/NullUtilsTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/marker/GitProvenanceTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/quark/.editorconfig delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/quark/QuarkParserTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/semver/CaretRangeTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/semver/LatestPatchTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/semver/LatestReleaseTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/semver/SemverTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/semver/TildeRangeTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/semver/XRangeTest.kt delete mode 100644 rewrite-core/src/test/kotlin/org/openrewrite/text/AppendToTextFileTest.kt diff --git a/rewrite-benchmarks/src/jmh/java/org/openrewrite/benchmarks/java/JavaFiles.java b/rewrite-benchmarks/src/jmh/java/org/openrewrite/benchmarks/java/JavaFiles.java index 60a30560dea..83095fffb89 100644 --- a/rewrite-benchmarks/src/jmh/java/org/openrewrite/benchmarks/java/JavaFiles.java +++ b/rewrite-benchmarks/src/jmh/java/org/openrewrite/benchmarks/java/JavaFiles.java @@ -45,8 +45,8 @@ public void setup() throws URISyntaxException, IOException { sourceFiles = new ArrayList<>(1_000); for (int i = 0; i < 1_000; i++) { - Files.write(test.resolve("Test" + i + ".java"), - ("package test; class Test" + i + " {}").getBytes()); + Files.writeString(test.resolve("Test" + i + ".java"), + "package test; class Test" + i + " {}"); } } diff --git a/rewrite-core/build.gradle.kts b/rewrite-core/build.gradle.kts index 6eb20fea5bd..e32e8541bd4 100644 --- a/rewrite-core/build.gradle.kts +++ b/rewrite-core/build.gradle.kts @@ -29,8 +29,6 @@ dependencies { implementation("org.yaml:snakeyaml:latest.release") testImplementation(project(":rewrite-test")) - - testRuntimeOnly("com.fasterxml.jackson.module:jackson-module-kotlin") } tasks.withType { diff --git a/rewrite-core/src/main/java/org/openrewrite/Recipe.java b/rewrite-core/src/main/java/org/openrewrite/Recipe.java index 44a16a187e2..032714f6906 100644 --- a/rewrite-core/src/main/java/org/openrewrite/Recipe.java +++ b/rewrite-core/src/main/java/org/openrewrite/Recipe.java @@ -171,6 +171,9 @@ public boolean causesAnotherCycle() { * @return This recipe. */ public Recipe doNext(Recipe recipe) { + if (recipe == this) { + throw new IllegalArgumentException("Cannot add a recipe to itself."); + } recipeList.add(recipe); return this; } @@ -216,7 +219,7 @@ protected TreeVisitor getApplicableTest() { */ @SuppressWarnings("unused") public Recipe addApplicableTest(TreeVisitor test) { - if(applicableTests == null) { + if (applicableTests == null) { applicableTests = new ArrayList<>(1); } applicableTests.add(test); @@ -252,7 +255,7 @@ protected TreeVisitor getSingleSourceApplicableTest() { * @return A tree visitor that performs an applicability test. */ public Recipe addSingleSourceApplicableTest(TreeVisitor test) { - if(singleSourceApplicableTests == null) { + if (singleSourceApplicableTests == null) { singleSourceApplicableTests = new ArrayList<>(1); } singleSourceApplicableTests.add(test); @@ -269,7 +272,7 @@ public List> getSingleSourceApplicableTests() { * Note that here, as throughout OpenRewrite, we use referential equality to detect that a change has occured. * To indicate to rewrite that the recipe has made changes a different instance must be returned than the instance * passed in as "before". - * + *

* Currently, the list passed in as "before" is not immutable, but you should treat it as such anyway. * * @param before The set of source files to operate on. @@ -303,7 +306,7 @@ public final RecipeRun run(List before, public Validated validate(ExecutionContext ctx) { Validated validated = validate(); - for(Recipe recipe : recipeList) { + for (Recipe recipe : recipeList) { validated = validated.and(recipe.validate(ctx)); } return validated; @@ -326,7 +329,7 @@ public Validated validate() { logger.warn("Unable to validate the field [{}] on the class [{}]", field.getName(), this.getClass().getName()); } } - for(Recipe recipe : recipeList) { + for (Recipe recipe : recipeList) { validated = validated.and(recipe.validate()); } return validated; diff --git a/rewrite-core/src/main/java/org/openrewrite/config/CategoryTree.java b/rewrite-core/src/main/java/org/openrewrite/config/CategoryTree.java index 5a5c18afcea..234a8c9adf6 100644 --- a/rewrite-core/src/main/java/org/openrewrite/config/CategoryTree.java +++ b/rewrite-core/src/main/java/org/openrewrite/config/CategoryTree.java @@ -331,7 +331,7 @@ CategoryTree findOrAddCategory(G group, CategoryDescriptor category) { void addRecipe(G group, RecipeDescriptor recipe) { if (!recipe.getName().contains(".")) { - throw new IllegalArgumentException("Expected recipe with name '" + recipe.getName() + "' to have" + + throw new IllegalArgumentException("Expected recipe with name '" + recipe.getName() + "' to have " + "a package, but it did not."); } String category = recipe.getName().substring(0, recipe.getName().lastIndexOf('.')); diff --git a/rewrite-core/src/test/java/org/openrewrite/ApplicabilityTest.java b/rewrite-core/src/test/java/org/openrewrite/ApplicabilityTest.java new file mode 100644 index 00000000000..a02c03eca6b --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/ApplicabilityTest.java @@ -0,0 +1,118 @@ +/* + * Copyright 2022 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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; + +import org.junit.jupiter.api.Test; +import org.openrewrite.marker.SearchResult; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; +import org.openrewrite.text.PlainText; +import org.openrewrite.text.PlainTextVisitor; + +import static org.openrewrite.test.SourceSpecs.text; + +class ApplicabilityTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.validateRecipeSerialization(false); + } + + @Test + void not() { + rewriteRun( + spec -> spec.recipe(recipe(Applicability.not(contains("z")))), + text("hello", "goodbye") + ); + } + + @Test + void notNot() { + rewriteRun( + spec -> spec.recipe(recipe(Applicability.not(contains("h")))), + text("hello") + ); + } + + + @Test + void or() { + rewriteRun( + spec -> spec.recipe(recipe(Applicability.or(contains("h"), contains("z")))), + text("hello", "goodbye") + ); + } + + @Test + void notOr() { + rewriteRun( + spec -> spec.recipe(recipe(Applicability.or(contains("x"), contains("z")))), + text("hello") + ); + } + + @Test + void and() { + rewriteRun( + spec -> spec.recipe(recipe(Applicability.and(contains("h"), contains("ello")))), + text("hello", "goodbye") + ); + } + + @Test + void notAnd() { + rewriteRun( + spec -> spec.recipe(recipe(Applicability.and(contains("h"), contains("z")))), + text("hello") + ); + } + + Recipe recipe(TreeVisitor applicability) { + return new Recipe() { + @Override + public String getDisplayName() { + return "Say goodbye"; + } + + @Override + protected TreeVisitor getSingleSourceApplicableTest() { + return applicability; + } + + @Override + protected TreeVisitor getVisitor() { + return new PlainTextVisitor<>() { + @Override + public PlainText visitText(PlainText text, ExecutionContext executionContext) { + return text.withText("goodbye"); + } + }; + } + }; + } + + PlainTextVisitor contains(String s) { + return new PlainTextVisitor<>() { + @Override + public PlainText visitText(PlainText text, ExecutionContext executionContext) { + if (text.getText().contains(s)) { + return SearchResult.found(text); + } + return text; + } + }; + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/CursorTest.java b/rewrite-core/src/test/java/org/openrewrite/CursorTest.java new file mode 100644 index 00000000000..b5cbd6a00ff --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/CursorTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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; + +import org.junit.jupiter.api.Test; +import org.openrewrite.marker.Markers; +import org.openrewrite.text.PlainText; + +import java.nio.file.Paths; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.openrewrite.Tree.randomId; + +class CursorTest { + @Test + void peekMessages() { + var t = new PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test"); + var cursor = new Cursor(null, t); + + cursor.putMessage("key", 1); + assertThat(cursor.getNearestMessage("key")).isEqualTo(1); + + var child = new Cursor(cursor, t); + assertThat(child.getNearestMessage("key")).isEqualTo(1); + } + + @Test + void pollMessages() { + var t = new PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test"); + var cursor = new Cursor(null, t); + + cursor.putMessage("key", 1); + assertThat(cursor.pollNearestMessage("key")).isEqualTo(1); + assertThat(cursor.pollNearestMessage("key")).isNull(); + + cursor.putMessage("key", 1); + var child = new Cursor(cursor, t); + assertThat(child.getNearestMessage("key")).isEqualTo(1); + } + + @Test + void pathPredicates() { + var t = new PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test"); + var cursor = new Cursor(new Cursor(new Cursor(null, 1), t), 2); + assertThat(cursor.getPath(v -> v instanceof PlainText).next()).isSameAs(t); + } + + @Test + void pathAsStreamPredicates() { + var t = new PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test"); + var cursor = new Cursor(new Cursor(new Cursor(null, 1), t), 2); + assertThat(cursor.getPathAsStream(v -> v instanceof PlainText).toList()).containsExactly(t); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/ExecutionContextTest.java b/rewrite-core/src/test/java/org/openrewrite/ExecutionContextTest.java new file mode 100644 index 00000000000..c6f0703d296 --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/ExecutionContextTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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; + +import org.junit.jupiter.api.Test; +import org.openrewrite.internal.lang.Nullable; +import org.openrewrite.test.RewriteTest; +import org.openrewrite.text.PlainText; +import org.openrewrite.text.PlainTextVisitor; + +import java.util.concurrent.atomic.AtomicInteger; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.openrewrite.test.RewriteTest.toRecipe; +import static org.openrewrite.test.SourceSpecs.text; + +class ExecutionContextTest implements RewriteTest { + + @Test + void anotherCycleIfNewMessagesInExecutionContext() { + var cycles = new AtomicInteger(); + rewriteRun( + spec -> spec.recipe(toRecipe(() -> new PlainTextVisitor<>() { + @Override + public @Nullable PlainText visit(@Nullable Tree tree, ExecutionContext p) { + if(p.pollMessage("test") == null) { + p.putMessage("test", "test"); + } + cycles.incrementAndGet(); + return super.visit(tree, p); + } + }).withCausesAnotherCycle(true)), + text("hello world") + ); + assertThat(cycles.get()).isEqualTo(2); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/RecipeBasicsTest.java b/rewrite-core/src/test/java/org/openrewrite/RecipeBasicsTest.java index 7f55ebb3a13..8bbfea34a97 100644 --- a/rewrite-core/src/test/java/org/openrewrite/RecipeBasicsTest.java +++ b/rewrite-core/src/test/java/org/openrewrite/RecipeBasicsTest.java @@ -23,9 +23,16 @@ import java.util.HashMap; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; public class RecipeBasicsTest { + @Test + void recipeDoNextWithItself() { + Recipe r = Recipe.noop(); + assertThrows(IllegalArgumentException.class, () -> r.doNext(r)); + } + @Test void cloneRecipe() throws JsonMappingException { ChangeText ct = new ChangeText("hi"); diff --git a/rewrite-core/src/test/java/org/openrewrite/RecipeLifecycleTest.java b/rewrite-core/src/test/java/org/openrewrite/RecipeLifecycleTest.java new file mode 100644 index 00000000000..3e51b0441f5 --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/RecipeLifecycleTest.java @@ -0,0 +1,312 @@ +/* + * Copyright 2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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; + +import org.intellij.lang.annotations.Language; +import org.junit.jupiter.api.Test; +import org.openrewrite.config.RecipeDescriptor; +import org.openrewrite.internal.ListUtils; +import org.openrewrite.internal.lang.Nullable; +import org.openrewrite.marker.Markers; +import org.openrewrite.test.RewriteTest; +import org.openrewrite.text.ChangeText; +import org.openrewrite.text.PlainText; +import org.openrewrite.text.PlainTextVisitor; + +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; +import static org.openrewrite.Recipe.NOOP; +import static org.openrewrite.Recipe.noop; +import static org.openrewrite.Tree.randomId; +import static org.openrewrite.test.RewriteTest.toRecipe; +import static org.openrewrite.test.SourceSpecs.text; + +class RecipeLifecycleTest implements RewriteTest { + + @Test + void panic() { + var ctx = new InMemoryExecutionContext(); + ctx.putMessage(Recipe.PANIC, true); + + rewriteRun( + spec -> spec.recipe(toRecipe(() -> new TreeVisitor<>() { + @Override + public Tree visit(@Nullable Tree tree, ExecutionContext executionContext) { + fail("Should never have reached a visit method"); + return tree; + } + })).executionContext(ctx), + text("hello") + ); + } + + @Test + void notApplicableRecipe() { + rewriteRun( + spec -> spec.recipe(toRecipe(() -> new PlainTextVisitor<>() { + @Override + public PlainText visitText(PlainText text, ExecutionContext executionContext) { + return text.withText("goodbye"); + } + }).addApplicableTest(NOOP)), + text("hello") + ); + } + + @Test + void generateFile() { + rewriteRun( + spec -> spec + .recipe(toRecipe() + .withVisit((before, ctx) -> ListUtils.concat(before, new PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test"))) + .withName("test.GeneratingRecipe") + ) + .afterRecipe(run -> assertThat(run.getResults().stream() + .map(r -> r.getRecipeDescriptorsThatMadeChanges().get(0).getName())) + .containsOnly("test.GeneratingRecipe")) + .cycles(1).expectedCyclesThatMakeChanges(1), + text(null, "test", spec -> spec.path("test.txt")) + ); + } + + @Test + void deleteFile() { + var results = new Recipe() { + @Override + public String getName() { + return "test.DeletingRecipe"; + } + + @Override + public String getDisplayName() { + return getName(); + } + + @Override + protected List visit(List before, ExecutionContext ctx) { + return Collections.emptyList(); + } + }.run(List.of(new PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test"))).getResults(); + + assertThat(results.stream().map(r -> r.getRecipeDescriptorsThatMadeChanges().get(0).getName())) + .containsExactly("test.DeletingRecipe"); + } + + @Test + void deleteFileByReturningNullFromVisit() { + rewriteRun( + spec -> spec.recipe(toRecipe(() -> new PlainTextVisitor<>() { + @Override + public @Nullable PlainText visit(@Nullable Tree tree, ExecutionContext executionContext) { + return null; + } + })), + text( + "hello", + (String) null + ) + ); + } + + class FooVisitor

extends TreeVisitor { + @Override + public @Nullable FooSource preVisit(FooSource tree, P p) { + //noinspection ConstantConditions + if (!(tree instanceof FooSource)) { + throw new RuntimeException("tree is not a FooSource"); + } + return super.preVisit(tree, p); + } + + @Override + public @Nullable FooSource postVisit(FooSource tree, P p) { + //noinspection ConstantConditions + if (!(tree instanceof FooSource)) { + throw new RuntimeException("tree is not a FooSource"); + } + return super.postVisit(tree, p); + } + } + + class FooSource implements SourceFile { + @Override + public Path getSourcePath() { + throw new UnsupportedOperationException(); + } + + @Override + public T withSourcePath(Path path) { + throw new UnsupportedOperationException(); + } + + @Override + public @Nullable Charset getCharset() { + throw new UnsupportedOperationException(); + } + + @Override + public T withCharset(Charset charset) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isCharsetBomMarked() { + return false; + } + + @Override + public T withCharsetBomMarked(boolean marked) { + throw new UnsupportedOperationException(); + } + + @Override + public @Nullable Checksum getChecksum() { + throw new UnsupportedOperationException(); + } + + @Override + public T withChecksum(@Nullable Checksum checksum) { + throw new UnsupportedOperationException(); + } + + @Override + public @Nullable FileAttributes getFileAttributes() { + throw new UnsupportedOperationException(); + } + + @Override + public T withFileAttributes(@Nullable FileAttributes fileAttributes) { + throw new UnsupportedOperationException(); + } + + @Override + public UUID getId() { + throw new UnsupportedOperationException(); + } + + @Override + public Markers getMarkers() { + throw new UnsupportedOperationException(); + } + + @Override + public T withMarkers(Markers markers) { + throw new UnsupportedOperationException(); + } + + @Override + public T withId(UUID id) { + throw new UnsupportedOperationException(); + } + + @Override + public

boolean isAcceptable(TreeVisitor v, P p) { + return v.isAdaptableTo(FooVisitor.class); + } + } + + @Issue("https://github.com/openrewrite/rewrite/issues/389") + @Test + void sourceFilesAcceptOnlyApplicableVisitors() { + var sources = List.of(new FooSource(), new PlainText(randomId(), Paths.get("test.txt"), Markers.build(List.of()), null, false, null, null, "Hello")); + var fooVisitor = new FooVisitor(); + var textVisitor = new PlainTextVisitor(); + var ctx = new InMemoryExecutionContext(); + + for (SourceFile source : sources) { + fooVisitor.visit(source, ctx); + textVisitor.visit(source, ctx); + } + } + + @Test + void accurateReportingOfRecipesMakingChanges() { + rewriteRun( + spec -> spec + .recipe(testRecipe("Change1").doNext(noop()).doNext(testRecipe("Change2"))) + .validateRecipeSerialization(false) + .afterRecipe(run -> { + var results = run.getResults(); + assertThat(results).hasSize(1); + assertThat(results.get(0).getRecipeDescriptorsThatMadeChanges().stream().map(RecipeDescriptor::getName)) + .containsExactlyInAnyOrder("Change1", "Change2"); + }) + .cycles(1).expectedCyclesThatMakeChanges(1), + text( + "Hello", + "Change2Change1Hello" + ) + ); + } + + @Test + void recipeDescriptorsReturnCorrectStructure() { + Recipe r = noop(); + r.doNext(testRecipe("A") + .doNext(testRecipe("B") + .doNext(testRecipe("D") + .doNext(testRecipe("C")))) + .doNext(noop())); + r.doNext(testRecipe("A") + .doNext(testRecipe("B") + .doNext(testRecipe("E")) + .doNext(new ChangeText("E1")) + .doNext(new ChangeText("E2")))); + r.doNext(testRecipe("E") + .doNext(testRecipe("F"))); + r.doNext(noop()); + + rewriteRun( + spec -> spec + .recipe(r) + .validateRecipeSerialization(false) + .afterRecipe(run -> { + var results = run.getResults(); + var recipeDescriptors = results.get(0).getRecipeDescriptorsThatMadeChanges(); + assertThat(recipeDescriptors).hasSize(2); + + var aDescriptor = recipeDescriptors.get(0); + var bDescriptor = aDescriptor.getRecipeList().get(0); + // B (2 test recipes, 2 ChangeText with different options and 1 noChangeRecipe) resulting in 4 changes + assertThat(bDescriptor.getName()).isEqualTo("B"); + assertThat(bDescriptor.getRecipeList()).hasSize(4); + }) + .cycles(1).expectedCyclesThatMakeChanges(1), + text( + "Hello", + "FE2") + ); + } + + private Recipe testRecipe(@Language("markdown") String name) { + return toRecipe(() -> new PlainTextVisitor<>() { + @Override + public PlainText visitText(PlainText text, ExecutionContext executionContext) { + if (!text.getText().contains(name)) { + return text.withText(name + text.getText()); + } + return super.visitText(text, executionContext); + } + }).withName(name); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/RecipeSchedulerTest.java b/rewrite-core/src/test/java/org/openrewrite/RecipeSchedulerTest.java new file mode 100644 index 00000000000..b10c6c6939c --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/RecipeSchedulerTest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2022 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; +import org.openrewrite.text.PlainText; +import org.openrewrite.text.PlainTextVisitor; + +import java.util.Arrays; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.openrewrite.test.SourceSpecs.text; + +public class RecipeSchedulerTest implements RewriteTest { + + @Test + void exceptionsCauseResult() { + rewriteRun( + spec -> spec + .executionContext(new InMemoryExecutionContext()) + .recipe(new BoomRecipe()) + .afterRecipe(run -> assertThat(run.getResults().get(0).getRecipeErrors()).isNotEmpty()), + text( + "hello", + "~~(boom)~~>hello" + ) + ); + } +} + +class BoomRecipe extends Recipe { + @Override + public String getDisplayName() { + return "We go boom"; + } + + @Override + public String getDescription() { + return "Test recipe."; + } + + @Override + protected TreeVisitor getVisitor() { + return new PlainTextVisitor<>() { + @Override + public PlainText visitText(PlainText text, ExecutionContext executionContext) { + throw new BoomException(); + } + }; + } +} + +/** + * Simplified exception that only displays stack trace elements within the [BoomRecipe]. + */ +class BoomException extends RuntimeException { + public BoomException() { + super("boom"); + } + + @Override + public StackTraceElement[] getStackTrace() { + return Arrays.stream(super.getStackTrace()) + .filter(st -> st.getClassName().startsWith(BoomRecipe.class.getName())) + .toArray(StackTraceElement[]::new); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/ResultTest.java b/rewrite-core/src/test/java/org/openrewrite/ResultTest.java new file mode 100644 index 00000000000..9e9b5eef54a --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/ResultTest.java @@ -0,0 +1,219 @@ +/* + * Copyright 2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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; + +import org.junit.jupiter.api.Test; +import org.openrewrite.internal.StringUtils; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.LinkedHashSet; +import java.util.Set; + +import static java.util.Collections.emptySet; +import static org.assertj.core.api.Assertions.assertThat; +import static org.openrewrite.test.RewriteTest.toRecipe; + +class ResultTest { + private final Path filePath = Paths.get("com/netflix/MyJavaClass.java"); + + private String ab(String which) { + return which + "/" + filePath.toString().replace("\\", "/"); + } + + @Test + void idempotent() { + try (var diff = new Result.InMemoryDiffEntry( + Paths.get("com/netflix/MyJavaClass.java"), + Paths.get("com/netflix/MyJavaClass.java"), + null, + "public class A {}", + "public class A {}", + emptySet() + )) { + assertThat(diff.getDiff()).isEmpty(); + } + } + + @Test + void ignoreWhitespace() { + try (var diff = new Result.InMemoryDiffEntry( + Paths.get("com/netflix/MyJavaClass.java"), + Paths.get("com/netflix/MyJavaClass.java"), + null, + "public class A {} ", + "public class A {}", + emptySet() + )) { + var diffNoWs = diff.getDiff(true); + assertThat( + """ + diff --git a/com/netflix/MyJavaClass.java b/com/netflix/MyJavaClass.java + index 9bfeb36..efd7fa3 100644 + --- a/com/netflix/MyJavaClass.java + +++ b/com/netflix/MyJavaClass.java + """.trim() + ).isEqualTo(StringUtils.trimIndent(diffNoWs)); + } + } + + @Test + void singleLineChange() { + try (var result = new Result.InMemoryDiffEntry( + filePath, filePath, null, + """ + public void test() { + logger.infof("some %s", 1); + } + """, + """ + public void test() { + logger.info("some {}", 1); + } + """, + Set.of(toRecipe().withName("logger.Fix")))) { + assertThat(result.getDiff()).isEqualTo( + """ + diff --git %s %s + index 3490cbf..5d64ae4 100644 + --- %s + +++ %s + @@ -1,3 +1,3 @@ logger.Fix + public void test() { + - logger.infof("some %%s", 1); + + logger.info("some {}", 1); + } + """.formatted(ab("a"), ab("b"), ab("a"), ab("b")) + ); + } + } + + @Test + void multipleChangesMoreThanThreeLinesApart() { + try (var result = new Result.InMemoryDiffEntry( + filePath, filePath, null, + """ + public void test() { + logger.infof("some %s", 1); + System.out.println("1"); + System.out.println("2"); + System.out.println("3"); + System.out.println("4"); + System.out.println("5"); + System.out.println("6"); + System.out.println("7"); + System.out.println("8"); + logger.infof("some %s", 2); + } + """, + """ + public void test() { + logger.info("some {}", 1); + System.out.println("1"); + System.out.println("2"); + System.out.println("3"); + System.out.println("4"); + System.out.println("5"); + System.out.println("6"); + System.out.println("7"); + System.out.println("8"); + logger.info("some %s", 2); + } + """, + new LinkedHashSet<>() {{ + add(toRecipe().withName("logger.Fix1")); + add(toRecipe().withName("logger.Fix2")); + }} + )) { + assertThat(result.getDiff()).isEqualTo( + """ + diff --git %s %s + index c17f051..bb2dfba 100644 + --- %s + +++ %s + @@ -1,5 +1,5 @@ logger.Fix1, logger.Fix2 + public void test() { + - logger.infof("some %%s", 1); + + logger.info("some {}", 1); + System.out.println("1"); + System.out.println("2"); + System.out.println("3"); + @@ -8,5 +8,5 @@ + System.out.println("6"); + System.out.println("7"); + System.out.println("8"); + - logger.infof("some %%s", 2); + + logger.info("some %%s", 2); + } + """.formatted(ab("a"), ab("b"), ab("a"), ab("b")) + ); + } + } + + @Test + void addFile() { + try (var result = new Result.InMemoryDiffEntry( + null, filePath, null, + "", + """ + public void test() { + logger.info("Hello Fred"); + } + """, + Set.of(toRecipe().withName("logger.Fix1")))) { + assertThat(result.getDiff()).isEqualTo( + """ + diff --git a/com/netflix/MyJavaClass.java b/com/netflix/MyJavaClass.java + new file mode 100644 + index 0000000..efeb105 + --- /dev/null + +++ b/com/netflix/MyJavaClass.java + @@ -0,0 +1,3 @@ logger.Fix1 + +public void test() { + + logger.info("Hello Fred"); + +} + """ + ); + } + } + + @Test + void deleteFile() { + try (var result = new Result.InMemoryDiffEntry( + filePath, null, null, + """ + public void test() { + logger.info("Hello Fred"); + } + """, + "", + Set.of(toRecipe().withName("logger.Fix1")))) { + assertThat(result.getDiff()).isEqualTo( + """ + diff --git a/com/netflix/MyJavaClass.java b/com/netflix/MyJavaClass.java + deleted file mode 100644 + index efeb105..0000000 + --- a/com/netflix/MyJavaClass.java + +++ /dev/null + @@ -1,3 +0,0 @@ logger.Fix1 + -public void test() { + - logger.info("Hello Fred"); + -} + """ + ); + } + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/TreeObserverTest.java b/rewrite-core/src/test/java/org/openrewrite/TreeObserverTest.java new file mode 100644 index 00000000000..7e4bdce832f --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/TreeObserverTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2022 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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; + +import org.junit.jupiter.api.Test; +import org.openrewrite.test.RewriteTest; +import org.openrewrite.text.PlainText; +import org.openrewrite.text.PlainTextVisitor; + +import java.util.concurrent.atomic.AtomicInteger; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.openrewrite.test.RewriteTest.toRecipe; +import static org.openrewrite.test.SourceSpecs.text; + +class TreeObserverTest implements RewriteTest { + + @Test + void observePropertyChange() { + var observed = new AtomicInteger(0); + + rewriteRun( + spec -> spec + .recipe(toRecipe(() -> new PlainTextVisitor<>() { + @Override + public PlainText visitText(PlainText text, ExecutionContext executionContext) { + return text.withText("hello jonathan"); + } + })) + .cycles(1) + .expectedCyclesThatMakeChanges(1) + .executionContext(new InMemoryExecutionContext().addObserver(new TreeObserver.Subscription(new TreeObserver() { + @Override + public Tree propertyChanged(String property, Cursor cursor, Tree newTree, Object oldValue, Object newValue) { + if (property.equals("text")) { + observed.incrementAndGet(); + } + return newTree; + } + }).subscribeToType(PlainText.class))), + text( + "hello jon", + "hello jonathan" + ) + ); + + assertThat(observed.get()).isEqualTo(1); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/internal/ListUtilsTest.java b/rewrite-core/src/test/java/org/openrewrite/internal/ListUtilsTest.java new file mode 100644 index 00000000000..90b4fe776da --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/internal/ListUtilsTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.internal; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class ListUtilsTest { + + @Test + void flatMap() { + var l = List.of(1.0, 2.0, 3.0); + assertThat(ListUtils.flatMap(l, l2 -> l2.intValue() % 2 == 0 ? List.of(2.0, 2.1, 2.2) : l2)) + .containsExactly(1.0, 2.0, 2.1, 2.2, 3.0); + } + + @Test + void replaceSingleWithMultipleAtPosition0() { + var l = List.of(1); + assertThat(ListUtils.flatMap(l, l2 -> List.of(2, 3))) + .containsExactly(2, 3); + } + + @Test + void removeSingleItem() { + var l = List.of(1, 2, 3); + assertThat(ListUtils.flatMap(l, l1 -> l1.equals(2) ? null : l1)) + .containsExactly(1, 3); + } + + @Test + void replaceItemWithCollectionThenRemoveNextItem() { + var l = List.of(2, 0); + assertThat(ListUtils.flatMap(l, l1 -> l1.equals(2) ? List.of(10, 11) : null)) + .containsExactly(10, 11); + } + + @Test + void removeByAddingEmptyCollection() { + var l = List.of(2, 0); + assertThat(ListUtils.flatMap(l, l1 -> l1.equals(2) ? List.of(10, 11) : List.of())) + .containsExactly(10, 11); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/internal/NameCaseConventionTest.java b/rewrite-core/src/test/java/org/openrewrite/internal/NameCaseConventionTest.java new file mode 100644 index 00000000000..4856033fe07 --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/internal/NameCaseConventionTest.java @@ -0,0 +1,138 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.internal; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static org.assertj.core.api.Assertions.assertThat; + +class NameCaseConventionTest { + + @ParameterizedTest + @CsvSource(value = { + "foo.config-client.enabled:foo.config-client.enabled", + "com.fooBar.FooBar:com.foo-bar.foo-bar", + "foo_bar.bar:foo-bar.bar", + "FooBar:foo-bar", + "com.bar.FooBar:com.bar.foo-bar", + "Foo:foo", + "FooBBar:foo-bbar", + "fooBBar:foo-bbar", + "fooBar:foo-bar", + "foo bar:foo-bar", + " foo bar :foo-bar", + }, delimiter = ':') + void lowerHyphen(String input, String expected) { + assertThat(NameCaseConvention.LOWER_HYPHEN.format(input)).isEqualTo(expected); + } + + @ParameterizedTest + @CsvSource(value = { + "a:a", + "abc:abc", + "1:1", + "123:123", + "1a:1a", + "a1:a1", + "$:$", + "$a:$a", + "a$:a$", + "a$a:a$a", + "a_a:a_a", + "Foo:foo", + "Foo-Bar:foo_bar", + "FOO.FOO-BAR:foo.foo_bar", + "foo bar:foo_bar", + " foo bar :foo_bar", + }, delimiter = ':') + void lowerUnderscore(String input, String expected) { + assertThat(NameCaseConvention.LOWER_UNDERSCORE.format(input)).isEqualTo(expected); + } + + @ParameterizedTest + @CsvSource(value = { + "ID:id", + "rename_one:renameOne", + "RenameTwo:renameTwo", + "__rename__three__:renameThree", + "_Rename___Four_:renameFour", + "$a:$a", + "a$:a$", + "a$a:a$a", + "a_a:aA", + "_a:a", + "foo.config-client.enabled:foo.configClient.enabled", + "foo-bar:fooBar", + "foo bar:fooBar", + " foo bar :fooBar", + "FOO_BAR:fooBar", + }, delimiter = ':') + void lowerCamel(String input, String expected) { + assertThat(NameCaseConvention.LOWER_CAMEL.format(input)).isEqualTo(expected); + } + + @ParameterizedTest + @CsvSource(value = { + "rename_one:RenameOne", + "RenameTwo:RenameTwo", + "__rename__three__:RenameThree", + "_Rename__Four:RenameFour", + "foo-bar:FooBar", + "foo bar:FooBar", + " foo bar :FooBar", + }, delimiter = ':') + void upperCamel(String input, String expected) { + assertThat(NameCaseConvention.UPPER_CAMEL.format(input)).isEqualTo(expected); + } + + @ParameterizedTest + @CsvSource(value = { + "foo:FOO", + "foo-bar:FOO_BAR", + "foo_bar:FOO_BAR", + "FooBar:FOO_BAR", + "Foo.fooBar:FOO.FOO_BAR", + "foo bar:FOO_BAR", + " foo bar :FOO_BAR", + }, delimiter = ':') + void upperUnderscore(String input, String expected) { + assertThat(NameCaseConvention.UPPER_UNDERSCORE.format(input)).isEqualTo(expected); + } + + @ParameterizedTest + @CsvSource(value = { + "foo.fooBar:foo.foo-bar", + "foo.foo-bar:foo.fooBar", + }, delimiter = ':') + void equalsRelaxedBinding(String input, String expected) { + assertThat(NameCaseConvention.equalsRelaxedBinding(input, expected)).isTrue(); + } + + @Test + void matchesRelaxedBinding() { + assertThat(NameCaseConvention.matchesRelaxedBinding( + "spring.registration.test.identityprovider", + "spring.registration.*.identityprovider" + )).isTrue(); + + assertThat(NameCaseConvention.matchesRelaxedBinding( + "spring.registration.test.assertingparty", + "spring.registration.*.identityprovider" + )).isFalse(); + } +} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/internal/PropertyPlaceholderHelperTest.kt b/rewrite-core/src/test/java/org/openrewrite/internal/PropertyPlaceholderHelperTest.java similarity index 58% rename from rewrite-core/src/test/kotlin/org/openrewrite/internal/PropertyPlaceholderHelperTest.kt rename to rewrite-core/src/test/java/org/openrewrite/internal/PropertyPlaceholderHelperTest.java index ad788d23f8f..532bdd46c93 100644 --- a/rewrite-core/src/test/kotlin/org/openrewrite/internal/PropertyPlaceholderHelperTest.kt +++ b/rewrite-core/src/test/java/org/openrewrite/internal/PropertyPlaceholderHelperTest.java @@ -13,23 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openrewrite.internal +package org.openrewrite.internal; -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; class PropertyPlaceholderHelperTest { @Test - fun dashed() { - val helper = PropertyPlaceholderHelper("%%{", "}", null) - val s = helper.replacePlaceholders("%%{k1} %%{k2}") { k -> - when(k) { - "k1" -> "hi" - "k2" -> "jon" - else -> TODO() - } - } - assertThat(s).isEqualTo("hi jon") + void dashed() { + var helper = new PropertyPlaceholderHelper("%%{", "}", null); + var s = helper.replacePlaceholders("%%{k1} %%{k2}", k -> switch (k) { + case "k1" -> "hi"; + case "k2" -> "jon"; + default -> throw new UnsupportedOperationException(); + }); + assertThat(s).isEqualTo("hi jon"); } } diff --git a/rewrite-core/src/test/java/org/openrewrite/internal/StringUtilsTest.java b/rewrite-core/src/test/java/org/openrewrite/internal/StringUtilsTest.java new file mode 100644 index 00000000000..f27cc8a0562 --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/internal/StringUtilsTest.java @@ -0,0 +1,126 @@ +/* + * Copyright 2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.internal; + +import org.junit.jupiter.api.Test; +import org.openrewrite.Issue; + +import static org.openrewrite.internal.StringUtils.*; + +import static org.assertj.core.api.Assertions.assertThat; + +class StringUtilsTest { + + @Test + void containsOnlyWhitespaceAndCommentsTest() { + assertThat(containsOnlyWhitespaceAndComments("")).isTrue(); + assertThat(containsOnlyWhitespaceAndComments(" \n\r\t")).isTrue(); + assertThat(containsOnlyWhitespaceAndComments(" // hello ")).isTrue(); + assertThat(containsOnlyWhitespaceAndComments("//")).isTrue(); + assertThat(containsOnlyWhitespaceAndComments("/**/")).isTrue(); + assertThat(containsOnlyWhitespaceAndComments(""" + /** + asdf + */ + """)).isTrue(); + + assertThat(containsOnlyWhitespaceAndComments("a")).isFalse(); + assertThat(containsOnlyWhitespaceAndComments(""" + // hello + goodbye + """)).isFalse(); + assertThat(containsOnlyWhitespaceAndComments("a//")).isFalse(); + assertThat(containsOnlyWhitespaceAndComments( + """ + /* + */ + a + """)).isFalse(); + } + + @Test + void replaceFirst() { + var result = StringUtils.replaceFirst("#{} Fred #{}", "#{}", "I am"); + assertThat(result).isEqualTo("I am Fred #{}"); + result = StringUtils.replaceFirst(result, "#{}", "surely."); + assertThat(result).isEqualTo("I am Fred surely."); + result = StringUtils.replaceFirst("#{}#{}#{}", "#{}", "yo"); + assertThat(result).isEqualTo("yo#{}#{}"); + result = StringUtils.replaceFirst(result, "#{}", "yo"); + assertThat(result).isEqualTo("yoyo#{}"); + result = StringUtils.replaceFirst(result, "#{}", "yo"); + assertThat(result).isEqualTo("yoyoyo"); + result = StringUtils.replaceFirst("Nothing to see here", "#{}", "nonsense"); + assertThat(result).isEqualTo("Nothing to see here"); + result = StringUtils.replaceFirst("Nothing to see here", "", "nonsense"); + assertThat(result).isEqualTo("Nothing to see here"); + result = StringUtils.replaceFirst("", "", "nonsense"); + assertThat(result).isEqualTo(""); + } + + @Test + void occurrenceCount() { + assertThat(countOccurrences("yoyoyoyoyo", "yo")).isEqualTo(5); + assertThat(countOccurrences("yoyoyoyoyo", "yoyo")).isEqualTo(2); + assertThat(countOccurrences("nonononono", "yo")).isEqualTo(0); + assertThat(countOccurrences("", "")).isEqualTo(0); + } + + @Test + void globMatching() { + assertThat(matchesGlob("expression", "expr*")).isTrue(); + assertThat(matchesGlob("some/xpath", "some/*")).isTrue(); + assertThat(matchesGlob("some/xpath/expression", "some/**")).isTrue(); + assertThat(matchesGlob("//some/xpath/expression", "**/xpath/*")).isTrue(); + } + + @SuppressWarnings("TextBlockMigration") + @Test + void greatestCommonMargin() { + assertThat(StringUtils.greatestCommonMargin( + "" + + " \n" + + " \n" + + " \n")).isEqualTo(" "); + + assertThat(StringUtils.greatestCommonMargin( + "" + + " \n" + + " s \n" + + " \n")).isEqualTo(" "); + + assertThat(StringUtils.greatestCommonMargin("")).isEqualTo(""); + assertThat(StringUtils.greatestCommonMargin("\n\n")).isEqualTo(""); + } + + @Test + void greatestCommonSubstringLength() { + assertThat(StringUtils.greatestCommonSubstringLength("", "")).isEqualTo(0); + assertThat(StringUtils.greatestCommonSubstringLength("abc", "def")).isEqualTo(0); + assertThat(StringUtils.greatestCommonSubstringLength("abc1", "1")).isEqualTo(1); + } + + @Test + void allowConsecutiveLineBreaks() { + assertThat(trimIndentPreserveCRLF(" \n \n a")).isEqualTo("\n\na"); + } + + @Issue("https://github.com/openrewrite/rewrite/issues/2268") + @Test + void trailingCrlf() { + assertThat(trimIndentPreserveCRLF(" \r\n \r\n a\r\n")).isEqualTo("\r\n\r\na"); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/internal/lang/NullUtilsTest.java b/rewrite-core/src/test/java/org/openrewrite/internal/lang/NullUtilsTest.java new file mode 100644 index 00000000000..6b87e86024c --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/internal/lang/NullUtilsTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2020 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.internal.lang; + +import org.junit.jupiter.api.Test; +import org.openrewrite.internal.lang.nonnull.DefaultNonNullTest; +import org.openrewrite.internal.lang.nullable.NonNullTest; + +import static org.assertj.core.api.Assertions.assertThat; + +class NullUtilsTest { + + @Test + void testPackageNonNullDefault() { + var results = NullUtils.findNonNullFields(DefaultNonNullTest.class); + assertThat(results).hasSize(4); + assertThat(results.get(0).getName()).isEqualTo("aCoolNonNullName"); + assertThat(results.get(1).getName()).isEqualTo("beCoolNonNullName"); + assertThat(results.get(2).getName()).isEqualTo("coolNonNullName"); + assertThat(results.get(3).getName()).isEqualTo("yourCoolNonNullName"); + } + + @Test + void testNonNulls() { + var results = NullUtils.findNonNullFields(NonNullTest.class); + assertThat(results).hasSize(4); + assertThat(results.get(0).getName()).isEqualTo("aCoolNonNullName"); + assertThat(results.get(1).getName()).isEqualTo("beCoolNonNullName"); + assertThat(results.get(2).getName()).isEqualTo("coolNonNullName"); + assertThat(results.get(3).getName()).isEqualTo("yourCoolNonNullName"); + } + + @Test + void noMemberFields() { + var results = NullUtils.findNonNullFields(NoMembers.class); + assertThat(results).isEmpty(); + } + + static class NoMembers { + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/marker/GitProvenanceTest.java b/rewrite-core/src/test/java/org/openrewrite/marker/GitProvenanceTest.java new file mode 100644 index 00000000000..ec83c796daf --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/marker/GitProvenanceTest.java @@ -0,0 +1,234 @@ +/* + * Copyright 2022 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.marker; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.RepositoryCache; +import org.eclipse.jgit.transport.TagOpt; +import org.eclipse.jgit.transport.URIish; +import org.eclipse.jgit.util.FS; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.openrewrite.marker.ci.JenkinsBuildEnvironment; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_BRANCH_SECTION; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import static org.openrewrite.Tree.randomId; + +@Disabled("How to deal with FS signer information not matching?") +@SuppressWarnings("ConstantConditions") +class GitProvenanceTest { + + private static Stream remotes() { + return Stream.of( + "ssh://git@github.com/openrewrite/rewrite.git", + "https://github.com/openrewrite/rewrite.git", + "file:///openrewrite/rewrite.git", + "http://localhost:7990/scm/openrewrite/rewrite.git", + "git@github.com:openrewrite/rewrite.git" + ); + } + + @ParameterizedTest + @MethodSource("remotes") + void getOrganizationName(String remote) { + assertThat(new GitProvenance(randomId(), remote, "main", "123", null, null).getOrganizationName()) + .isEqualTo("openrewrite"); + } + + @ParameterizedTest + @MethodSource("remotes") + void getRepositoryName(String remote) { + assertThat(new GitProvenance(randomId(), remote, "main", "123", null, null).getRepositoryName()) + .isEqualTo("rewrite"); + } + + @Test + void localBranchPresent(@TempDir Path projectDir) throws GitAPIException { + try (Git g = Git.init().setDirectory(projectDir.toFile()).setInitialBranch("main").call()) { + GitProvenance git = GitProvenance.fromProjectDirectory(projectDir, null); + assertThat(git).isNotNull(); + assertThat(git.getBranch()).isEqualTo("main"); + } + } + + @Test + void detachedHead(@TempDir Path projectDir) throws GitAPIException, IOException, URISyntaxException { + try (Git git = initGitWithOneCommit(projectDir)) { + git.checkout().setName(git.getRepository().resolve(Constants.HEAD).getName()).call(); + assertThat(GitProvenance.fromProjectDirectory(projectDir, null).getBranch()) + .isEqualTo("main"); + } + } + + @Test + void detachedHeadJenkinsLocalBranch(@TempDir Path projectDir) throws GitAPIException, IOException, URISyntaxException { + try (Git git = initGitWithOneCommit(projectDir)) { + git.checkout().setName(git.getRepository().resolve(Constants.HEAD).getName()).call(); + assertThat( + GitProvenance.fromProjectDirectory( + projectDir, + new JenkinsBuildEnvironment( + randomId(), "1", "1", "https://jenkins/job/1", + "https://jenkins", "job", "main", "origin/main" + ) + ).getBranch() + ).isEqualTo("main"); + } + } + + @Test + void detachedHeadJenkinsNoLocalBranch(@TempDir Path projectDir) throws GitAPIException, IOException, URISyntaxException { + try (Git git = initGitWithOneCommit(projectDir)) { + git.checkout().setName(git.getRepository().resolve(Constants.HEAD).getName()).call(); + assertThat( + GitProvenance.fromProjectDirectory( + projectDir, + new JenkinsBuildEnvironment(randomId(), "1", "1", "https://jenkins/job/1", + "https://jenkins", "job", null, "origin/main") + ).getBranch() + ).isEqualTo("main"); + } + } + + private Git initGitWithOneCommit(Path projectDir) throws GitAPIException, IOException, URISyntaxException { + var git = Git.init().setDirectory(projectDir.toFile()).setInitialBranch("main").call(); + Files.writeString(projectDir.resolve("test.txt"), "hi"); + git.add().addFilepattern("*").call(); + git.commit().setMessage("init").setSign(false).call(); + git.remoteAdd().setName("origin").setUri(new URIish("git@github.com:openrewrite/doesnotexist.git")).call(); + + // origins are still present in .git/config on Jenkins + var config = git.getRepository().getConfig(); + config.setString(CONFIG_BRANCH_SECTION, "main", "remote", "origin"); + config.setString(CONFIG_BRANCH_SECTION, "main", "merge", "refs/heads/main"); + config.save(); + + return git; + } + + @Test + void detachedHeadBehindBranchHead(@TempDir Path projectDir) throws GitAPIException { + try (Git git = Git.init().setDirectory(projectDir.toFile()).setInitialBranch("main").call()) { + Files.writeString(projectDir.resolve("test.txt"), "hi"); + git.add().addFilepattern("*").call(); + git.commit().setMessage("init").setSign(false).call(); + var commit1 = git.getRepository().resolve(Constants.HEAD).getName(); + + Files.writeString(projectDir.resolve("test.txt"), "hi"); + git.add().addFilepattern("*").call(); + git.commit().setMessage("init").setSign(false).call(); + + assertThat(git.getRepository().resolve(Constants.HEAD).getName()).isNotEqualTo(commit1); + + git.checkout().setName(commit1).call(); + + assertThat(GitProvenance.fromProjectDirectory(projectDir, null).getBranch()) + .isEqualTo("main"); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Test + void shallowCloneDetachedHead(@TempDir Path projectDir) throws IOException, GitAPIException { + var remoteDir = projectDir.resolve("remote"); + var fileKey = RepositoryCache.FileKey.exact(remoteDir.toFile(), FS.DETECTED); + // push an initial commit to the remote + var cloneDir = projectDir.resolve("clone1"); + try (var remoteRepo = fileKey.open(false)) { + remoteRepo.create(true); + try (Git git = Git.cloneRepository().setURI(remoteRepo.getDirectory().getAbsolutePath()).setDirectory(cloneDir.toFile()).call()) { + Files.writeString(projectDir.resolve("test.txt"), "hi"); + git.add().addFilepattern("*").call(); + git.commit().setMessage("init").setSign(false).call(); + + runCommand(cloneDir, "git push -u origin main"); + var commit = git.getRepository().resolve(Constants.HEAD).getName(); + + // shallow clone the remote to another directory + runCommand(projectDir, "git clone file:///${remoteRepo.getDirectory().getAbsolutePath()} shallowClone --depth 1 --branch main"); + try (var git2 = Git.open(projectDir.resolve("shallowClone").toFile())) { + // creates detached head + git2.checkout().setName(commit).call(); + + assumeTrue(GitProvenance.fromProjectDirectory(projectDir.resolve("shallowClone"), null) != null); + assertThat(GitProvenance.fromProjectDirectory(projectDir.resolve("shallowClone"), null).getBranch()) + .isEqualTo(null); + } + } + } + } + + @Test + void noLocalBranchDeriveFromRemote(@TempDir Path projectDir) throws IOException, GitAPIException, URISyntaxException { + var remoteDir = projectDir.resolve("remote"); + var fileKey = RepositoryCache.FileKey.exact(remoteDir.toFile(), FS.DETECTED); + try (var remoteRepo = fileKey.open(false)) { + remoteRepo.create(true); + + // push an initial commit to the remote + var cloneDir = projectDir.resolve("clone1"); + try (Git gitSetup = Git.cloneRepository().setURI(remoteRepo.getDirectory().getAbsolutePath()).setDirectory(cloneDir.toFile()).call()) { + Files.writeString(projectDir.resolve("test.txt"), "hi"); + gitSetup.add().addFilepattern("*").call(); + var commit = gitSetup.commit().setMessage("init").setSign(false).call(); + gitSetup.push().add("master").setRemote("origin").call(); + + //Now create new workspace directory, git init and then fetch from remote. + var workspaceDir = projectDir.resolve("workspace"); + try (Git git = Git.init().setDirectory(workspaceDir.toFile()).call()) { + git.remoteAdd().setName("origin").setUri(new URIish(remoteRepo.getDirectory().getAbsolutePath())).call(); + git.fetch().setRemote("origin").setForceUpdate(true).setTagOpt(TagOpt.FETCH_TAGS).setRefSpecs("+refs/heads/*:refs/remotes/origin/*").call(); + git.checkout().setName(commit.getName()).call(); + } + } + } + + assumeTrue(GitProvenance.fromProjectDirectory(projectDir.resolve("workspace"), null) != null); + assertThat(GitProvenance.fromProjectDirectory(projectDir.resolve("workspace"), null).getBranch()) + .isEqualTo("master"); + } + + void runCommand(Path workingDir, String command) { + //noinspection ResultOfMethodCallIgnored + workingDir.toFile().mkdirs(); + try { + new ProcessBuilder(command.split(" ")) + .directory(workingDir.toFile()) + .redirectOutput(ProcessBuilder.Redirect.INHERIT) + .redirectError(ProcessBuilder.Redirect.INHERIT) + .start() + .waitFor(5, TimeUnit.SECONDS); + } catch (InterruptedException | IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/quark/QuarkParserTest.java b/rewrite-core/src/test/java/org/openrewrite/quark/QuarkParserTest.java new file mode 100644 index 00000000000..9d6ad3fda14 --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/quark/QuarkParserTest.java @@ -0,0 +1,117 @@ +/* + * Copyright 2022 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.quark; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.openrewrite.ExecutionContext; +import org.openrewrite.Result; +import org.openrewrite.SourceFile; +import org.openrewrite.TreeVisitor; +import org.openrewrite.test.RewriteTest; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.fail; +import static org.openrewrite.test.RewriteTest.toRecipe; +import static org.openrewrite.test.SourceSpecs.other; +import static org.openrewrite.test.SourceSpecs.text; + +class QuarkParserTest implements RewriteTest { + + @Test + void allOthers() { + rewriteRun( + spec -> spec.beforeRecipe(sources -> { + try { + List quarks = QuarkParser.parseAllOtherFiles(Paths.get("../"), sources); + assertThat(quarks).isNotEmpty(); + assertThat(quarks.stream().map(Quark::getSourcePath)) + .doesNotContain(Paths.get("build.gradle.kts")); + } catch (IOException e) { + throw new RuntimeException(e); + } + + }), + text("hi", spec -> spec.path(Paths.get("build.gradle.kts"))) + ); + } + + @Test + void oneQuark() { + rewriteRun( + spec -> spec.beforeRecipe(sources -> assertThat(sources.stream().filter(s -> s instanceof Quark)).hasSize(1)), + text("hi"), + other("jon") + ); + } + + @Disabled("How to deal with FS signer information not matching?") + @Test + void renameQuark(@TempDir Path tempDir) { + rewriteRun( + spec -> + spec + .expectedCyclesThatMakeChanges(1) + .recipe(toRecipe(() -> new TreeVisitor() { + @Override + public SourceFile visitSourceFile(SourceFile sourceFile, ExecutionContext executionContext) { + if (sourceFile.getSourcePath().toString().endsWith(".bak")) { + return sourceFile; + } + return sourceFile.withSourcePath(Paths.get(sourceFile.getSourcePath() + ".bak")); + } + })) + .afterRecipe(run -> { + try { + for (Result result : run.getResults()) { + try (var git = Git.init().setDirectory(tempDir.toFile()).call()) { + git.apply().setPatch(new ByteArrayInputStream(result.diff().getBytes())).call(); + } + } + assertThat(tempDir.toFile().list()) + .containsExactlyInAnyOrder("hi.txt.bak", "jon.bak", ".git"); + assertThat(Files.readString(tempDir.resolve("jon.bak")).trim()).isEqualTo("jon"); + } catch (IOException | GitAPIException e) { + fail(e); + } + }), + text( + "hi", + spec -> spec + .path("hi.txt") + .beforeRecipe(s -> Files.writeString(tempDir.resolve(s.getSourcePath()), "hi")) + .afterRecipe(s -> assertThat(s.getSourcePath()).isEqualTo(Paths.get("hi.txt.bak"))) + ), + other( + "jon", + spec -> spec + .path("jon") + .beforeRecipe(s -> Files.writeString(tempDir.resolve(s.getSourcePath()), "jon")) + .afterRecipe(s -> assertThat(s.getSourcePath()).isEqualTo(Paths.get("jon.bak"))) + ) + ); + } +} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/quark/QuarkTest.java b/rewrite-core/src/test/java/org/openrewrite/quark/QuarkTest.java similarity index 100% rename from rewrite-core/src/test/kotlin/org/openrewrite/quark/QuarkTest.java rename to rewrite-core/src/test/java/org/openrewrite/quark/QuarkTest.java diff --git a/rewrite-core/src/test/java/org/openrewrite/semver/CaretRangeTest.java b/rewrite-core/src/test/java/org/openrewrite/semver/CaretRangeTest.java new file mode 100644 index 00000000000..7d3aad92f72 --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/semver/CaretRangeTest.java @@ -0,0 +1,120 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.semver; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class CaretRangeTest { + + @Test + void isValidWhenCurrentIsNull() { + CaretRange caretRange = CaretRange.build("^1", null).getValue(); + + assertThat(caretRange).isNotNull(); + assertThat(caretRange.isValid(null, "1.0.0")).isTrue(); + } + + @Test + void pattern() { + assertThat(CaretRange.build("^1", null).isValid()).isTrue(); + assertThat(CaretRange.build("^1.2", null).isValid()).isTrue(); + assertThat(CaretRange.build("^1.2.3", null).isValid()).isTrue(); + assertThat(CaretRange.build("^1.2.3.4", null).isValid()).isTrue(); + assertThat(CaretRange.build("^1.2.3.4.5", null).isValid()).isFalse(); + } + + @Test + void updateMicro() { + CaretRange caretRange = CaretRange.build("^1.2.3.4", null).getValue(); + + assertThat(caretRange).isNotNull(); + assertThat(caretRange.isValid("1.0", "1.2.3.4")).isTrue(); + assertThat(caretRange.isValid("1.0", "1.2.3.4.RELEASE")).isTrue(); + assertThat(caretRange.isValid("1.0", "1.2.3.5")).isTrue(); + assertThat(caretRange.isValid("1.0", "1.2.4")).isTrue(); + assertThat(caretRange.isValid("1.0", "1.9.0")).isTrue(); + assertThat(caretRange.isValid("1.0", "1.2.3.3")).isFalse(); + assertThat(caretRange.isValid("1.0", "2.0.0")).isFalse(); + } + + /** + * ^1.2.3 := >=1.2.3 <2.0.0 + */ + @Test + void updateMinorAndPatch() { + CaretRange caretRange = CaretRange.build("^1.2.3", null).getValue(); + + assertThat(caretRange).isNotNull(); + assertThat(caretRange.isValid("1.0", "1.2.3")).isTrue(); + assertThat(caretRange.isValid("1.0", "1.2.3.RELEASE")).isTrue(); + assertThat(caretRange.isValid("1.0", "1.2.4")).isTrue(); + assertThat(caretRange.isValid("1.0", "1.9.0")).isTrue(); + assertThat(caretRange.isValid("1.0", "2.0.0")).isFalse(); + } + + /** + * ^0.2.3 := >=0.2.3 <0.3.0 + */ + @Test + void updatePatch() { + CaretRange caretRange = CaretRange.build("^0.2.3", null).getValue(); + + assertThat(caretRange).isNotNull(); + assertThat(caretRange.isValid("1.0", "0.2.3")).isTrue(); + assertThat(caretRange.isValid("1.0", "0.2.4")).isTrue(); + assertThat(caretRange.isValid("1.0", "0.3.0")).isFalse(); + } + + @Test + void updateNothing() { + CaretRange caretRange = CaretRange + .build("^0.0.3", null) + .getValue(); + + assertThat(caretRange).isNotNull(); + assertThat(caretRange.isValid("1.0", "0.0.3")).isFalse(); + assertThat(caretRange.isValid("1.0", "0.0.4")).isFalse(); + } + + /** + * ^1.x := >=1.0.0 <2.0.0 + */ + @Test + void desugarMinorWildcard() { + CaretRange caretRange = CaretRange.build("^1.x", null).getValue(); + + assertThat(caretRange).isNotNull(); + assertThat(caretRange.isValid("1.0", "1.0.0")).isTrue(); + assertThat(caretRange.isValid("1.0", "1.0.1")).isTrue(); + assertThat(caretRange.isValid("1.0", "1.1.0")).isTrue(); + assertThat(caretRange.isValid("1.0", "2.0.0")).isFalse(); + } + + /** + * ^0.0.x := >=0.0.0 <0.1.0 + */ + @Test + void desugarPatchWildcard() { + CaretRange caretRange = CaretRange.build("^0.0.x", null).getValue(); + + assertThat(caretRange).isNotNull(); + assertThat(caretRange.isValid("1.0", "0.0.0")).isTrue(); + assertThat(caretRange.isValid("1.0", "0.0.1")).isTrue(); + assertThat(caretRange.isValid("1.0", "0.1.0")).isFalse(); + } +} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/semver/DependencyMatcherTest.kt b/rewrite-core/src/test/java/org/openrewrite/semver/DependencyMatcherTest.java similarity index 80% rename from rewrite-core/src/test/kotlin/org/openrewrite/semver/DependencyMatcherTest.kt rename to rewrite-core/src/test/java/org/openrewrite/semver/DependencyMatcherTest.java index 40c90fbd73d..bcf3ead954d 100644 --- a/rewrite-core/src/test/kotlin/org/openrewrite/semver/DependencyMatcherTest.kt +++ b/rewrite-core/src/test/java/org/openrewrite/semver/DependencyMatcherTest.java @@ -13,15 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openrewrite.semver +package org.openrewrite.semver; -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; class DependencyMatcherTest { @Test - fun groupArtifact() { - assertThat(DependencyMatcher.build("org.springframework.boot:*").isValid).isTrue + void groupArtifact() { + assertThat(DependencyMatcher.build("org.springframework.boot:*").isValid()).isTrue(); } } diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/semver/HyphenRangeTest.kt b/rewrite-core/src/test/java/org/openrewrite/semver/HyphenRangeTest.java similarity index 54% rename from rewrite-core/src/test/kotlin/org/openrewrite/semver/HyphenRangeTest.kt rename to rewrite-core/src/test/java/org/openrewrite/semver/HyphenRangeTest.java index 938adb63a92..eaf881aa466 100644 --- a/rewrite-core/src/test/kotlin/org/openrewrite/semver/HyphenRangeTest.kt +++ b/rewrite-core/src/test/java/org/openrewrite/semver/HyphenRangeTest.java @@ -13,66 +13,71 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.openrewrite.semver +package org.openrewrite.semver; -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; class HyphenRangeTest { @Test - fun isValidWhenCurrentIsNull() { - val hyphenRange: HyphenRange = HyphenRange.build("1-2", null).getValue()!! - assertThat(hyphenRange.isValid(null, "1.0.0")).isTrue + void isValidWhenCurrentIsNull() { + HyphenRange hyphenRange = HyphenRange.build("1-2", null).getValue(); + + assertThat(hyphenRange).isNotNull(); + assertThat(hyphenRange.isValid(null, "1.0.0")).isTrue(); } @Test - fun pattern() { - assertThat(HyphenRange.build("1 - 2", null).isValid).isTrue - assertThat(HyphenRange.build("1.0.0.0 - 2", null).isValid).isTrue - assertThat(HyphenRange.build("1 - 2.0.0.0", null).isValid).isTrue - assertThat(HyphenRange.build("1.0.0.0 - 2.0.0.0", null).isValid).isTrue - assertThat(HyphenRange.build("1", null).isValid).isFalse - assertThat(HyphenRange.build("1 - 2.x", null).isValid).isFalse - assertThat(HyphenRange.build("1.0.0.0.0 - 2", null).isValid).isFalse + void pattern() { + assertThat(HyphenRange.build("1 - 2", null).isValid()).isTrue(); + assertThat(HyphenRange.build("1.0.0.0 - 2", null).isValid()).isTrue(); + assertThat(HyphenRange.build("1 - 2.0.0.0", null).isValid()).isTrue(); + assertThat(HyphenRange.build("1.0.0.0 - 2.0.0.0", null).isValid()).isTrue(); + assertThat(HyphenRange.build("1", null).isValid()).isFalse(); + assertThat(HyphenRange.build("1 - 2.x", null).isValid()).isFalse(); + assertThat(HyphenRange.build("1.0.0.0.0 - 2", null).isValid()).isFalse(); } /** * 1.2.3 - 2.3.4 := >=1.2.3 <=2.3.4 */ @Test - fun inclusiveSet() { - val hyphenRange: HyphenRange = HyphenRange.build("1.2.3 - 2.3.4", null).getValue()!! + void inclusiveSet() { + HyphenRange hyphenRange = HyphenRange.build("1.2.3 - 2.3.4", null).getValue(); - assertThat(hyphenRange.isValid("1.0", "1.2.2")).isFalse - assertThat(hyphenRange.isValid("1.0", "1.2.2.0")).isFalse - assertThat(hyphenRange.isValid("1.0", "1.2.3.RELEASE")).isTrue - assertThat(hyphenRange.isValid("1.0", "1.2.3.0.RELEASE")).isTrue - assertThat(hyphenRange.isValid("1.0", "1.2.3")).isTrue - assertThat(hyphenRange.isValid("1.0", "1.2.3.0")).isTrue - assertThat(hyphenRange.isValid("1.0", "1.2.3.0.0")).isTrue - assertThat(hyphenRange.isValid("1.0", "2.3.4")).isTrue - assertThat(hyphenRange.isValid("1.0", "2.3.4.0")).isTrue - assertThat(hyphenRange.isValid("1.0", "2.3.4.1")).isFalse - assertThat(hyphenRange.isValid("1.0", "2.3.5")).isFalse - assertThat(hyphenRange.isValid("1.0", "2.3.5.0")).isFalse + assertThat(hyphenRange).isNotNull(); + assertThat(hyphenRange.isValid("1.0", "1.2.2")).isFalse(); + assertThat(hyphenRange.isValid("1.0", "1.2.2.0")).isFalse(); + assertThat(hyphenRange.isValid("1.0", "1.2.3.RELEASE")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "1.2.3.0.RELEASE")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "1.2.3")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "1.2.3.0")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "1.2.3.0.0")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "2.3.4")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "2.3.4.0")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "2.3.4.1")).isFalse(); + assertThat(hyphenRange.isValid("1.0", "2.3.5")).isFalse(); + assertThat(hyphenRange.isValid("1.0", "2.3.5.0")).isFalse(); } /** * 1.2 - 2 := >=1.2.0 <=2.0.0 */ @Test - fun partialVersion() { - val hyphenRange: HyphenRange = HyphenRange.build("1.2 - 2", null).getValue()!! + void partialVersion() { + HyphenRange hyphenRange = HyphenRange.build("1.2 - 2", null).getValue(); - assertThat(hyphenRange.isValid("1.0", "1.1.9")).isFalse - assertThat(hyphenRange.isValid("1.0", "1.1.9.9")).isFalse - assertThat(hyphenRange.isValid("1.0", "1.2.0")).isTrue - assertThat(hyphenRange.isValid("1.0", "1.2.0.0")).isTrue - assertThat(hyphenRange.isValid("1.0", "1.2.0.0.0")).isTrue - assertThat(hyphenRange.isValid("1.0", "2.0.0")).isTrue - assertThat(hyphenRange.isValid("1.0", "2.0.0.0")).isTrue - assertThat(hyphenRange.isValid("1.0", "2.0.1")).isFalse - assertThat(hyphenRange.isValid("1.0", "2.0.0.1")).isFalse + assertThat(hyphenRange).isNotNull(); + assertThat(hyphenRange.isValid("1.0", "1.1.9")).isFalse(); + assertThat(hyphenRange.isValid("1.0", "1.1.9.9")).isFalse(); + assertThat(hyphenRange.isValid("1.0", "1.2.0")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "1.2.0.0")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "1.2.0.0.0")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "2.0.0")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "2.0.0.0")).isTrue(); + assertThat(hyphenRange.isValid("1.0", "2.0.1")).isFalse(); + assertThat(hyphenRange.isValid("1.0", "2.0.0.1")).isFalse(); } } diff --git a/rewrite-core/src/test/java/org/openrewrite/semver/LatestPatchTest.java b/rewrite-core/src/test/java/org/openrewrite/semver/LatestPatchTest.java new file mode 100644 index 00000000000..82fbc4858a4 --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/semver/LatestPatchTest.java @@ -0,0 +1,106 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.semver; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class LatestPatchTest { + private final LatestPatch latestPatch = new LatestPatch(null); + private final LatestPatch latestMetadataPatch = new LatestPatch("-fred"); + + @Test + void isValidWhenCurrentIsNull() { + assertThat(latestPatch.isValid(null, "1.0.0")).isTrue(); + } + + @Test + void isValid() { + assertThat(latestPatch.isValid("1.0.0", "1.0.0")).isTrue(); + assertThat(latestPatch.isValid("1.0.0", "1.0.0.1")).isTrue(); + assertThat(latestPatch.isValid("1.0.0", "1.0.1")).isTrue(); + assertThat(latestPatch.isValid("1.0", "1.0.1")).isTrue(); + assertThat(latestPatch.isValid("1.0.0", "1.1.0")).isFalse(); + assertThat(latestPatch.isValid("1.0.0", "2.0.0")).isFalse(); + } + + @Test + void upgrade() { + var upgrade = latestPatch.upgrade("2.10.10.3.24", List.of("2.10.0")); + assertThat(upgrade.isPresent()).isFalse(); + + upgrade = latestPatch.upgrade("2.10.10.3.24", List.of("2.11.0")); + assertThat(upgrade.isPresent()).isFalse(); + upgrade = latestPatch.upgrade("2.10.10.3.24", List.of("2.10.9")); + assertThat(upgrade.isPresent()).isFalse(); + + upgrade = latestPatch.upgrade("2.10.10.3.24", List.of("2.10.11")); + assertThat(upgrade.isPresent()).isTrue(); + assertThat(upgrade.get()).isEqualTo("2.10.11"); + + upgrade = latestPatch.upgrade("2.10.10.3.24", List.of("2.10.10.3.23")); + assertThat(upgrade.isPresent()).isFalse(); + + upgrade = latestPatch.upgrade("2.10.10.3.24", List.of("2.10.10.2.25")); + assertThat(upgrade.isPresent()).isFalse(); + + upgrade = latestPatch.upgrade("2.10.10.3.24", List.of("2.10.10.3.25")); + assertThat(upgrade.isPresent()).isTrue(); + assertThat(upgrade.get()).isEqualTo("2.10.10.3.25"); + } + + @Test + void compare() { + assertThat(latestPatch.compare("1.0", "1.0.1", "1.0.2")).isLessThan(0); + assertThat(latestPatch.compare("1.0", "1.0.0.1", "1.0.1")).isLessThan(0); + } + + @Test + void metadataValid() { + assertThat(latestMetadataPatch.isValid("1.0.0-fred", "1.0.4-fred")).isTrue(); + assertThat(latestMetadataPatch.isValid("1.0-fred", "1.0.1-fred")).isTrue(); + assertThat(latestMetadataPatch.isValid("1.0.0-fred", "1.0.4-not-fred")).isFalse(); + } + + @Test + void metadataUpgrade() { + var upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", List.of("2.10.0-fred")); + assertThat(upgrade.isPresent()).isFalse(); + + upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", List.of("2.11.0-fred")); + assertThat(upgrade.isPresent()).isFalse(); + upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", List.of("2.10.9-fred")); + assertThat(upgrade.isPresent()).isFalse(); + + upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", List.of("2.10.11-fred")); + assertThat(upgrade.isPresent()).isTrue(); + assertThat(upgrade.get()).isEqualTo("2.10.11-fred"); + + upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", List.of("2.10.10.3.23-fred")); + assertThat(upgrade.isPresent()).isFalse(); + + upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", List.of("2.10.10.2.25-fred")); + assertThat(upgrade.isPresent()).isFalse(); + + upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", List.of("2.10.10.3.25-fred")); + assertThat(upgrade.isPresent()).isTrue(); + assertThat(upgrade.get()).isEqualTo("2.10.10.3.25-fred"); + } + +} diff --git a/rewrite-core/src/test/java/org/openrewrite/semver/LatestReleaseTest.java b/rewrite-core/src/test/java/org/openrewrite/semver/LatestReleaseTest.java new file mode 100644 index 00000000000..5616f47f6bf --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/semver/LatestReleaseTest.java @@ -0,0 +1,123 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.semver; + +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.openrewrite.semver.LatestRelease.normalizeVersion; + +class LatestReleaseTest { + private final LatestRelease latestRelease = new LatestRelease(null); + + @Test + void isValidWhenCurrentIsNull() { + assertThat(latestRelease.isValid(null, "1.0.0")).isTrue(); + } + + @Test + void onlyNumericPartsValid() { + assertThat(latestRelease.isValid("1.0", "1.1.1.1")).isTrue(); + assertThat(latestRelease.isValid("1.0", "1.1.1")).isTrue(); + assertThat(latestRelease.isValid("1.0", "1.1")).isTrue(); + assertThat(latestRelease.isValid("1.0", "1")).isTrue(); + assertThat(latestRelease.isValid("1.0", "1.1.a")).isFalse(); + assertThat(latestRelease.isValid("1.0", "1.1.1.1.a")).isFalse(); + assertThat(latestRelease.isValid("1.0", "1.1.1.1.1")).isTrue(); + assertThat(latestRelease.isValid("1.0", "1.1.1.1.1-SNAPSHOT")).isFalse(); + assertThat(latestRelease.isValid("1.0", "1.1.0-SNAPSHOT")).isFalse(); + } + + @Test + void differentMicroVersions() { + assertThat(latestRelease.compare("1.0", "1.1.1.1", "1.1.1.2")).isLessThan(0); + assertThat(latestRelease.compare("1.0", "1", "1.1.1.1")).isLessThan(0); + assertThat(latestRelease.compare("1.0", "1.1.1.1", "2")).isLessThan(0); + } + + @Test + void differentPatchVersions() { + assertThat(latestRelease.compare("1.0", "1.1.1.1", "1.1.2.1")).isLessThan(0); + assertThat(latestRelease.compare("1.0", "1.1.1", "1.1.2")).isLessThan(0); + } + + @Test + void differentMinorVersions() { + assertThat(latestRelease.compare("1.0", "1.1.1.1", "1.2.1.1")).isLessThan(0); + assertThat(latestRelease.compare("1.0", "1.1.1", "1.2.1")).isLessThan(0); + assertThat(latestRelease.compare("1.0", "1.1", "1.2")).isLessThan(0); + } + + @Test + void differentMajorVersions() { + assertThat(latestRelease.compare("1.0", "1.1.1.1", "2.1.1.1")).isLessThan(0); + assertThat(latestRelease.compare("1.0", "1.1.1", "2.1.1")).isLessThan(0); + assertThat(latestRelease.compare("1.0", "1.1", "2.1")).isLessThan(0); + assertThat(latestRelease.compare("1.0", "1", "2")).isLessThan(0); + } + + @Test + void differentNumberOfParts() { + assertThat(latestRelease.compare("1.0", "1.1.1", "1.1.1.1")).isLessThan(0); + assertThat(latestRelease.compare("1.0", "1.1", "1.1.1")).isLessThan(0); + assertThat(latestRelease.compare("1.0", "1", "1.1")).isLessThan(0); + } + + @Test + void guavaVariants() { + assertThat(latestRelease.compare("1.0", "25.0-jre", "29.0-jre")).isLessThan(0); + } + + @Test + @Disabled("https://github.com/openrewrite/rewrite/issues/1204") + // feel free to move this under "guavaVariants", todo + void guavaVariantsMetadataBoundaries() { + assertThat(latestRelease.compare("1.0", "25", "25.0-jre")).isEqualTo(0); + } + + @Test + void matchMetadata() { + assertThat(new LatestRelease("-jre").isValid("1.0", "29.0.0.0-jre")).isTrue(); + assertThat(new LatestRelease("-jre").isValid("1.0", "29.0-jre")).isTrue(); + assertThat(new LatestRelease("-jre").isValid("1.0", "29.0")).isFalse(); + assertThat(new LatestRelease("-jre").isValid("1.0", "29.0-android")).isFalse(); + assertThat(new LatestRelease("").isValid("1.0", "29.0")).isTrue(); + assertThat(new LatestRelease("").isValid("1.0", "29.0-jre")).isFalse(); + assertThat(new LatestRelease(null).isValid("1.0", "29.0-jre")).isFalse(); + } + + @Test + void normalizeVersionStripReleaseSuffix() { + assertThat(normalizeVersion("1.5.1.2.RELEASE")).isEqualTo("1.5.1.2"); + assertThat(normalizeVersion("1.5.1.RELEASE")).isEqualTo("1.5.1"); + assertThat(normalizeVersion("1.5.1.FINAL")).isEqualTo("1.5.1"); + assertThat(normalizeVersion("1.5.1.Final")).isEqualTo("1.5.1"); + } + + @Test + void normalizeVersionToHaveMajorMinorPatch() { + assertThat(normalizeVersion("29.0")).isEqualTo("29.0.0"); + assertThat(normalizeVersion("29.0-jre")).isEqualTo("29.0.0-jre"); + assertThat(normalizeVersion("29-jre")).isEqualTo("29.0.0-jre"); + } + + @Test + void datedSnapshotVersions() { + assertThat(latestRelease.compare(null, "7.17.0-20211102.000501-28", + "7.17.0-20211102.012229-29")).isLessThan(0); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/semver/SemverTest.java b/rewrite-core/src/test/java/org/openrewrite/semver/SemverTest.java new file mode 100644 index 00000000000..3db04c09e3a --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/semver/SemverTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.semver; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class SemverTest { + @Test + void validToVersion() { + assertThat(Semver.validate("latest.release", null).getValue()) + .isInstanceOf(LatestRelease.class); + assertThat(Semver.validate("1.5 - 2", null).getValue()) + .isInstanceOf(HyphenRange.class); + assertThat(Semver.validate("1.x", null).getValue()) + .isInstanceOf(XRange.class); + assertThat(Semver.validate("~1.5", null).getValue()) + .isInstanceOf(TildeRange.class); + assertThat(Semver.validate("^1.5", null).getValue()) + .isInstanceOf(CaretRange.class); + assertThat(Semver.validate("[1.5,2)", null).getValue()) + .isInstanceOf(SetRange.class); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/semver/TildeRangeTest.java b/rewrite-core/src/test/java/org/openrewrite/semver/TildeRangeTest.java new file mode 100644 index 00000000000..78f3c60646e --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/semver/TildeRangeTest.java @@ -0,0 +1,96 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.semver; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class TildeRangeTest { + + @Test + void isValidWhenCurrentIsNull() { + TildeRange tildeRange = TildeRange.build("~1", null).getValue(); + + assertThat(tildeRange).isNotNull(); + assertThat(tildeRange.isValid(null, "1.0.0")).isTrue(); + } + + @Test + void pattern() { + assertThat(TildeRange.build("~1", null).isValid()).isTrue(); + assertThat(TildeRange.build("~1.2", null).isValid()).isTrue(); + assertThat(TildeRange.build("~1.2.3", null).isValid()).isTrue(); + assertThat(TildeRange.build("~1.2.3.4", null).isValid()).isTrue(); + assertThat(TildeRange.build("~1.2.3.4.5", null).isValid()).isFalse(); + } + + /** + * ~1.2.3 := >=1.2.3 <1.(2+1).0 := >=1.2.3 <1.3.0 + */ + @Test + void updatePatch() { + TildeRange tildeRange = TildeRange.build("~1.2.3", null).getValue(); + + assertThat(tildeRange).isNotNull(); + assertThat(tildeRange.isValid("1.0", "1.2.3.0")).isTrue(); + assertThat(tildeRange.isValid("1.0", "1.2.3.1")).isTrue(); + assertThat(tildeRange.isValid("1.0", "1.2.3")).isTrue(); + assertThat(tildeRange.isValid("1.0", "1.2.3.RELEASE")).isTrue(); + assertThat(tildeRange.isValid("1.0", "1.2.4")).isTrue(); + assertThat(tildeRange.isValid("1.0", "1.3.0")).isFalse(); + } + + @Test + void updateMicro() { + TildeRange tildeRange = TildeRange.build("~1.2.3.4", null).getValue(); + + assertThat(tildeRange).isNotNull(); + assertThat(tildeRange.isValid("1.0", "1.2.3.5")).isTrue(); + assertThat(tildeRange.isValid("1.0", "1.2.3.0")).isFalse(); + assertThat(tildeRange.isValid("1.0", "1.2.3.5.0")).isTrue(); + assertThat(tildeRange.isValid("1.0", "1.2.3")).isFalse(); + assertThat(tildeRange.isValid("1.0", "1.2.4")).isFalse(); + assertThat(tildeRange.isValid("1.0", "1.2.4.0")).isFalse(); + assertThat(tildeRange.isValid("1.0", "1.3.0")).isFalse(); + } + + /** + * ~1.2 := >=1.2.0 <1.(2+1).0 := >=1.2.0 <1.3.0-0 (Same as 1.2.x) + */ + @Test + void updatePatchImplicitZeroPatch() { + TildeRange tildeRange = TildeRange.build("~1.2", null).getValue(); + + assertThat(tildeRange).isNotNull(); + assertThat(tildeRange.isValid("1.0", "1.2.0")).isTrue(); + assertThat(tildeRange.isValid("1.0", "1.2.4")).isTrue(); + assertThat(tildeRange.isValid("1.0", "1.3.0")).isFalse(); + } + + /** + * ~1 := >=1.0.0 <(1+1).0.0 := >=1.0.0 <2.0.0-0 (Same as 1.x) + */ + @Test + void updateMajor() { + TildeRange tildeRange = TildeRange.build("~1", null).getValue(); + + assertThat(tildeRange).isNotNull(); + assertThat(tildeRange.isValid("1.0", "1.0.1")).isTrue(); + assertThat(tildeRange.isValid("1.0", "1.9.9")).isTrue(); + assertThat(tildeRange.isValid("1.0", "2.0.0")).isFalse(); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/semver/XRangeTest.java b/rewrite-core/src/test/java/org/openrewrite/semver/XRangeTest.java new file mode 100644 index 00000000000..45870f1398f --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/semver/XRangeTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2021 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.semver; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class XRangeTest { + + @Test + void isValidWhenCurrentIsNull() { + XRange xRange = XRange.build("*", null).getValue(); + + assertThat(xRange).isNotNull(); + assertThat(xRange.isValid(null, "1.0.0")).isTrue(); + } + + @Test + void pattern() { + assertThat(XRange.build("*", null).isValid()).isTrue(); + assertThat(XRange.build("*.0.0", null).isValid()).isFalse(); + assertThat(XRange.build("1.x", null).isValid()).isTrue(); + assertThat(XRange.build("1.x.0", null).isValid()).isFalse(); + assertThat(XRange.build("1.1.X", null).isValid()).isTrue(); + assertThat(XRange.build("1.1.1.X", null).isValid()).isTrue(); + assertThat(XRange.build("1.1.1.1.X", null).isValid()).isFalse(); + assertThat(XRange.build("1.1.x.1", null).isValid()).isFalse(); + assertThat(XRange.build("a", null).isValid()).isFalse(); + } + + @Test + void doesNotMatchFixedVersion() { + assertThat(XRange.build("5.3.0", null).isValid()).isFalse(); + } + + /** + * X := >=0.0.0 + */ + @Test + void anyVersion() { + XRange xRange = XRange.build("X", null).getValue(); + + assertThat(xRange).isNotNull(); + assertThat(xRange.isValid("1.0", "0.0.0.0")).isTrue(); + assertThat(xRange.isValid("1.0", "0.0.0")).isTrue(); + } + + /** + * 1.* := >=1.0.0 <2.0.0-0 + */ + @Test + void matchingMajorVersion() { + XRange xRange = XRange.build("1.*", null).getValue(); + + assertThat(xRange).isNotNull(); + assertThat(xRange.isValid("1.0", "1.0.0")).isTrue(); + assertThat(xRange.isValid("1.0", "1.0.0.1")).isTrue(); + assertThat(xRange.isValid("1.0", "1.2.3.RELEASE")).isTrue(); + assertThat(xRange.isValid("1.0", "1.9.9")).isTrue(); + assertThat(xRange.isValid("1.0", "2.0.0")).isFalse(); + } + + /** + * 1.2.X := >=1.2.0 <1.3.1 + */ + @Test + void matchingMajorAndMinorVersions() { + XRange xRange = XRange.build("1.2.X", null).getValue(); + + assertThat(xRange).isNotNull(); + assertThat(xRange.isValid("1.0", "1.2.0")).isTrue(); + assertThat(xRange.isValid("1.0", "1.3.0")).isFalse(); + } + + @Test + void matchingMicroVersions() { + XRange xRange = XRange.build("1.2.3.X", null).getValue(); + + assertThat(xRange).isNotNull(); + assertThat(xRange.isValid("1.0", "1.2.3.0")).isTrue(); + assertThat(xRange.isValid("1.0", "1.2.3")).isTrue(); + assertThat(xRange.isValid("1.0", "1.2.4.0")).isFalse(); + assertThat(xRange.isValid("1.0", "1.2.4")).isFalse(); + } + + @Test + void matchingJavaxValidation() { + XRange xRange = XRange.build("2.X", null).getValue(); + + assertThat(xRange).isNotNull(); + // The version pattern of javax.validation:validation-api + assertThat(xRange.isValid("1.0", "2.0.1.Final")).isTrue(); + } +} diff --git a/rewrite-core/src/test/java/org/openrewrite/text/AppendToTextFileTest.java b/rewrite-core/src/test/java/org/openrewrite/text/AppendToTextFileTest.java new file mode 100644 index 00000000000..9fe8350a402 --- /dev/null +++ b/rewrite-core/src/test/java/org/openrewrite/text/AppendToTextFileTest.java @@ -0,0 +1,188 @@ +/* + * Copyright 2022 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * 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.text; + +import org.junit.jupiter.api.Test; +import org.openrewrite.Recipe; +import org.openrewrite.test.RewriteTest; +import org.openrewrite.test.SourceSpec; + +import java.util.function.Supplier; + +import static org.openrewrite.test.SourceSpecs.text; + +class AppendToTextFileTest implements RewriteTest { + + @Test + void createsFileIfNeeded() { + rewriteRun( + spec -> spec.recipe(new AppendToTextFile("file.txt", "content", "preamble", true, "leave")), + text( + null, + """ + preamble + content + """ + ) + ); + } + + @Test + void createsFileIfNeededWithMultipleInstances() { + Supplier r = () -> new AppendToTextFile("file.txt", "content", "preamble", true, "leave"); + rewriteRun( + spec -> spec.recipe(r.get().doNext(r.get())), + text( + null, + """ + preamble + content + content + """, + SourceSpec::noTrim + ) + ); + } + + @Test + void replacesFileIfRequested() { + rewriteRun( + spec -> spec.recipe(new AppendToTextFile("file.txt", "content", "preamble", true, "replace")), + text( + """ + existing + """, + """ + preamble + content + """, + spec -> spec.path("file.txt").noTrim() + ) + ); + } + + @Test + void continuesFileIfRequested() { + rewriteRun( + spec -> spec.recipe(new AppendToTextFile("file.txt", "content", "preamble", true, "continue")), + text( + """ + existing + """, + """ + existing + content + """, + spec -> spec.path("file.txt").noTrim() + ) + ); + } + + @Test + void leavesFileIfRequested() { + rewriteRun( + spec -> spec.recipe(new AppendToTextFile("file.txt", "content", "preamble", true, "leave")), + text("existing", spec -> spec.path("file.txt")) + ); + } + + @Test + void multipleInstancesCanAppend() { + rewriteRun( + spec -> spec.recipe( + new AppendToTextFile("file.txt", "content", "preamble", true, "replace") + .doNext(new AppendToTextFile("file.txt", "content", "preamble", true, "replace"))), + text( + "existing", + """ + preamble + content + content + """, + spec -> spec.path("file.txt").noTrim() + ) + ); + } + + @Test + void noLeadingNewlineIfNoPreamble() { + rewriteRun( + spec -> spec.recipe(new AppendToTextFile("file.txt", "content", null, true, "replace")), + text( + """ + existing + """, + """ + content + """, + spec -> spec.path("file.txt").noTrim() + ) + ); + } + + @Test + void multipleFiles() { + rewriteRun( + spec -> spec.recipe(new AppendToTextFile("file1.txt", "content1", "preamble1", true, "replace") + .doNext(new AppendToTextFile("file2.txt", "content2", "preamble2", true, "replace"))), + text( + "existing1", + """ + preamble1 + content1 + """, + spec -> spec.path("file1.txt").noTrim() + ), + text( + "existing2", + """ + preamble2 + content2 + """, + spec -> spec.path("file2.txt").noTrim() + ) + ); + } + + @Test + void multipleInstancesOnMultipleFiles() { + rewriteRun( + spec -> spec.recipe( + new AppendToTextFile("file1.txt", "content1", "preamble1", true, "replace") + .doNext(new AppendToTextFile("file2.txt", "content2", "preamble2", true, "replace")) + .doNext(new AppendToTextFile("file1.txt", "content1", "preamble1", true, "replace")) + .doNext(new AppendToTextFile("file2.txt", "content2", "preamble2", true, "replace"))), + text( + "existing1", + """ + preamble1 + content1 + content1 + """, + spec -> spec.path("file1.txt").noTrim() + ), + text( + "existing2", + """ + preamble2 + content2 + content2 + """, + spec -> spec.path("file2.txt").noTrim() + ) + ); + } +} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/ApplicabilityTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/ApplicabilityTest.kt deleted file mode 100644 index 17513fc5fa4..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/ApplicabilityTest.kt +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2022 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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 - -import org.junit.jupiter.api.Test -import org.openrewrite.marker.SearchResult -import org.openrewrite.test.RecipeSpec -import org.openrewrite.test.RewriteTest -import org.openrewrite.test.SourceSpecs.text -import org.openrewrite.text.PlainText -import org.openrewrite.text.PlainTextVisitor - -class ApplicabilityTest : RewriteTest { - override fun defaults(spec: RecipeSpec) { - spec.validateRecipeSerialization(false) - } - - @Test - fun not() = rewriteRun( - { spec -> spec.recipe(recipe(Applicability.not(contains("z")))) }, - text("hello", "goodbye") - ) - - @Test - fun notNot() = rewriteRun( - { spec -> spec.recipe(recipe(Applicability.not(contains("h")))) }, - text("hello") - ) - - - @Test - fun or() = rewriteRun( - { spec -> spec.recipe(recipe(Applicability.or(contains("h"), contains("z")))) }, - text("hello", "goodbye") - ) - - @Test - fun notOr() = rewriteRun( - { spec -> spec.recipe(recipe(Applicability.or(contains("x"), contains("z")))) }, - text("hello") - ) - - @Test - fun and() = rewriteRun( - { spec -> spec.recipe(recipe(Applicability.and(contains("h"), contains("ello")))) }, - text("hello", "goodbye") - ) - - @Test - fun notAnd() = rewriteRun( - { spec -> spec.recipe(recipe(Applicability.and(contains("h"), contains("z")))) }, - text("hello") - ) - - fun recipe(applicability: TreeVisitor<*, ExecutionContext>) = object : Recipe() { - override fun getDisplayName() = "Say goodbye" - override fun getSingleSourceApplicableTest() = applicability - override fun getVisitor() = object : PlainTextVisitor() { - override fun visitText(text: PlainText, p: ExecutionContext): PlainText { - return text.withText("goodbye") - } - } - } - - fun contains(s: String) = object : PlainTextVisitor() { - override fun visitText(text: PlainText, p: ExecutionContext): PlainText = - if (text.text.contains(s)) { - SearchResult.found(text) - } else text - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/CursorTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/CursorTest.kt deleted file mode 100644 index 2cb8bd239de..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/CursorTest.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2020 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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 - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.openrewrite.Tree.randomId -import org.openrewrite.marker.Markers -import org.openrewrite.text.PlainText -import java.nio.file.Paths -import kotlin.streams.toList - -class CursorTest { - @Test - fun peekMessages() { - val t = PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test") - val cursor = Cursor(null, t) - - cursor.putMessage("key", 1) - assertThat(cursor.getNearestMessage("key")!!).isEqualTo(1) - - val child = Cursor(cursor, t) - assertThat(child.getNearestMessage("key")!!).isEqualTo(1) - } - - @Test - fun pollMessages() { - val t = PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test") - val cursor = Cursor(null, t) - - cursor.putMessage("key", 1) - assertThat(cursor.pollNearestMessage("key")!!).isEqualTo(1) - - @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") - assertThat(cursor.pollNearestMessage("key")).isNull() - - cursor.putMessage("key", 1) - val child = Cursor(cursor, t) - assertThat(child.getNearestMessage("key")!!).isEqualTo(1) - } - - @Test - fun pathPredicates() { - val t = PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test") - val cursor = Cursor(Cursor(Cursor(null, 1), t), 2) - assertThat(cursor.getPath { it is PlainText }.next()).isSameAs(t) - } - - @Test - fun pathAsStreamPredicates() { - val t = PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test") - val cursor = Cursor(Cursor(Cursor(null, 1), t), 2) - assertThat(cursor.getPathAsStream { it is PlainText }.toList()).containsExactly(t) - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/ExecutionContextTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/ExecutionContextTest.kt deleted file mode 100644 index e6b1e15d247..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/ExecutionContextTest.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2020 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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 - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.openrewrite.Tree.randomId -import org.openrewrite.marker.Markers -import org.openrewrite.text.PlainText -import org.openrewrite.text.PlainTextVisitor -import java.nio.file.Paths - -class ExecutionContextTest { - @Test - fun anotherCycleIfNewMessagesInExecutionContext() { - var cycles = 0 - - object: Recipe() { - override fun getDisplayName(): String { - return name - } - - override fun causesAnotherCycle(): Boolean { - return true - } - - override fun getVisitor(): PlainTextVisitor { - return object : PlainTextVisitor() { - override fun visit(tree: Tree?, p: ExecutionContext): PlainText? { - if(p.pollMessage("test") == null) { - p.putMessage("test", "test") - } - cycles = cycles.inc() - return super.visit(tree, p) - } - } - } - }.run(listOf(PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "hello world"))) - - assertThat(cycles).isEqualTo(2) - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/RecipeLifecycleTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/RecipeLifecycleTest.kt deleted file mode 100644 index 6224c3e1013..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/RecipeLifecycleTest.kt +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2020 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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 - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test -import org.openrewrite.Tree.randomId -import org.openrewrite.internal.lang.Nullable -import org.openrewrite.marker.Markers -import org.openrewrite.text.ChangeText -import org.openrewrite.text.PlainText -import org.openrewrite.text.PlainTextVisitor -import java.nio.charset.Charset -import java.nio.file.Path -import java.nio.file.Paths -import java.util.* -import java.util.concurrent.atomic.AtomicInteger - -class RecipeLifecycleTest { - - @Test - fun panic() { - val visited = AtomicInteger(0) - val ctx = InMemoryExecutionContext() - ctx.putMessage(Recipe.PANIC, true) - - object : Recipe() { - override fun getDisplayName(): String = "Slow" - - override fun getVisitor(): TreeVisitor<*, ExecutionContext> { - return object : TreeVisitor() { - override fun visit(tree: Tree?, p: ExecutionContext): Tree? { - visited.incrementAndGet() - return tree - } - } - } - }.run(listOf(PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null,"hello world")), ctx) - - assertThat(visited.get()).isEqualTo(0) - } - - @Test - fun notApplicableRecipe() { - val results = object : Recipe() { - override fun getName() = "test.NotApplicable" - override fun getDisplayName(): String { - return name - } - - override fun getApplicableTest(): TreeVisitor<*, ExecutionContext>? { - return NOOP // never going to be applicable - } - - override fun visit(before: List, ctx: ExecutionContext) = - before + PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test") - }.run(emptyList()).results - - assertThat(results).isEmpty() - } - - @Test - fun generateFile() { - val results = object : Recipe() { - override fun getName() = "test.GeneratingRecipe" - override fun getDisplayName(): String { - return name - } - - override fun visit(before: List, ctx: ExecutionContext) = - before + PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test") - }.run(emptyList()).results - - assertThat(results.map { it.recipeDescriptorsThatMadeChanges.map { r -> r.name }.first() } - .distinct()).containsExactly("test.GeneratingRecipe") - } - - @Test - fun deleteFile() { - val results = object : Recipe() { - override fun getName() = "test.DeletingRecipe" - - override fun getDisplayName(): String { - return name - } - - override fun visit(before: List, ctx: ExecutionContext) = - emptyList() - }.run(listOf(PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test"))).results - - assertThat(results.map { - it.recipeDescriptorsThatMadeChanges.map { r -> r.name }.first() - }).containsExactly("test.DeletingRecipe") - } - - @Test - fun deleteFileByReturningNullFromVisit() { - val results = object : Recipe() { - override fun getName() = "test.DeletingRecipe" - - override fun getDisplayName(): String { - return name - } - - override fun getVisitor(): PlainTextVisitor { - return object : PlainTextVisitor() { - override fun visit(tree: Tree?, p: ExecutionContext): PlainText? = null - } - - } - - }.run(listOf(PlainText(randomId(), Paths.get("test.txt"), Markers.EMPTY, null, false, null, null, "test"))).results - - assertThat(results.map { - it.recipeDescriptorsThatMadeChanges.map { r -> r.name }.first() - }).containsExactly("test.DeletingRecipe") - } - - @Suppress("USELESS_IS_CHECK") - class FooVisitor

: TreeVisitor() { - override fun preVisit(tree: FooSource, p: P): FooSource { - if (tree !is FooSource) { - throw RuntimeException("tree is not a FooSource") - } - return tree - } - - override fun postVisit(tree: FooSource, p: P): FooSource { - if (tree !is FooSource) { - throw RuntimeException("tree is not a FooSource") - } - return tree - } - } - - class FooSource : SourceFile { - override fun

isAcceptable(v: TreeVisitor<*, P>, p: P) = v.isAdaptableTo(FooVisitor::class.java) - - override fun getMarkers(): Markers = throw NotImplementedError() - override fun withMarkers(markers: Markers): T = throw NotImplementedError() - override fun getId(): UUID = throw NotImplementedError() - override fun withId(id: UUID): T = throw NotImplementedError() - override fun getSourcePath() = throw NotImplementedError() - override fun withSourcePath(path: Path): T = throw NotImplementedError() - override fun getCharset() = throw NotImplementedError() - override fun withCharset(charset: Charset): T = throw NotImplementedError() - override fun isCharsetBomMarked() = throw NotImplementedError() - override fun withCharsetBomMarked(marked: Boolean): T = throw NotImplementedError() - override fun getChecksum(): Checksum = throw NotImplementedError() - override fun withChecksum(checksum: Checksum?): T = throw NotImplementedError() - override fun getFileAttributes(): FileAttributes = throw NotImplementedError() - override fun withFileAttributes(fileAttributes: FileAttributes?): T = throw NotImplementedError() - } - - @Issue("https://github.com/openrewrite/rewrite/issues/389") - @Test - fun sourceFilesAcceptOnlyApplicableVisitors() { - val sources = listOf(FooSource(), PlainText(randomId(), Paths.get("test.txt"), Markers.build(listOf()), null, false, null, null, "Hello")) - val fooVisitor = FooVisitor() - val textVisitor = PlainTextVisitor() - val ctx = InMemoryExecutionContext { - throw it - } - sources.forEach { - fooVisitor.visit(it, ctx) - textVisitor.visit(it, ctx) - } - } - - @Test - fun accurateReportingOfRecipesMakingChanges() { - val sources = listOf(PlainText(randomId(), Paths.get("test.txt"), Markers.build(listOf()), null, false, null, null, "Hello")) - // Set up a composite recipe which prepends "Change1" and appends "Change2" to the input text - val recipe = object : Recipe() { - override fun getDisplayName() = "root" - }.apply { - doNext(testRecipe("Change1")) - doNext(noChangeRecipe()) - doNext(testRecipe("Change2")) - } - val results = recipe.run(sources, InMemoryExecutionContext { throw it }).results - assertThat(results.size) - .isEqualTo(1) - assertThat(results.first().recipeDescriptorsThatMadeChanges.map { it.name }) - .containsExactlyInAnyOrder("Change1", "Change2") - } - - @Test - fun recipeDescriptorsReturnCorrectStructure() { - val sources = listOf( - PlainText(randomId(), Paths.get("test.txt"), Markers.build(listOf()), null, false, null, null,"Hello") - ) - // Set up a composite recipe which with a nested structure of recipes - val recipe = object : Recipe() { - override fun getDisplayName() = "Environment.Composite" - override fun getName() = displayName - override fun toString() = displayName - }.apply { - doNext(testRecipe("A") - .doNext(testRecipe("B") - .doNext(testRecipe("D") - .doNext(testRecipe("C")))) - .doNext(noChangeRecipe())) - doNext(testRecipe("A") - .doNext(testRecipe("B") - .doNext(testRecipe("E")) - .doNext(ChangeText("E1")) - .doNext(ChangeText( "E2")))) - doNext(testRecipe("E") - .doNext(testRecipe("F"))) - doNext(noChangeRecipe()) - } - val results = recipe.run(sources, InMemoryExecutionContext { throw it }).results - assertThat(results.size).isEqualTo(1) - - val recipeDescriptors = results[0].recipeDescriptorsThatMadeChanges - assertThat(recipeDescriptors.size).isEqualTo(2) - - val aDescriptor = recipeDescriptors[0] - val bDescriptor = aDescriptor?.recipeList?.get(0) - // B (2 test recipes, 2 ChangeText with different options and 1 noChangeRecipe) resulting in 4 changes - assertThat(bDescriptor?.name).isEqualTo("B") - assertThat(bDescriptor?.recipeList?.size).isEqualTo(4) - } - - private fun testRecipe(name: String): Recipe { - return object : Recipe() { - override fun getDisplayName() = name - override fun getName() = displayName - override fun toString() = displayName - override fun getVisitor(): PlainTextVisitor { - return object : PlainTextVisitor() { - override fun visit(@Nullable tree: Tree?, p: ExecutionContext): PlainText { - var pt = tree as PlainText - if (!pt.printAll().contains(displayName)) { - pt = pt.withText(displayName + pt.printAll()) - } - return pt - } - } - } - } - } - private fun noChangeRecipe(): Recipe { - return object : Recipe() { - override fun getDisplayName() = "NoChange" - override fun getName() = displayName - override fun toString() = displayName - } - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/RecipeSchedulerTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/RecipeSchedulerTest.kt deleted file mode 100644 index adeaa599b90..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/RecipeSchedulerTest.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2022 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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 - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.openrewrite.test.RewriteTest -import org.openrewrite.test.SourceSpecs.text -import org.openrewrite.text.PlainText -import org.openrewrite.text.PlainTextVisitor - -class RecipeSchedulerTest : RewriteTest { - - @Test - fun exceptionsCauseResult() = rewriteRun( - { spec -> - spec - .executionContext(InMemoryExecutionContext()) - .recipe(BoomRecipe()) - .afterRecipe { run -> assertThat(run.results[0].recipeErrors).isNotEmpty() } - }, - text( - "hello", - "~~(boom)~~>hello" - ) - ) -} - -class BoomRecipe : Recipe() { - override fun getDisplayName() = "We go boom" - - override fun getDescription() = "Test recipe." - override fun getVisitor() = object : PlainTextVisitor() { - override fun visitText(text: PlainText, p: ExecutionContext): PlainText { - throw BoomException() - } - } -} - -/** - * Simplified exception that only displays stack trace elements within the [BoomRecipe]. - */ -class BoomException : RuntimeException("boom") { - override fun getStackTrace() = super.getStackTrace() - .filter { it.className.startsWith(BoomRecipe::class.java.name) } - .toTypedArray() -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/ResultTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/ResultTest.kt deleted file mode 100644 index 1aed29bcff4..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/ResultTest.kt +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 2020 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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 - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import java.nio.file.Paths - -class ResultTest { - private val filePath = Paths.get("com/netflix/MyJavaClass.java") - - private fun ab(which: String) = "$which/" + filePath.toString().replace("\\", "/") - - @Test - fun idempotent() { - val diff = Result.InMemoryDiffEntry( - Paths.get("com/netflix/MyJavaClass.java"), - Paths.get("com/netflix/MyJavaClass.java"), - null, - "public class A {}", - "public class A {}", - emptySet() - ) - - assertThat(diff.diff).isEmpty() - } - - @Test - fun ignoreWhitespace() { - val diff = Result.InMemoryDiffEntry( - Paths.get("com/netflix/MyJavaClass.java"), - Paths.get("com/netflix/MyJavaClass.java"), - null, - "public class A {} ", - "public class A {}", - emptySet() - ) - - val diffNoWs = diff.getDiff(true); - assertThat( - """ - diff --git a/com/netflix/MyJavaClass.java b/com/netflix/MyJavaClass.java - index 9bfeb36..efd7fa3 100644 - --- a/com/netflix/MyJavaClass.java - +++ b/com/netflix/MyJavaClass.java - """.trimIndent() - ).isEqualTo(diffNoWs.trimIndent()); - } - @Test - fun singleLineChange() { - val diff = Result.InMemoryDiffEntry( - filePath, filePath, null, - """ - |public void test() { - | logger.infof("some %s", 1); - |} - | - """.trimMargin(), - """ - |public void test() { - | logger.info("some {}", 1); - |} - | - """.trimMargin(), - setOf(object : Recipe() { - override fun getName(): String = "logger.Fix" - override fun getDisplayName(): String { - return name - } - }) - ).diff - - assertThat( - """ - |diff --git ${ab("a")} ${ab("b")} - |index 3490cbf..5d64ae4 100644 - |--- ${ab("a")} - |+++ ${ab("b")} - |@@ -1,3 +1,3 @@ logger.Fix - | public void test() { - |- logger.infof("some %s", 1); - |+ logger.info("some {}", 1); - | } - | - """.trimMargin() - ).isEqualTo(diff) - } - - @Test - fun multipleChangesMoreThanThreeLinesApart() { - val diff = Result.InMemoryDiffEntry( - filePath, filePath, null, - """ - |public void test() { - | logger.infof("some %s", 1); - | System.out.println("1"); - | System.out.println("2"); - | System.out.println("3"); - | System.out.println("4"); - | System.out.println("5"); - | System.out.println("6"); - | System.out.println("7"); - | System.out.println("8"); - | logger.infof("some %s", 2); - |} - | - """.trimMargin(), - """ - |public void test() { - | logger.info("some {}", 1); - | System.out.println("1"); - | System.out.println("2"); - | System.out.println("3"); - | System.out.println("4"); - | System.out.println("5"); - | System.out.println("6"); - | System.out.println("7"); - | System.out.println("8"); - | logger.info("some %s", 2); - |} - | - """.trimMargin(), - - setOf( - object : Recipe() { - override fun getName(): String = "logger.Fix1" - override fun getDisplayName(): String { - return name - } - }, - object : Recipe() { - override fun getName(): String = "logger.Fix2" - override fun getDisplayName(): String { - return name - } - } - ) - ).diff - - assertThat( - """ - |diff --git ${ab("a")} ${ab("b")} - |index c17f051..bb2dfba 100644 - |--- ${ab("a")} - |+++ ${ab("b")} - |@@ -1,5 +1,5 @@ logger.Fix1, logger.Fix2 - | public void test() { - |- logger.infof("some %s", 1); - |+ logger.info("some {}", 1); - | System.out.println("1"); - | System.out.println("2"); - | System.out.println("3"); - |@@ -8,5 +8,5 @@ - | System.out.println("6"); - | System.out.println("7"); - | System.out.println("8"); - |- logger.infof("some %s", 2); - |+ logger.info("some %s", 2); - | } - | - """.trimMargin() - ).isEqualTo(diff) - } - - @Test - fun addFile() { - val diff = Result.InMemoryDiffEntry( - null, filePath, null, - "", - """ - |public void test() { - | logger.info("Hello Fred"); - |} - | - """.trimMargin(), - setOf( - object : Recipe() { - override fun getName(): String = "logger.Fix1" - override fun getDisplayName(): String { - return name - } - } - )).diff - - assertThat(diff).isEqualTo( - """ - |diff --git a/com/netflix/MyJavaClass.java b/com/netflix/MyJavaClass.java - |new file mode 100644 - |index 0000000..efeb105 - |--- /dev/null - |+++ b/com/netflix/MyJavaClass.java - |@@ -0,0 +1,3 @@ logger.Fix1 - |+public void test() { - |+ logger.info("Hello Fred"); - |+} - | - """.trimMargin() - ) - } - - @Test - fun deleteFile() { - val diff = Result.InMemoryDiffEntry( - filePath, null, null, - """ - |public void test() { - | logger.info("Hello Fred"); - |} - | - """.trimMargin(), - "", - setOf( - object : Recipe() { - override fun getName(): String = "logger.Fix1" - override fun getDisplayName(): String { - return name - } - } - )).diff - - assertThat(diff).isEqualTo( - """ - |diff --git a/com/netflix/MyJavaClass.java b/com/netflix/MyJavaClass.java - |deleted file mode 100644 - |index efeb105..0000000 - |--- a/com/netflix/MyJavaClass.java - |+++ /dev/null - |@@ -1,3 +0,0 @@ logger.Fix1 - |-public void test() { - |- logger.info("Hello Fred"); - |-} - | - """.trimMargin() - ) - - } - -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/TreeObserverTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/TreeObserverTest.kt deleted file mode 100644 index 5e2d7f25cec..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/TreeObserverTest.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2022 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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 - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.openrewrite.text.PlainText -import org.openrewrite.text.PlainTextParser -import org.openrewrite.text.PlainTextVisitor -import java.util.concurrent.atomic.AtomicInteger - -class TreeObserverTest { - - @Test - fun observePropertyChange() { - val t = PlainTextParser().parse( - """ - hello jon - """.trimIndent() - ) - - val observed = AtomicInteger(0) - - val ctx = InMemoryExecutionContext() - ctx.addObserver(TreeObserver.Subscription(object : TreeObserver { - override fun propertyChanged( - property: String, - cursor: Cursor, - newTree: Tree, - oldValue: Any, - newValue: Any - ): Tree { - if (property == "text") { - observed.incrementAndGet() - } - return newTree - } - }).subscribeToType(PlainText::class.java)) - - object : Recipe() { - override fun getDisplayName(): String = "Change hello" - - override fun getVisitor(): PlainTextVisitor = - object : PlainTextVisitor() { - override fun visitText(text: PlainText, p: ExecutionContext): PlainText { - return text.withText("hello jonathan") - } - } - }.run(t, ctx) - - assertThat(observed.get()).isEqualTo(1) - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/internal/ListUtilsTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/internal/ListUtilsTest.kt deleted file mode 100644 index eab7b67a69a..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/internal/ListUtilsTest.kt +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2020 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.internal - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class ListUtilsTest { - - @Test - fun flatMap() { - val l = listOf(1.0, 2.0, 3.0) - assertThat(ListUtils.flatMap(l) { l2 -> - if(l2.toInt() % 2 == 0) { - listOf(2.0, 2.1, 2.2) - } else { - l2 - } - }).containsExactly(1.0, 2.0, 2.1, 2.2, 3.0) - } - - @Test - fun replaceSingleWithMultipleAtPosition0() { - val l = listOf(1) - assertThat(ListUtils.flatMap(l) { _ -> listOf(2, 3) }).containsExactly(2, 3) - } - @Test - fun removeSingleItem() { - val l = listOf(1, 2, 3) - assertThat(ListUtils.flatMap(l) { l1 -> - if (l1.equals(2)) { - null - } else { - l1 - } - }).containsExactly(1, 3) - } - - @Test - fun replaceItemWithCollectionThenRemoveNextItem() { - val l = listOf(2, 0) - assertThat(ListUtils.flatMap(l) { l1 -> - if (l1.equals(2)) { - listOf(10, 11) - } else { - null - } - }).containsExactly(10, 11) - } - - @Test - fun removeByAddingEmptyCollection() { - val l = listOf(2, 0) - assertThat(ListUtils.flatMap(l) { l1 -> - if (l1.equals(2)) { - listOf(10, 11) - } else { - listOf() - } - }).containsExactly(10, 11) - } - -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/internal/NameCaseConventionTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/internal/NameCaseConventionTest.kt deleted file mode 100644 index 99972e74f69..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/internal/NameCaseConventionTest.kt +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2021 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.internal - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.CsvSource - -@Suppress("SpellCheckingInspection") -class NameCaseConventionTest { - - @ParameterizedTest - @CsvSource( - value = [ - "foo.config-client.enabled:foo.config-client.enabled", - "com.fooBar.FooBar:com.foo-bar.foo-bar", - "foo_bar.bar:foo-bar.bar", - "FooBar:foo-bar", - "com.bar.FooBar:com.bar.foo-bar", - "Foo:foo", - "FooBBar:foo-bbar", - "fooBBar:foo-bbar", - "fooBar:foo-bar", - "foo bar:foo-bar", - " foo bar :foo-bar", - ], delimiter = ':' - ) - fun lowerHyphen(input: String, expected: String) { - assertThat(NameCaseConvention.LOWER_HYPHEN.format(input)).isEqualTo(expected) - } - - @ParameterizedTest - @CsvSource( - value = [ - "a:a", - "abc:abc", - "1:1", - "123:123", - "1a:1a", - "a1:a1", - "\$:\$", - "\$a:\$a", - "a\$:a\$", - "a\$a:a\$a", - "a_a:a_a", - "Foo:foo", - "Foo-Bar:foo_bar", - "FOO.FOO-BAR:foo.foo_bar", - "foo bar:foo_bar", - " foo bar :foo_bar", - ], delimiter = ':' - ) - fun lowerUnderscore(input: String, expected: String) { - assertThat(NameCaseConvention.LOWER_UNDERSCORE.format(input)).isEqualTo(expected) - } - - @ParameterizedTest - @CsvSource( - value = [ - "ID:id", - "rename_one:renameOne", - "RenameTwo:renameTwo", - "__rename__three__:renameThree", - "_Rename___Four_:renameFour", - "\$a:\$a", - "a\$:a\$", - "a\$a:a\$a", - "a_a:aA", - "_a:a", - "foo.config-client.enabled:foo.configClient.enabled", - "foo-bar:fooBar", - "foo bar:fooBar", - " foo bar :fooBar", - "FOO_BAR:fooBar", - ], delimiter = ':' - ) - fun lowerCamel(input: String, expected: String) { - assertThat(NameCaseConvention.LOWER_CAMEL.format(input)).isEqualTo(expected) - } - - @ParameterizedTest - @CsvSource( - value = [ - "rename_one:RenameOne", - "RenameTwo:RenameTwo", - "__rename__three__:RenameThree", - "_Rename__Four:RenameFour", - "foo-bar:FooBar", - "foo bar:FooBar", - " foo bar :FooBar", - ], delimiter = ':' - ) - fun upperCamel(input: String, expected: String) { - assertThat(NameCaseConvention.UPPER_CAMEL.format(input)).isEqualTo(expected) - } - - @ParameterizedTest - @CsvSource( - value = [ - "foo:FOO", - "foo-bar:FOO_BAR", - "foo_bar:FOO_BAR", - "FooBar:FOO_BAR", - "Foo.fooBar:FOO.FOO_BAR", - "foo bar:FOO_BAR", - " foo bar :FOO_BAR", - ], delimiter = ':' - ) - fun upperUnderscore(input: String, expected: String) { - assertThat(NameCaseConvention.UPPER_UNDERSCORE.format(input)).isEqualTo(expected) - } - - @ParameterizedTest - @CsvSource( - value = [ - "foo.fooBar:foo.foo-bar", - "foo.foo-bar:foo.fooBar", - ], delimiter = ':' - ) - fun equalsRelaxedBinding(input: String, expected: String) { - assertThat(NameCaseConvention.equalsRelaxedBinding(input, expected)).isTrue - } - - @Test - fun matchesRelaxedBinding() { - assertThat( - NameCaseConvention.matchesRelaxedBinding( - "spring.registration.test.identityprovider", - "spring.registration.*.identityprovider" - ) - ).isTrue - assertThat( - NameCaseConvention.matchesRelaxedBinding( - "spring.registration.test.assertingparty", - "spring.registration.*.identityprovider" - ) - ).isFalse - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/internal/RecipeIntrospectionUtilsTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/internal/RecipeIntrospectionUtilsTest.kt deleted file mode 100644 index e3d2c173279..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/internal/RecipeIntrospectionUtilsTest.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2022 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.internal - -import org.junit.jupiter.api.Test -import org.openrewrite.Option -import org.openrewrite.Recipe - -class RecipeIntrospectionUtilsTest { - - @Test - fun kotlinNonNullConstructorArgs() { - RecipeIntrospectionUtils.constructRecipe(TestRecipe::class.java) - } - - enum class EnumOption { - Value - } - - class TestRecipe constructor( - @Option val option1: String, - @Option val option2: EnumOption, - @Option val option3: List, - @Option val option4: Boolean - ) : Recipe() { - override fun getDisplayName() = "Test" - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/internal/StringUtilsTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/internal/StringUtilsTest.kt deleted file mode 100644 index 16cfe9a1321..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/internal/StringUtilsTest.kt +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2020 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.internal - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.openrewrite.Issue -import org.openrewrite.internal.StringUtils.* - -class StringUtilsTest { - - @Test - fun trimIndentBlankLines() { - val input = """ - - class { - - A field; - } - """ - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun trimIndentEndLineNonWhitespace() { - val input = """ - - class { - - A field; - } - hello""" - System.out.println("Kotlin : '" + input.trimIndent() + "'") - - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun trimIndentFirstLineSameAsIndent() { - val input = """ - - class { - - A field; - } - """ - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun trimIndentFirstLineGreaterThanIndent() { - val input = """ - - class { - - A field; - } - """ - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun trimIndentFirstLineEmpty() { - val input = """ - - class { - - A field; - } - """ - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun trimIndentNoNewLine() { - val input = " a" - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun trimIndentOneCharacter() { - val input = "a" - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun trimIndentFirstLineNotEmpty() { - val input = """ - fred - class { - - A field; - } - """ - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun trimIndentFirstCharacterNotLineBreak() { - val input = """fred - class { - - A field; - } - """ - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun trimIndentMinimalIndent() { - val input = """ - class { - A field; - } - """ - - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun trimIndentNoIndent() { - val input = "class{\n A field;\n}" - - assertThat(trimIndent(input)).isEqualTo(input.trimIndent()) - } - - @Test - fun containsOnlyWhitespaceAndCommentsTest() { - assertThat(containsOnlyWhitespaceAndComments("")).isTrue - assertThat(containsOnlyWhitespaceAndComments(" \n\r\t")).isTrue - assertThat(containsOnlyWhitespaceAndComments(" // hello ")).isTrue - assertThat(containsOnlyWhitespaceAndComments("//")).isTrue - assertThat(containsOnlyWhitespaceAndComments("/**/")).isTrue - assertThat(containsOnlyWhitespaceAndComments(""" - /** - asdf - */ - """)).isTrue - - assertThat(containsOnlyWhitespaceAndComments("a")).isFalse - assertThat(containsOnlyWhitespaceAndComments(""" - // hello - goodbye - """)).isFalse - assertThat(containsOnlyWhitespaceAndComments("a//")).isFalse - assertThat(containsOnlyWhitespaceAndComments( - """ - /* - */ - a - """)).isFalse - } - - @Test - fun replaceFirst() { - var result = replaceFirst("#{} Fred #{}", "#{}", "I am") - assertThat(result).isEqualTo("I am Fred #{}") - result = replaceFirst(result, "#{}", "surely.") - assertThat(result).isEqualTo("I am Fred surely.") - result = replaceFirst("#{}#{}#{}", "#{}", "yo") - assertThat(result).isEqualTo("yo#{}#{}") - result = replaceFirst(result, "#{}", "yo") - assertThat(result).isEqualTo("yoyo#{}") - result = replaceFirst(result, "#{}", "yo") - assertThat(result).isEqualTo("yoyoyo") - result = replaceFirst("Nothing to see here", "#{}", "nonsense") - assertThat(result).isEqualTo("Nothing to see here") - result = replaceFirst("Nothing to see here", "", "nonsense") - assertThat(result).isEqualTo("Nothing to see here") - result = replaceFirst("", "", "nonsense") - assertThat(result).isEqualTo("") - } - - @Test - fun occurrenceCount() { - assertThat(countOccurrences("yoyoyoyoyo", "yo")).isEqualTo(5) - assertThat(countOccurrences("yoyoyoyoyo", "yoyo")).isEqualTo(2) - assertThat(countOccurrences("nonononono", "yo")).isEqualTo(0) - assertThat(countOccurrences("", "")).isEqualTo(0) - } - - @Test - fun globMatching() { - assertThat(matchesGlob("expression", "expr*")).isTrue - assertThat(matchesGlob("some/xpath", "some/*")).isTrue - assertThat(matchesGlob("some/xpath/expression", "some/**")).isTrue - assertThat(matchesGlob("//some/xpath/expression", "**/xpath/*")).isTrue - } - - @Test - fun greatestCommonMargin() { - assertThat(greatestCommonMargin(""" - | - | - | - """.trimMargin("|"))).isEqualTo(" ") - - assertThat(greatestCommonMargin(""" - | - | s - | - """.trimMargin("|"))).isEqualTo(" ") - - assertThat(greatestCommonMargin("")).isEqualTo("") - assertThat(greatestCommonMargin("\n\n")).isEqualTo("") - } - - @Test - fun greatestCommonSubstringLength() { - assertThat(greatestCommonSubstringLength("", "")).isEqualTo(0) - assertThat(greatestCommonSubstringLength("abc", "def")).isEqualTo(0) - assertThat(greatestCommonSubstringLength("abc1", "1")).isEqualTo(1) - } - - @Test - fun allowConsecutiveLineBreaks() { - assertThat(trimIndentPreserveCRLF(" \n \n a")).isEqualTo("\n\na") - } - - @Issue("https://github.com/openrewrite/rewrite/issues/2268") - @Test - fun trailingCrlf() { - assertThat(trimIndentPreserveCRLF(" \r\n \r\n a\r\n")).isEqualTo("\r\n\r\na") - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/internal/lang/NullUtilsTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/internal/lang/NullUtilsTest.kt deleted file mode 100644 index cedf53bde19..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/internal/lang/NullUtilsTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2020 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.internal.lang - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.openrewrite.internal.lang.nonnull.DefaultNonNullTest -import org.openrewrite.internal.lang.nullable.NonNullTest - -class NullUtilsTest { - - @Test - fun testPackageNonNullDefault() { - val results = NullUtils.findNonNullFields(DefaultNonNullTest::class.java) - assertThat(results).hasSize(4) - assertThat(results[0].name).isEqualTo("aCoolNonNullName") - assertThat(results[1].name).isEqualTo("beCoolNonNullName") - assertThat(results[2].name).isEqualTo("coolNonNullName") - assertThat(results[3].name).isEqualTo("yourCoolNonNullName") - } - - @Test - fun testNonNulls() { - val results = NullUtils.findNonNullFields(NonNullTest::class.java) - assertThat(results).hasSize(4) - assertThat(results[0].name).isEqualTo("aCoolNonNullName") - assertThat(results[1].name).isEqualTo("beCoolNonNullName") - assertThat(results[2].name).isEqualTo("coolNonNullName") - assertThat(results[3].name).isEqualTo("yourCoolNonNullName") - } - - @Test - fun noMemberFields() { - val results = NullUtils.findNonNullFields(NoMembers::class.java) - assertThat(results).isEmpty() - } - - class NoMembers { - } -} \ No newline at end of file diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/marker/GitProvenanceTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/marker/GitProvenanceTest.kt deleted file mode 100644 index 04ca63d781d..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/marker/GitProvenanceTest.kt +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2022 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.marker - -import org.assertj.core.api.Assertions.assertThat -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.lib.ConfigConstants.CONFIG_BRANCH_SECTION -import org.eclipse.jgit.lib.Constants -import org.eclipse.jgit.lib.RepositoryCache -import org.eclipse.jgit.transport.TagOpt -import org.eclipse.jgit.transport.URIish -import org.eclipse.jgit.util.FS -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.io.TempDir -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.MethodSource -import org.openrewrite.Tree.randomId -import org.openrewrite.marker.ci.JenkinsBuildEnvironment -import java.nio.file.Files -import java.nio.file.Path -import java.util.concurrent.TimeUnit -import kotlin.io.path.writeText - -class GitProvenanceTest { - companion object { - @JvmStatic - fun remotes() = arrayOf( - "ssh://git@github.com/openrewrite/rewrite.git", - "https://github.com/openrewrite/rewrite.git", - "file:///openrewrite/rewrite.git", - "http://localhost:7990/scm/openrewrite/rewrite.git", - "git@github.com:openrewrite/rewrite.git" - ) - } - - @ParameterizedTest - @MethodSource("remotes") - fun getOrganizationName(remote: String) { - assertThat(GitProvenance(randomId(), remote, "main", "123", null, null).organizationName) - .isEqualTo("openrewrite") - } - - @ParameterizedTest - @MethodSource("remotes") - fun getRepositoryName(remote: String) { - assertThat(GitProvenance(randomId(), remote, "main", "123", null, null).repositoryName) - .isEqualTo("rewrite") - } - - @Test - fun localBranchPresent(@TempDir projectDir: Path) { - Git.init().setDirectory(projectDir.toFile()).setInitialBranch("main").call().use { - assertThat(GitProvenance.fromProjectDirectory(projectDir, null)!!.branch) - .isEqualTo("main") - } - } - - @Test - fun detachedHead(@TempDir projectDir: Path) { - initGitWithOneCommit(projectDir).use { git -> - git.checkout().setName(git.repository.resolve(Constants.HEAD).name).call() - assertThat(GitProvenance.fromProjectDirectory(projectDir, null)!!.branch) - .isEqualTo("main") - } - } - - @Test - fun detachedHeadJenkinsLocalBranch(@TempDir projectDir: Path) { - initGitWithOneCommit(projectDir).use { git -> - git.checkout().setName(git.repository.resolve(Constants.HEAD).name).call() - assertThat( - GitProvenance.fromProjectDirectory( - projectDir, - JenkinsBuildEnvironment( - randomId(), "1", "1", "https://jenkins/job/1", - "https://jenkins", "job", "main", "origin/main" - ) - )!!.branch - ).isEqualTo("main") - } - } - - @Test - fun detachedHeadJenkinsNoLocalBranch(@TempDir projectDir: Path) { - initGitWithOneCommit(projectDir).use { git -> - git.checkout().setName(git.repository.resolve(Constants.HEAD).name).call() - - assertThat( - GitProvenance.fromProjectDirectory( - projectDir, - JenkinsBuildEnvironment(randomId(), "1", "1", "https://jenkins/job/1", - "https://jenkins", "job", null, "origin/main") - )!!.branch - ).isEqualTo("main") - } - - } - - private fun initGitWithOneCommit(projectDir: Path): Git { - val git = Git.init().setDirectory(projectDir.toFile()).setInitialBranch("main").call() - projectDir.resolve("test.txt").writeText("hi") - git.add().addFilepattern("*").call() - git.commit().setMessage("init").setSign(false).call() - git.remoteAdd().setName("origin").setUri(URIish("git@github.com:openrewrite/doesnotexist.git")).call() - - // origins are still present in .git/config on Jenkins - val config = git.repository.config - config.setString(CONFIG_BRANCH_SECTION, "main", "remote", "origin") - config.setString(CONFIG_BRANCH_SECTION, "main", "merge", "refs/heads/main") - config.save() - - return git - } - - @Test - fun detachedHeadBehindBranchHead(@TempDir projectDir: Path) { - Git.init().setDirectory(projectDir.toFile()).setInitialBranch("main").call().use { git -> - projectDir.resolve("test.txt").writeText("hi") - git.add().addFilepattern("*").call() - git.commit().setMessage("init").setSign(false).call() - val commit1 = git.repository.resolve(Constants.HEAD).name - - projectDir.resolve("test.txt").writeText("hi") - git.add().addFilepattern("*").call() - git.commit().setMessage("init").setSign(false).call() - - assertThat(git.repository.resolve(Constants.HEAD).name).isNotEqualTo(commit1) - - git.checkout().setName(commit1).call() - - assertThat(GitProvenance.fromProjectDirectory(projectDir, null)!!.branch) - .isEqualTo("main") - } - } - - @Test - fun shallowCloneDetachedHead(@TempDir projectDir: Path) { - val remoteDir = projectDir.resolve("remote") - val fileKey = RepositoryCache.FileKey.exact(remoteDir.toFile(), FS.DETECTED) - val remoteRepo = fileKey.open(false) - remoteRepo.create(true) - - // push an initial commit to the remote - val cloneDir = projectDir.resolve("clone1") - Git.cloneRepository().setURI(remoteRepo.directory.absolutePath).setDirectory(cloneDir.toFile()).call().use { git -> - projectDir.resolve("test.txt").writeText("hi") - git.add().addFilepattern("*").call() - git.commit().setMessage("init").setSign(false).call() - - try { - "git push -u origin main".runCommand(cloneDir) - val commit = git.repository.resolve(Constants.HEAD).name - - // shallow clone the remote to another directory - "git clone file:///${remoteRepo.directory.absolutePath} shallowClone --depth 1 --branch main".runCommand( - projectDir - ) - val git2 = Git.open(projectDir.resolve("shallowClone").toFile()) - - // creates detached head - git2.checkout().setName(commit).call() - - assertThat(GitProvenance.fromProjectDirectory(projectDir.resolve("shallowClone"), null)!!.branch) - .isEqualTo(null) - } catch (ignored: Throwable) { - // can't run git command line - } - } - } - - @Test - fun noLocalBranchDeriveFromRemote(@TempDir projectDir: Path) { - - val remoteDir = projectDir.resolve("remote") - val fileKey = RepositoryCache.FileKey.exact(remoteDir.toFile(), FS.DETECTED) - val remoteRepo = fileKey.open(false) - remoteRepo.create(true) - - // push an initial commit to the remote - val cloneDir = projectDir.resolve("clone1") - val gitSetup = Git.cloneRepository().setURI(remoteRepo.directory.absolutePath).setDirectory(cloneDir.toFile()).call() - projectDir.resolve("test.txt").writeText("hi") - gitSetup.add().addFilepattern("*").call() - val commit = gitSetup.commit().setMessage("init").setSign(false).call() - gitSetup.push().add("master").setRemote("origin").call() - - //Now create new workspace directory, git init and then fetch from remote. - val workspaceDir = projectDir.resolve("workspace") - Git.init().setDirectory(workspaceDir.toFile()).call().use { git -> - git.remoteAdd().setName("origin").setUri(URIish(remoteRepo.directory.absolutePath)).call() - git.fetch().setRemote("origin").setForceUpdate(true).setTagOpt(TagOpt.FETCH_TAGS).setRefSpecs("+refs/heads/*:refs/remotes/origin/*").call() - git.checkout().setName(commit.name).call() - } - - try { - assertThat(GitProvenance.fromProjectDirectory(projectDir.resolve("workspace"), null)!!.branch) - .isEqualTo("master") - } catch (ignored: Throwable) { - // can't run git command line - } - } - - private fun String.runCommand(workingDir: Path) { - workingDir.toFile().mkdirs() - ProcessBuilder(*split(" ").toTypedArray()) - .directory(workingDir.toFile()) - .redirectOutput(ProcessBuilder.Redirect.INHERIT) - .redirectError(ProcessBuilder.Redirect.INHERIT) - .start() - .waitFor(5, TimeUnit.SECONDS) - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/quark/.editorconfig b/rewrite-core/src/test/kotlin/org/openrewrite/quark/.editorconfig deleted file mode 100644 index a32e5c2e7a5..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/quark/.editorconfig +++ /dev/null @@ -1,5 +0,0 @@ -root = true - -[QuarkTest.java] -indent_size = 4 -ij_continuation_indent_size = 2 diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/quark/QuarkParserTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/quark/QuarkParserTest.kt deleted file mode 100644 index 58574e3aa04..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/quark/QuarkParserTest.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2022 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.quark - -import org.assertj.core.api.Assertions.assertThat -import org.eclipse.jgit.api.Git -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.io.TempDir -import org.openrewrite.ExecutionContext -import org.openrewrite.SourceFile -import org.openrewrite.TreeVisitor -import org.openrewrite.test.RewriteTest -import org.openrewrite.test.RewriteTest.toRecipe -import org.openrewrite.test.SourceSpecs -import org.openrewrite.test.SourceSpecs.other -import org.openrewrite.test.SourceSpecs.text -import java.nio.file.Path -import java.nio.file.Paths -import kotlin.io.path.readText -import kotlin.io.path.writeText - -class QuarkParserTest : RewriteTest { - - @Test - fun allOthers() = rewriteRun( - { spec -> - spec.beforeRecipe { sources -> - val quarks = QuarkParser.parseAllOtherFiles(Paths.get("../"), sources) - assertThat(quarks).isNotEmpty - assertThat(quarks.map { it.sourcePath }).doesNotContain(Paths.get("build.gradle.kts")) - } - }, - text("hi") { spec -> spec.path(Paths.get("build.gradle.kts")) }, - ) - - @Test - fun oneQuark() = rewriteRun( - { spec -> - spec.beforeRecipe { sources -> - assertThat(sources.map { it::class.java }).containsOnlyOnce(Quark::class.java) - } - }, - text("hi"), - other("jon") - ) - - @Test - fun renameQuark(@TempDir tempDir: Path) = rewriteRun( - { spec -> - spec.expectedCyclesThatMakeChanges(1) - .recipe(toRecipe { - object : TreeVisitor() { - override fun visitSourceFile(sourceFile: SourceFile, p: ExecutionContext): SourceFile { - return if (sourceFile.sourcePath.toString().endsWith(".bak")) { - sourceFile - } else sourceFile.withSourcePath(Paths.get(sourceFile.sourcePath.toString() + ".bak")) - } - } - }) - .afterRecipe { run -> - run.results.forEach { - val git = Git.init().setDirectory(tempDir.toFile()).call() - git.apply().setPatch(it.diff().byteInputStream()).call() - } - assertThat(tempDir.toFile().list()) - .containsExactlyInAnyOrder("hi.txt.bak", "jon.bak", ".git") - assertThat(tempDir.resolve("jon.bak").readText().trim()).isEqualTo("jon") - } - }, - text("hi") { spec -> - spec.path("hi.txt") - .beforeRecipe { s -> tempDir.resolve(s.sourcePath).writeText("hi") } - .afterRecipe { s -> assertThat(s.sourcePath).isEqualTo(Paths.get("hi.txt.bak")) } - }, - other("jon") { spec -> - spec.path("jon") - .beforeRecipe { s -> tempDir.resolve(s.sourcePath).writeText("jon") } - .afterRecipe { s -> assertThat(s.sourcePath).isEqualTo(Paths.get("jon.bak")) } - } - ) -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/semver/CaretRangeTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/semver/CaretRangeTest.kt deleted file mode 100644 index 61c600cf3ec..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/semver/CaretRangeTest.kt +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2021 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.semver - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class CaretRangeTest { - - @Test - fun isValidWhenCurrentIsNull() { - val caretRange: CaretRange = CaretRange.build("^1", null).getValue()!! - assertThat(caretRange.isValid(null, "1.0.0")).isTrue - } - - @Test - fun pattern() { - assertThat(CaretRange.build("^1", null).isValid).isTrue - assertThat(CaretRange.build("^1.2", null).isValid).isTrue - assertThat(CaretRange.build("^1.2.3", null).isValid).isTrue - assertThat(CaretRange.build("^1.2.3.4", null).isValid).isTrue - assertThat(CaretRange.build("^1.2.3.4.5", null).isValid).isFalse - } - - @Test - fun updateMicro() { - val caretRange: CaretRange = CaretRange.build("^1.2.3.4", null).getValue()!! - - assertThat(caretRange.isValid("1.0", "1.2.3.4")).isTrue - assertThat(caretRange.isValid("1.0", "1.2.3.4.RELEASE")).isTrue - assertThat(caretRange.isValid("1.0", "1.2.3.5")).isTrue - assertThat(caretRange.isValid("1.0", "1.2.4")).isTrue - assertThat(caretRange.isValid("1.0", "1.9.0")).isTrue - assertThat(caretRange.isValid("1.0", "1.2.3.3")).isFalse - assertThat(caretRange.isValid("1.0", "2.0.0")).isFalse - } - - /** - * ^1.2.3 := >=1.2.3 <2.0.0 - */ - @Test - fun updateMinorAndPatch() { - val caretRange: CaretRange = CaretRange.build("^1.2.3", null).getValue()!! - - assertThat(caretRange.isValid("1.0", "1.2.3")).isTrue - assertThat(caretRange.isValid("1.0", "1.2.3.RELEASE")).isTrue - assertThat(caretRange.isValid("1.0", "1.2.4")).isTrue - assertThat(caretRange.isValid("1.0", "1.9.0")).isTrue - assertThat(caretRange.isValid("1.0", "2.0.0")).isFalse - } - - /** - * ^0.2.3 := >=0.2.3 <0.3.0 - */ - @Test - fun updatePatch() { - val caretRange: CaretRange = CaretRange.build("^0.2.3", null).getValue()!! - - assertThat(caretRange.isValid("1.0", "0.2.3")).isTrue - assertThat(caretRange.isValid("1.0", "0.2.4")).isTrue - assertThat(caretRange.isValid("1.0", "0.3.0")).isFalse - } - - @Test - fun updateNothing() { - val caretRange: CaretRange = CaretRange - .build("^0.0.3", null) - .getValue()!! - - assertThat(caretRange.isValid("1.0", "0.0.3")).isFalse - assertThat(caretRange.isValid("1.0", "0.0.4")).isFalse - } - - /** - * ^1.x := >=1.0.0 <2.0.0 - */ - @Test - fun desugarMinorWildcard() { - val caretRange: CaretRange = CaretRange.build("^1.x", null).getValue()!! - - assertThat(caretRange.isValid("1.0", "1.0.0")).isTrue - assertThat(caretRange.isValid("1.0", "1.0.1")).isTrue - assertThat(caretRange.isValid("1.0", "1.1.0")).isTrue - assertThat(caretRange.isValid("1.0", "2.0.0")).isFalse - } - - /** - * ^0.0.x := >=0.0.0 <0.1.0 - */ - @Test - fun desugarPatchWildcard() { - val caretRange: CaretRange = CaretRange.build("^0.0.x", null).getValue()!! - - assertThat(caretRange.isValid("1.0", "0.0.0")).isTrue - assertThat(caretRange.isValid("1.0", "0.0.1")).isTrue - assertThat(caretRange.isValid("1.0", "0.1.0")).isFalse - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/semver/LatestPatchTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/semver/LatestPatchTest.kt deleted file mode 100644 index 65803296523..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/semver/LatestPatchTest.kt +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2021 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.semver - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import java.util.* - -class LatestPatchTest { - private val latestPatch = LatestPatch(null) - private val latestMetadataPatch = LatestPatch("-fred") - - @Test - fun isValidWhenCurrentIsNull() { - assertThat(latestPatch.isValid(null, "1.0.0")).isTrue - } - - @Test - fun isValid() { - assertThat(latestPatch.isValid("1.0.0", "1.0.0")).isTrue - assertThat(latestPatch.isValid("1.0.0", "1.0.0.1")).isTrue - assertThat(latestPatch.isValid("1.0.0", "1.0.1")).isTrue - assertThat(latestPatch.isValid("1.0", "1.0.1")).isTrue - assertThat(latestPatch.isValid("1.0.0", "1.1.0")).isFalse - assertThat(latestPatch.isValid("1.0.0", "2.0.0")).isFalse - } - - @Test - fun upgrade() { - var upgrade = latestPatch.upgrade("2.10.10.3.24", Arrays.asList("2.10.0")) - assertThat(upgrade.isPresent).isFalse() - - upgrade = latestPatch.upgrade("2.10.10.3.24", Arrays.asList("2.11.0")) - assertThat(upgrade.isPresent).isFalse() - upgrade = latestPatch.upgrade("2.10.10.3.24", Arrays.asList("2.10.9")) - assertThat(upgrade.isPresent).isFalse() - - upgrade = latestPatch.upgrade("2.10.10.3.24", Arrays.asList("2.10.11")) - assertThat(upgrade.isPresent).isTrue() - assertThat(upgrade.get()).isEqualTo("2.10.11") - - upgrade = latestPatch.upgrade("2.10.10.3.24", Arrays.asList("2.10.10.3.23")) - assertThat(upgrade.isPresent).isFalse() - - upgrade = latestPatch.upgrade("2.10.10.3.24", Arrays.asList("2.10.10.2.25")) - assertThat(upgrade.isPresent).isFalse() - - upgrade = latestPatch.upgrade("2.10.10.3.24", Arrays.asList("2.10.10.3.25")) - assertThat(upgrade.isPresent).isTrue() - assertThat(upgrade.get()).isEqualTo("2.10.10.3.25") - } - - @Test - fun compare() { - assertThat(latestPatch.compare("1.0", "1.0.1", "1.0.2")).isLessThan(0) - assertThat(latestPatch.compare("1.0", "1.0.0.1", "1.0.1")).isLessThan(0) - } - - @Test - fun metadataValid() { - assertThat(latestMetadataPatch.isValid("1.0.0-fred", "1.0.4-fred")).isTrue - assertThat(latestMetadataPatch.isValid("1.0-fred", "1.0.1-fred")).isTrue - assertThat(latestMetadataPatch.isValid("1.0.0-fred", "1.0.4-not-fred")).isFalse - } - - @Test - fun metadataUpgrade() { - var upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", Arrays.asList("2.10.0-fred")) - assertThat(upgrade.isPresent).isFalse() - - upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", Arrays.asList("2.11.0-fred")) - assertThat(upgrade.isPresent).isFalse() - upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", Arrays.asList("2.10.9-fred")) - assertThat(upgrade.isPresent).isFalse() - - upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", Arrays.asList("2.10.11-fred")) - assertThat(upgrade.isPresent).isTrue() - assertThat(upgrade.get()).isEqualTo("2.10.11-fred") - - upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", Arrays.asList("2.10.10.3.23-fred")) - assertThat(upgrade.isPresent).isFalse() - - upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", Arrays.asList("2.10.10.2.25-fred")) - assertThat(upgrade.isPresent).isFalse() - - upgrade = latestMetadataPatch.upgrade("2.10.10.3.24-fred", Arrays.asList("2.10.10.3.25-fred")) - assertThat(upgrade.isPresent).isTrue() - assertThat(upgrade.get()).isEqualTo("2.10.10.3.25-fred") - } - -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/semver/LatestReleaseTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/semver/LatestReleaseTest.kt deleted file mode 100644 index 8b95503af77..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/semver/LatestReleaseTest.kt +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2021 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.semver - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertAll - -class LatestReleaseTest { - private val latestRelease = LatestRelease(null) - - @Test - fun isValidWhenCurrentIsNull() { - assertThat(latestRelease.isValid(null, "1.0.0")).isTrue - } - - @Test - fun onlyNumericPartsValid() { - assertAll( - { assertThat(latestRelease.isValid("1.0", "1.1.1.1")).isTrue }, - { assertThat(latestRelease.isValid("1.0", "1.1.1")).isTrue }, - { assertThat(latestRelease.isValid("1.0", "1.1")).isTrue }, - { assertThat(latestRelease.isValid("1.0", "1")).isTrue }, - { assertThat(latestRelease.isValid("1.0", "1.1.a")).isFalse }, - { assertThat(latestRelease.isValid("1.0", "1.1.1.1.a")).isFalse }, - { assertThat(latestRelease.isValid("1.0", "1.1.1.1.1")).isTrue }, - { assertThat(latestRelease.isValid("1.0", "1.1.1.1.1-SNAPSHOT")).isFalse }, - { assertThat(latestRelease.isValid("1.0", "1.1.0-SNAPSHOT")).isFalse } - ) - } - - @Test - fun differentMicroVersions() { - assertThat(latestRelease.compare("1.0", "1.1.1.1", "1.1.1.2")).isLessThan(0) - assertThat(latestRelease.compare("1.0", "1", "1.1.1.1")).isLessThan(0) - assertThat(latestRelease.compare("1.0", "1.1.1.1", "2")).isLessThan(0) - } - - @Test - fun differentPatchVersions() { - assertThat(latestRelease.compare("1.0", "1.1.1.1", "1.1.2.1")).isLessThan(0) - assertThat(latestRelease.compare("1.0", "1.1.1", "1.1.2")).isLessThan(0) - } - - @Test - fun differentMinorVersions() { - assertThat(latestRelease.compare("1.0", "1.1.1.1", "1.2.1.1")).isLessThan(0) - assertThat(latestRelease.compare("1.0", "1.1.1", "1.2.1")).isLessThan(0) - assertThat(latestRelease.compare("1.0", "1.1", "1.2")).isLessThan(0) - } - - @Test - fun differentMajorVersions() { - assertThat(latestRelease.compare("1.0", "1.1.1.1", "2.1.1.1")).isLessThan(0) - assertThat(latestRelease.compare("1.0", "1.1.1", "2.1.1")).isLessThan(0) - assertThat(latestRelease.compare("1.0", "1.1", "2.1")).isLessThan(0) - assertThat(latestRelease.compare("1.0", "1", "2")).isLessThan(0) - } - - @Test - fun differentNumberOfParts() { - assertThat(latestRelease.compare("1.0", "1.1.1", "1.1.1.1")).isLessThan(0) - assertThat(latestRelease.compare("1.0", "1.1", "1.1.1")).isLessThan(0) - assertThat(latestRelease.compare("1.0", "1", "1.1")).isLessThan(0) - } - - @Test - fun guavaVariants() { - assertThat(latestRelease.compare("1.0", "25.0-jre", "29.0-jre")).isLessThan(0) - } - - @Test - @Disabled("https://github.com/openrewrite/rewrite/issues/1204") - // feel free to move this under "guavaVariants", todo - fun guavaVariantsMetadataBoundaries() { - assertThat(latestRelease.compare("1.0", "25", "25.0-jre")).isEqualTo(0) - } - - @Test - fun matchMetadata() { - assertThat(LatestRelease("-jre").isValid("1.0", "29.0.0.0-jre")).isTrue - assertThat(LatestRelease("-jre").isValid("1.0", "29.0-jre")).isTrue - assertThat(LatestRelease("-jre").isValid("1.0", "29.0")).isFalse - assertThat(LatestRelease("-jre").isValid("1.0", "29.0-android")).isFalse - assertThat(LatestRelease("").isValid("1.0", "29.0")).isTrue - assertThat(LatestRelease("").isValid("1.0", "29.0-jre")).isFalse - assertThat(LatestRelease(null).isValid("1.0", "29.0-jre")).isFalse - } - - @Test - fun normalizeVersionStripReleaseSuffix() { - assertThat(LatestRelease.normalizeVersion("1.5.1.2.RELEASE")).isEqualTo("1.5.1.2") - assertThat(LatestRelease.normalizeVersion("1.5.1.RELEASE")).isEqualTo("1.5.1") - assertThat(LatestRelease.normalizeVersion("1.5.1.FINAL")).isEqualTo("1.5.1") - assertThat(LatestRelease.normalizeVersion("1.5.1.Final")).isEqualTo("1.5.1") - } - - @Test - fun normalizeVersionToHaveMajorMinorPatch() { - assertThat(LatestRelease.normalizeVersion("29.0")).isEqualTo("29.0.0") - assertThat(LatestRelease.normalizeVersion("29.0-jre")).isEqualTo("29.0.0-jre") - assertThat(LatestRelease.normalizeVersion("29-jre")).isEqualTo("29.0.0-jre") - } - - @Test - fun datedSnapshotVersions() { - assertThat(latestRelease.compare(null, "7.17.0-20211102.000501-28", - "7.17.0-20211102.012229-29")).isLessThan(0) - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/semver/SemverTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/semver/SemverTest.kt deleted file mode 100644 index 82b2d04c4c5..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/semver/SemverTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2021 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.semver - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class SemverTest { - @Test - fun validToVersion() { - assertThat(Semver.validate("latest.release", null).getValue()) - .isInstanceOf(LatestRelease::class.java) - assertThat(Semver.validate("1.5 - 2", null).getValue()) - .isInstanceOf(HyphenRange::class.java) - assertThat(Semver.validate("1.x", null).getValue()) - .isInstanceOf(XRange::class.java) - assertThat(Semver.validate("~1.5", null).getValue()) - .isInstanceOf(TildeRange::class.java) - assertThat(Semver.validate("^1.5", null).getValue()) - .isInstanceOf(CaretRange::class.java) - assertThat(Semver.validate("[1.5,2)", null).getValue()) - .isInstanceOf(SetRange::class.java) - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/semver/TildeRangeTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/semver/TildeRangeTest.kt deleted file mode 100644 index 5ba6c564b8e..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/semver/TildeRangeTest.kt +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2021 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.semver - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class TildeRangeTest { - - @Test - fun isValidWhenCurrentIsNull() { - val tildeRange: TildeRange = TildeRange.build("~1", null).getValue()!! - assertThat(tildeRange.isValid(null, "1.0.0")).isTrue - } - - @Test - fun pattern() { - assertThat(TildeRange.build("~1", null).isValid).isTrue - assertThat(TildeRange.build("~1.2", null).isValid).isTrue - assertThat(TildeRange.build("~1.2.3", null).isValid).isTrue - assertThat(TildeRange.build("~1.2.3.4", null).isValid).isTrue - assertThat(TildeRange.build("~1.2.3.4.5", null).isValid).isFalse - } - - /** - * ~1.2.3 := >=1.2.3 <1.(2+1).0 := >=1.2.3 <1.3.0 - */ - @Test - fun updatePatch() { - val tildeRange: TildeRange = TildeRange.build("~1.2.3", null).getValue()!! - - assertThat(tildeRange.isValid("1.0", "1.2.3.0")).isTrue - assertThat(tildeRange.isValid("1.0", "1.2.3.1")).isTrue - assertThat(tildeRange.isValid("1.0", "1.2.3")).isTrue - assertThat(tildeRange.isValid("1.0", "1.2.3.RELEASE")).isTrue - assertThat(tildeRange.isValid("1.0", "1.2.4")).isTrue - assertThat(tildeRange.isValid("1.0", "1.3.0")).isFalse - } - - @Test - fun updateMicro() { - val tildeRange: TildeRange = TildeRange.build("~1.2.3.4", null).getValue()!! - - assertThat(tildeRange.isValid("1.0", "1.2.3.5")).isTrue - assertThat(tildeRange.isValid("1.0", "1.2.3.0")).isFalse - assertThat(tildeRange.isValid("1.0", "1.2.3.5.0")).isTrue - assertThat(tildeRange.isValid("1.0", "1.2.3")).isFalse - assertThat(tildeRange.isValid("1.0", "1.2.4")).isFalse - assertThat(tildeRange.isValid("1.0", "1.2.4.0")).isFalse - assertThat(tildeRange.isValid("1.0", "1.3.0")).isFalse - } - - /** - * ~1.2 := >=1.2.0 <1.(2+1).0 := >=1.2.0 <1.3.0-0 (Same as 1.2.x) - */ - @Test - fun updatePatchImplicitZeroPatch() { - val tildeRange: TildeRange = TildeRange.build("~1.2", null).getValue()!! - - assertThat(tildeRange.isValid("1.0", "1.2.0")).isTrue - assertThat(tildeRange.isValid("1.0", "1.2.4")).isTrue - assertThat(tildeRange.isValid("1.0", "1.3.0")).isFalse - } - - /** - * ~1 := >=1.0.0 <(1+1).0.0 := >=1.0.0 <2.0.0-0 (Same as 1.x) - */ - @Test - fun updateMajor() { - val tildeRange: TildeRange = TildeRange.build("~1", null).getValue()!! - - assertThat(tildeRange.isValid("1.0", "1.0.1")).isTrue - assertThat(tildeRange.isValid("1.0", "1.9.9")).isTrue - assertThat(tildeRange.isValid("1.0", "2.0.0")).isFalse - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/semver/XRangeTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/semver/XRangeTest.kt deleted file mode 100644 index c325fef5321..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/semver/XRangeTest.kt +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2021 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.semver - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test - -class XRangeTest { - - @Test - fun isValidWhenCurrentIsNull() { - val xRange: XRange = XRange.build("*", null).getValue()!! - assertThat(xRange.isValid(null, "1.0.0")).isTrue - } - - @Test - fun pattern() { - assertThat(XRange.build("*", null).isValid).isTrue - assertThat(XRange.build("*.0.0", null).isValid).isFalse - assertThat(XRange.build("1.x", null).isValid).isTrue - assertThat(XRange.build("1.x.0", null).isValid).isFalse - assertThat(XRange.build("1.1.X", null).isValid).isTrue - assertThat(XRange.build("1.1.1.X", null).isValid).isTrue - assertThat(XRange.build("1.1.1.1.X", null).isValid).isFalse - assertThat(XRange.build("1.1.x.1", null).isValid).isFalse - assertThat(XRange.build("a", null).isValid).isFalse - } - - @Test - fun doesNotMatchFixedVersion() { - assertThat(XRange.build("5.3.0", null).isValid).isFalse - } - - /** - * X := >=0.0.0 - */ - @Test - fun anyVersion() { - val xRange: XRange = XRange.build("X", null).getValue()!! - - assertThat(xRange.isValid("1.0", "0.0.0.0")).isTrue - assertThat(xRange.isValid("1.0", "0.0.0")).isTrue - } - - /** - * 1.* := >=1.0.0 <2.0.0-0 - */ - @Test - fun matchingMajorVersion() { - val xRange: XRange = XRange.build("1.*", null).getValue()!! - - assertThat(xRange.isValid("1.0", "1.0.0")).isTrue - assertThat(xRange.isValid("1.0", "1.0.0.1")).isTrue - assertThat(xRange.isValid("1.0", "1.2.3.RELEASE")).isTrue - assertThat(xRange.isValid("1.0", "1.9.9")).isTrue - assertThat(xRange.isValid("1.0", "2.0.0")).isFalse - } - - /** - * 1.2.X := >=1.2.0 <1.3.1 - */ - @Test - fun matchingMajorAndMinorVersions() { - val xRange: XRange = XRange.build("1.2.X", null).getValue()!! - - assertThat(xRange.isValid("1.0", "1.2.0")).isTrue - assertThat(xRange.isValid("1.0", "1.3.0")).isFalse - } - - @Test - fun matchingMicroVersions() { - val xRange: XRange = XRange.build("1.2.3.X", null).getValue()!! - - assertThat(xRange.isValid("1.0", "1.2.3.0")).isTrue - assertThat(xRange.isValid("1.0", "1.2.3")).isTrue - assertThat(xRange.isValid("1.0", "1.2.4.0")).isFalse - assertThat(xRange.isValid("1.0", "1.2.4")).isFalse - } - - @Test - fun matchingJavaxValidation() { - val xRange: XRange = XRange.build("2.X", null).getValue()!! - - // The version pattern of javax.validation:validation-api - assertThat(xRange.isValid("1.0", "2.0.1.Final")).isTrue - } -} diff --git a/rewrite-core/src/test/kotlin/org/openrewrite/text/AppendToTextFileTest.kt b/rewrite-core/src/test/kotlin/org/openrewrite/text/AppendToTextFileTest.kt deleted file mode 100644 index 728f43d855a..00000000000 --- a/rewrite-core/src/test/kotlin/org/openrewrite/text/AppendToTextFileTest.kt +++ /dev/null @@ -1,209 +0,0 @@ -/* - * Copyright 2022 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * 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.text - -import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.Test -import org.openrewrite.internal.StringUtils.trimIndentPreserveCRLF -import org.openrewrite.test.RewriteTest -import org.openrewrite.test.SourceSpecs -import org.openrewrite.test.SourceSpecs.text - -class AppendToTextFileTest : RewriteTest { - @Test - fun `creates file if needed`() = rewriteRun( - { spec -> - spec - .recipe(AppendToTextFile("file.txt", "content", "preamble", true, "leave")) - .expectedCyclesThatMakeChanges(1) - .afterRecipe { run -> - run.results.let { - assertEquals(1, it.size) - val actualSourceFile = it[0].after!! - val actualPlaintext = actualSourceFile as PlainText - assertEquals("file.txt", actualSourceFile.sourcePath.toString()) - assertEquals( - trimIndentPreserveCRLF( - """ - preamble - content - - """ - ), actualPlaintext.text - ) - } - } - }, *arrayOf() - ) - - @Test - fun `creates file if needed with multiple instances`() = rewriteRun({ spec -> - spec - .recipe( - AppendToTextFile("file.txt", "content", "preamble", true, "leave") - .doNext(AppendToTextFile("file.txt", "content", "preamble", true, "leave")) - ) - .expectedCyclesThatMakeChanges(1) - .afterRecipe { run -> - run.results.let { - assertEquals(1, it.size) - val actualSourceFile = it[0].after!! - val actualPlaintext = actualSourceFile as PlainText - assertEquals("file.txt", actualSourceFile.sourcePath.toString()) - assertEquals( - trimIndentPreserveCRLF( - """ - preamble - content - content - - """ - ), actualPlaintext.text - ) - } - } - }, *arrayOf()) - - @Test - fun `replaces file if requested`() = rewriteRun( - { spec -> - spec.recipe(AppendToTextFile("file.txt", "content", "preamble", true, "replace")) - }, - text( - """ - existing - """, - """ - preamble - content - - """ - ) { spec -> spec.path("file.txt") }) - - @Test - fun `continues file if requested`() = rewriteRun( - { spec -> - spec.recipe(AppendToTextFile("file.txt", "content", "preamble", true, "continue")) - }, - text( - """ - existing - """, """ - existingcontent - - """ - ) { spec -> spec.path("file.txt") } - ) - - @Test - fun `leaves file if requested`() = rewriteRun( - { spec -> - spec.recipe(AppendToTextFile("file.txt", "content", "preamble", true, "leave")) - }, - text("existing") { spec -> spec.path("file.txt") } - ) - - @Test - fun `multiple instances can append`() = rewriteRun( - { spec -> - spec.recipe( - AppendToTextFile("file.txt", "content", "preamble", true, "replace") - .doNext(AppendToTextFile("file.txt", "content", "preamble", true, "replace")) - ) - }, - text( - "existing", - """ - preamble - content - content - - """ - ) { spec -> spec.path("file.txt") } - ) - - @Test - fun `no leading newline if no preamble`() = rewriteRun( - { spec -> - spec.recipe(AppendToTextFile("file.txt", "content", null, true, "replace")) - }, - text( - """ - existing - """, """ - content - - """ - ) { spec -> spec.path("file.txt") } - ) - - @Test - fun `multiple files`() = rewriteRun( - { spec -> - spec - .recipe( - AppendToTextFile("file1.txt", "content1", "preamble1", true, "replace") - .doNext(AppendToTextFile("file2.txt", "content2", "preamble2", true, "replace")) - ) - }, - text( - "existing1", - """ - preamble1 - content1 - - """ - ) { spec -> spec.path("file1.txt") }, - text( - "existing2", - """ - preamble2 - content2 - - """ - ) { spec -> spec.path("file2.txt") } - ) - - @Test - fun `multiple instances on multiple files`() = rewriteRun( - { spec -> - spec - .recipe( - AppendToTextFile("file1.txt", "content1", "preamble1", true, "replace") - .doNext(AppendToTextFile("file2.txt", "content2", "preamble2", true, "replace")) - .doNext(AppendToTextFile("file1.txt", "content1", "preamble1", true, "replace")) - .doNext(AppendToTextFile("file2.txt", "content2", "preamble2", true, "replace")) - ) - }, - text( - "existing1", - """ - preamble1 - content1 - content1 - - """ - ) { spec -> spec.path("file1.txt") }, - text( - "existing2", - """ - preamble2 - content2 - content2 - - """ - ) { spec -> spec.path("file2.txt") }) -} diff --git a/rewrite-java-tck/README.md b/rewrite-java-tck/README.md index 0e8164f5396..98c739f4c57 100644 --- a/rewrite-java-tck/README.md +++ b/rewrite-java-tck/README.md @@ -18,7 +18,9 @@ classDiagram `rewrite-java-8` ..> `rewrite-java-tck` : `compatibilityTest classpath` `rewrite-groovy` ..> `rewrite-java-test` : testImplementation `rewrite-java` ..> `rewrite-java-test` : testImplementation -note for `rewrite-java` "For Java Reflection type mapping" `rewrite-java-tck` ..> `rewrite-java-17`: testRuntimeOnly -note for `rewrite-java-tck` "Bound to the latest current language level" ``` + +* The `testRuntimeOnly` dependency that `rewrite-java-tck` has on `rewrite-java-17` allows us to run these tests in the IDE. +* The `rewrite-java` dependency on `rewrite-java-test` is for testing the Java Reflection type mapping. +* `rewrite-java-tck` should be bound to the latest language level supported at any given time. diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/MavenDependencyFailuresTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/MavenDependencyFailuresTest.java index 9afff057e91..aadc8e0090e 100644 --- a/rewrite-maven/src/test/java/org/openrewrite/maven/MavenDependencyFailuresTest.java +++ b/rewrite-maven/src/test/java/org/openrewrite/maven/MavenDependencyFailuresTest.java @@ -127,7 +127,7 @@ void unresolvableTransitiveDependency(@TempDir Path localRepository) throws IOEx // is overwritten on disk with dependencies that don't exist. Path localPom = localRepository.resolve("com/bad/bad-artifact/1/bad-artifact-1.pom"); assertThat(localPom.getParent().toFile().mkdirs()).isTrue(); - Files.write(localPom, + Files.writeString(localPom, //language=xml """ @@ -135,7 +135,7 @@ void unresolvableTransitiveDependency(@TempDir Path localRepository) throws IOEx bad-artifact 1 - """.getBytes() + """ ); MavenRepository mavenLocal = new MavenRepository("local", localRepository.toUri().toString(), true, false, true, null, null, null); @@ -185,7 +185,7 @@ void unresolvableTransitiveDependency(@TempDir Path localRepository) throws IOEx """, spec -> spec.beforeRecipe(maven -> { // make the local pom bad before running the recipe - Files.write(localPom, + Files.writeString(localPom, //language=xml """ @@ -205,7 +205,7 @@ void unresolvableTransitiveDependency(@TempDir Path localRepository) throws IOEx - """.getBytes() + """ ); }) ) diff --git a/rewrite-test/src/main/java/org/openrewrite/test/AdHocRecipe.java b/rewrite-test/src/main/java/org/openrewrite/test/AdHocRecipe.java index 7c1b22a8c2d..beda21508ac 100644 --- a/rewrite-test/src/main/java/org/openrewrite/test/AdHocRecipe.java +++ b/rewrite-test/src/main/java/org/openrewrite/test/AdHocRecipe.java @@ -15,26 +15,64 @@ */ package org.openrewrite.test; +import lombok.EqualsAndHashCode; +import lombok.Value; +import lombok.With; +import org.intellij.lang.annotations.Language; import org.openrewrite.ExecutionContext; import org.openrewrite.Recipe; +import org.openrewrite.SourceFile; import org.openrewrite.TreeVisitor; +import org.openrewrite.internal.StringUtils; +import org.openrewrite.internal.lang.Nullable; +import java.util.List; +import java.util.function.BiFunction; import java.util.function.Supplier; +@Value +@EqualsAndHashCode(callSuper = false) public class AdHocRecipe extends Recipe { - private final Supplier> treeVisitorSupplier; + @With + @Nullable + @Language("markdown") + String displayName; - public AdHocRecipe(Supplier> treeVisitorSupplier) { - this.treeVisitorSupplier = treeVisitorSupplier; + @With + @Nullable + String name; + + @With + @Nullable + Boolean causesAnotherCycle; + + @With + Supplier> getVisitor; + + @Nullable + @With + BiFunction, ExecutionContext, List> visit; + + public String getDisplayName() { + return StringUtils.isBlank(displayName) ? "Ad hoc recipe" : displayName; + } + + public String getName() { + return StringUtils.isBlank(name) ? super.getName() : name; } @Override - public String getDisplayName() { - return "Ad hoc recipe"; + public boolean causesAnotherCycle() { + return causesAnotherCycle == null ? super.causesAnotherCycle() : causesAnotherCycle; + } + + @Override + protected List visit(List before, ExecutionContext ctx) { + return visit == null ? before : visit.apply(before, ctx); } @Override public TreeVisitor getVisitor() { - return treeVisitorSupplier.get(); + return getVisitor.get(); } } diff --git a/rewrite-test/src/main/java/org/openrewrite/test/RewriteTest.java b/rewrite-test/src/main/java/org/openrewrite/test/RewriteTest.java index 39eb4300cb4..377b19b661f 100644 --- a/rewrite-test/src/main/java/org/openrewrite/test/RewriteTest.java +++ b/rewrite-test/src/main/java/org/openrewrite/test/RewriteTest.java @@ -32,6 +32,7 @@ import java.nio.file.Path; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -43,8 +44,12 @@ @SuppressWarnings("unused") public interface RewriteTest extends SourceSpecs { - static Recipe toRecipe(Supplier> visitor) { - return new AdHocRecipe(visitor); + static AdHocRecipe toRecipe(Supplier> visitor) { + return new AdHocRecipe(null, null, null, visitor, null); + } + + static AdHocRecipe toRecipe() { + return new AdHocRecipe(null, null, null, () -> Recipe.NOOP, null); } static Recipe fromRuntimeClasspath(String recipe) { diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/security/AddOwaspDateBoundSuppressions.java b/rewrite-xml/src/main/java/org/openrewrite/xml/security/AddOwaspDateBoundSuppressions.java index da41e91e00a..6665d31ca20 100644 --- a/rewrite-xml/src/main/java/org/openrewrite/xml/security/AddOwaspDateBoundSuppressions.java +++ b/rewrite-xml/src/main/java/org/openrewrite/xml/security/AddOwaspDateBoundSuppressions.java @@ -59,7 +59,7 @@ protected TreeVisitor getVisitor() { @Override protected TreeVisitor getSingleSourceApplicableTest() { - return new IsOwaspSuppressionsFile(); + return new IsOwaspSuppressionsFile().getVisitor(); } @Override diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/security/IsOwaspSuppressionsFile.java b/rewrite-xml/src/main/java/org/openrewrite/xml/security/IsOwaspSuppressionsFile.java index 492f9b0ca92..ba3fdd9f901 100644 --- a/rewrite-xml/src/main/java/org/openrewrite/xml/security/IsOwaspSuppressionsFile.java +++ b/rewrite-xml/src/main/java/org/openrewrite/xml/security/IsOwaspSuppressionsFile.java @@ -16,40 +16,56 @@ package org.openrewrite.xml.security; import org.openrewrite.ExecutionContext; +import org.openrewrite.Recipe; import org.openrewrite.Tree; +import org.openrewrite.TreeVisitor; import org.openrewrite.marker.SearchResult; import org.openrewrite.xml.XmlIsoVisitor; import org.openrewrite.xml.tree.Xml; import java.nio.file.Paths; -public class IsOwaspSuppressionsFile extends XmlIsoVisitor { +public class IsOwaspSuppressionsFile extends Recipe { - private static final String MATCHER = "https://jeremylong.github.io/DependencyCheck/dependency-suppression(.*?).xsd"; + @Override + public String getDisplayName() { + return "Find OWASP `suppressions.xml`"; + } + + @Override + public String getDescription() { + return "These files are used to suppress false positives in OWASP [Dependency Check](https://jeremylong.github.io/DependencyCheck)."; + } @Override - public Xml.Document visitDocument(Xml.Document document, ExecutionContext executionContext) { - Xml.Document doc = super.visitDocument(document, executionContext); - if (!doc.getSourcePath().equals(Paths.get("suppressions.xml")) || doc.getRoot() == null) { - return doc; - } - Xml.Tag root = doc.getRoot(); - // root must be suppressions - if (!root.getName().equals("suppressions")) { - return doc; - } - // check that root xmlns matches - boolean isOwaspSuppressionFile = false; - for (Xml.Attribute attribute : root.getAttributes()) { - if (attribute.getKeyAsString().equals("xmlns")) { - if (attribute.getValueAsString().matches(MATCHER)) { - isOwaspSuppressionFile = true; + public TreeVisitor getVisitor() { + return new XmlIsoVisitor() { + @Override + public Xml.Document visitDocument(Xml.Document document, ExecutionContext executionContext) { + Xml.Document doc = super.visitDocument(document, executionContext); + if (!doc.getSourcePath().equals(Paths.get("suppressions.xml")) || doc.getRoot() == null) { + return doc; + } + Xml.Tag root = doc.getRoot(); + + if (!root.getName().equals("suppressions")) { + return doc; + } + + // check that root xmlns matches + boolean isOwaspSuppressionFile = false; + for (Xml.Attribute attribute : root.getAttributes()) { + if (attribute.getKeyAsString().equals("xmlns")) { + if (attribute.getValueAsString().matches("https://jeremylong.github.io/DependencyCheck/dependency-suppression(.*?).xsd")) { + isOwaspSuppressionFile = true; + } + } + } + if (isOwaspSuppressionFile) { + return doc.withRoot(doc.getRoot().withMarkers(doc.getRoot().getMarkers().addIfAbsent(new SearchResult(Tree.randomId(), "Found it")))); } + return doc; } - } - if (isOwaspSuppressionFile) { - return doc.withRoot(doc.getRoot().withMarkers(doc.getRoot().getMarkers().addIfAbsent(new SearchResult(Tree.randomId(), "Found it")))); - } - return doc; + }; } } diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/security/RemoveOwaspSuppressions.java b/rewrite-xml/src/main/java/org/openrewrite/xml/security/RemoveOwaspSuppressions.java index 9fde7727b15..643211bf556 100644 --- a/rewrite-xml/src/main/java/org/openrewrite/xml/security/RemoveOwaspSuppressions.java +++ b/rewrite-xml/src/main/java/org/openrewrite/xml/security/RemoveOwaspSuppressions.java @@ -53,7 +53,7 @@ protected TreeVisitor getVisitor() { @Override protected TreeVisitor getSingleSourceApplicableTest() { - return new IsOwaspSuppressionsFile(); + return new IsOwaspSuppressionsFile().getVisitor(); } private static class RemoveSuppressionsVisitor extends XmlIsoVisitor { diff --git a/rewrite-xml/src/main/java/org/openrewrite/xml/security/UpdateOwaspSuppressionDate.java b/rewrite-xml/src/main/java/org/openrewrite/xml/security/UpdateOwaspSuppressionDate.java index 2f8c4b8b6e0..acd765f9f62 100644 --- a/rewrite-xml/src/main/java/org/openrewrite/xml/security/UpdateOwaspSuppressionDate.java +++ b/rewrite-xml/src/main/java/org/openrewrite/xml/security/UpdateOwaspSuppressionDate.java @@ -64,7 +64,7 @@ protected TreeVisitor getVisitor() { @Override protected TreeVisitor getSingleSourceApplicableTest() { - return new IsOwaspSuppressionsFile(); + return new IsOwaspSuppressionsFile().getVisitor(); } @Override diff --git a/rewrite-xml/src/test/java/org/openrewrite/xml/security/IsOwaspSuppressionsFileTest.java b/rewrite-xml/src/test/java/org/openrewrite/xml/security/IsOwaspSuppressionsFileTest.java index 1121a96d830..a710b9135a1 100644 --- a/rewrite-xml/src/test/java/org/openrewrite/xml/security/IsOwaspSuppressionsFileTest.java +++ b/rewrite-xml/src/test/java/org/openrewrite/xml/security/IsOwaspSuppressionsFileTest.java @@ -16,7 +16,6 @@ package org.openrewrite.xml.security; import org.junit.jupiter.api.Test; -import org.openrewrite.test.AdHocRecipe; import org.openrewrite.test.RecipeSpec; import org.openrewrite.test.RewriteTest; @@ -27,7 +26,7 @@ class IsOwaspSuppressionsFileTest implements RewriteTest { @Override public void defaults(RecipeSpec spec) { - spec.recipe(new AdHocRecipe(IsOwaspSuppressionsFile::new)); + spec.recipe(new IsOwaspSuppressionsFile()); } @Test