From 7b31cab4f90582bab8febcb8084c5ab7829aa94e Mon Sep 17 00:00:00 2001 From: martinfrancois Date: Tue, 11 Aug 2026 20:16:15 +0200 Subject: [PATCH] JSpecifyBestPractices: add failing tests for missing JSpecify dependency addJspecifyDependencyWithoutPriorNullnessAnnotations pins that best practices annotate a project using no nullness library without adding org.jspecify:jspecify. addDependencyForAnnotationsInsertedInSameRun pins that AddDependency's onlyIfUsing cannot match annotations inserted earlier in the same cycle, as disclosed in #1192. Both are marked with @ExpectedToFail. --- .../jspecify/JSpecifyBestPracticesTest.java | 135 ++++++++++++++++++ 1 file changed, 135 insertions(+) diff --git a/src/test/java/org/openrewrite/java/migrate/jspecify/JSpecifyBestPracticesTest.java b/src/test/java/org/openrewrite/java/migrate/jspecify/JSpecifyBestPracticesTest.java index 207f2bdd7d..bf7951ccc3 100644 --- a/src/test/java/org/openrewrite/java/migrate/jspecify/JSpecifyBestPracticesTest.java +++ b/src/test/java/org/openrewrite/java/migrate/jspecify/JSpecifyBestPracticesTest.java @@ -16,6 +16,7 @@ package org.openrewrite.java.migrate.jspecify; import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.ExpectedToFail; import org.openrewrite.DocumentExample; import org.openrewrite.Issue; import org.openrewrite.java.JavaParser; @@ -501,6 +502,140 @@ class Bar { ); } + @ExpectedToFail("No AddDependency guard in jspecify.yml matches a project without a prior nullness library, so the annotations just written do not resolve") + @Issue("https://github.com/openrewrite/rewrite-migrate-java/pull/1192") + @Test + void addJspecifyDependencyWithoutPriorNullnessAnnotations() { + rewriteRun( + mavenProject("foo", + srcMainJava( + //language=java + java( + """ + public class Test { + + public String getString() { + return null; + } + } + """, + """ + import org.jspecify.annotations.Nullable; + + public class Test { + + public @Nullable String getString() { + return null; + } + } + """ + ) + ), + //language=xml + pomXml( + """ + + 4.0.0 + com.example.foobar + foobar-core + 1.0.0 + + """, + """ + + 4.0.0 + com.example.foobar + foobar-core + 1.0.0 + + + org.jspecify + jspecify + 1.0.0 + + + + """ + ) + ) + ); + } + + @ExpectedToFail("AddDependency's onlyIfUsing scans the original sources and does not see annotations inserted earlier in the same cycle; the dependency is only added in a follow-up cycle") + @Issue("https://github.com/openrewrite/rewrite-migrate-java/pull/1192") + @Test + void addDependencyForAnnotationsInsertedInSameRun() { + rewriteRun( + spec -> spec.recipeFromYaml( + """ + type: specs.openrewrite.org/v1beta/recipe + name: org.openrewrite.java.jspecify.AnnotateNullableAndAddDependency + displayName: Annotate nullable methods and add the JSpecify dependency + description: Adds JSpecify annotations and the dependency providing them. + recipeList: + - org.openrewrite.staticanalysis.AnnotateNullableMethods + - org.openrewrite.java.dependencies.AddDependency: + groupId: org.jspecify + artifactId: jspecify + version: 1.0.0 + onlyIfUsing: org.jspecify.annotations.* + acceptTransitive: true + """, + "org.openrewrite.java.jspecify.AnnotateNullableAndAddDependency"), + mavenProject("foo", + srcMainJava( + //language=java + java( + """ + public class Test { + + public String getString() { + return null; + } + } + """, + """ + import org.jspecify.annotations.Nullable; + + public class Test { + + public @Nullable String getString() { + return null; + } + } + """ + ) + ), + //language=xml + pomXml( + """ + + 4.0.0 + com.example.foobar + foobar-core + 1.0.0 + + """, + """ + + 4.0.0 + com.example.foobar + foobar-core + 1.0.0 + + + org.jspecify + jspecify + 1.0.0 + + + + """ + ) + ) + ); + } + @Test void migrateFromMicronautAnnotationToJspecify() { rewriteRun(