From 5d9c0a8db55ceae7dc489b82f55c981d4d3be59d Mon Sep 17 00:00:00 2001 From: Stephan Schroevers Date: Sat, 23 Dec 2023 16:45:48 +0100 Subject: [PATCH] Make `BugPattern{,Test}Extractor` tests more maintainable As we're moving to a Java-based website generator located in the same package as the `Extractor` implementations, there is no need to validate the exact format of generated files; only that the data can be deserialized again. While there, track the source file from which data is extracted. --- documentation-support/pom.xml | 8 + .../documentation/BugPatternExtractor.java | 34 +++- .../BugPatternTestExtractor.java | 68 +++++++- .../DocumentationGeneratorTaskListener.java | 19 +- .../picnic/errorprone/documentation/Json.java | 45 +++++ .../BugPatternExtractorTest.java | 84 ++++++--- .../BugPatternTestExtractorTest.java | 162 ++++++++++++++---- ...torTest-bugpattern-CompleteBugChecker.json | 19 -- ...ctorTest-bugpattern-MinimalBugChecker.json | 14 -- ...ern-UndocumentedSuppressionBugPattern.json | 12 -- ...dBugCheckerRefactoringTestHelpersTest.json | 24 --- ...sWithCustomCheckerPackageAndNamesTest.json | 24 --- ...leBugCheckerRefactoringTestHelperTest.json | 20 --- ...st-MultiFileCompilationTestHelperTest.json | 18 -- ...leBugCheckerRefactoringTestHelperTest.json | 15 -- ...etArgsFixChooserAndCustomTestModeTest.json | 15 -- ...t-SingleFileCompilationTestHelperTest.json | 14 -- ...eCompilationTestHelperWithSetArgsTest.json | 14 -- 18 files changed, 335 insertions(+), 274 deletions(-) create mode 100644 documentation-support/src/main/java/tech/picnic/errorprone/documentation/Json.java delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-CompleteBugChecker.json delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-MinimalBugChecker.json delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-UndocumentedSuppressionBugPattern.json delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-CompilationAndBugCheckerRefactoringTestHelpersTest.json delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.json delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-MultiFileBugCheckerRefactoringTestHelperTest.json delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-MultiFileCompilationTestHelperTest.json delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileBugCheckerRefactoringTestHelperTest.json delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest.json delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileCompilationTestHelperTest.json delete mode 100644 documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileCompilationTestHelperWithSetArgsTest.json diff --git a/documentation-support/pom.xml b/documentation-support/pom.xml index e91c22a95d..6ae2e3ab62 100644 --- a/documentation-support/pom.xml +++ b/documentation-support/pom.xml @@ -40,6 +40,14 @@ com.fasterxml.jackson.core jackson-databind + + com.fasterxml.jackson.datatype + jackson-datatype-guava + + + com.fasterxml.jackson.module + jackson-module-parameter-names + com.google.auto auto-common diff --git a/documentation-support/src/main/java/tech/picnic/errorprone/documentation/BugPatternExtractor.java b/documentation-support/src/main/java/tech/picnic/errorprone/documentation/BugPatternExtractor.java index 4f21588744..15e9dad5e0 100644 --- a/documentation-support/src/main/java/tech/picnic/errorprone/documentation/BugPatternExtractor.java +++ b/documentation-support/src/main/java/tech/picnic/errorprone/documentation/BugPatternExtractor.java @@ -4,6 +4,7 @@ import static com.google.common.collect.ImmutableList.toImmutableList; import static java.util.Objects.requireNonNull; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.google.auto.common.AnnotationMirrors; import com.google.auto.service.AutoService; import com.google.auto.value.AutoValue; @@ -17,6 +18,7 @@ import com.sun.source.tree.ClassTree; import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Symbol.ClassSymbol; +import java.net.URI; import java.util.Optional; import javax.lang.model.element.AnnotationValue; import tech.picnic.errorprone.documentation.BugPatternExtractor.BugPatternDocumentation; @@ -45,7 +47,8 @@ public Optional tryExtract(ClassTree tree, VisitorState } return Optional.of( - new AutoValue_BugPatternExtractor_BugPatternDocumentation( + BugPatternDocumentation.create( + state.getPath().getCompilationUnit().getSourceFile().toUri(), symbol.getQualifiedName().toString(), annotation.name().isEmpty() ? tree.getSimpleName().toString() : annotation.name(), ImmutableList.copyOf(annotation.altNames()), @@ -91,7 +94,36 @@ private static T doCast(AnnotationValue value, Class } @AutoValue + @JsonDeserialize(as = AutoValue_BugPatternExtractor_BugPatternDocumentation.class) abstract static class BugPatternDocumentation { + static BugPatternDocumentation create( + URI source, + String fullyQualifiedName, + String name, + ImmutableList altNames, + String link, + ImmutableList tags, + String summary, + String explanation, + SeverityLevel severityLevel, + boolean canDisable, + ImmutableList suppressionAnnotations) { + return new AutoValue_BugPatternExtractor_BugPatternDocumentation( + source, + fullyQualifiedName, + name, + altNames, + link, + tags, + summary, + explanation, + severityLevel, + canDisable, + suppressionAnnotations); + } + + abstract URI source(); + abstract String fullyQualifiedName(); abstract String name(); diff --git a/documentation-support/src/main/java/tech/picnic/errorprone/documentation/BugPatternTestExtractor.java b/documentation-support/src/main/java/tech/picnic/errorprone/documentation/BugPatternTestExtractor.java index e24a23c865..a8cc2e41d0 100644 --- a/documentation-support/src/main/java/tech/picnic/errorprone/documentation/BugPatternTestExtractor.java +++ b/documentation-support/src/main/java/tech/picnic/errorprone/documentation/BugPatternTestExtractor.java @@ -4,6 +4,13 @@ import static com.google.errorprone.matchers.method.MethodMatchers.staticMethod; import static java.util.function.Predicate.not; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; +import com.fasterxml.jackson.annotation.JsonTypeInfo.As; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.google.auto.service.AutoService; import com.google.auto.value.AutoValue; import com.google.common.collect.ImmutableList; @@ -15,6 +22,7 @@ import com.sun.source.tree.ExpressionTree; import com.sun.source.tree.MethodInvocationTree; import com.sun.source.util.TreeScanner; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -52,7 +60,9 @@ public Optional tryExtract(ClassTree tree, VisitorState state) { .map( tests -> new AutoValue_BugPatternTestExtractor_TestCases( - ASTHelpers.getSymbol(tree).className(), tests)); + state.getPath().getCompilationUnit().getSourceFile().toUri(), + ASTHelpers.getSymbol(tree).className(), + tests)); } private static final class BugPatternTestCollector @@ -198,32 +208,78 @@ private static Optional getSourceCode(MethodInvocationTree tree) { } @AutoValue + @JsonDeserialize(as = AutoValue_BugPatternTestExtractor_TestCases.class) abstract static class TestCases { + static TestCases create(URI source, String testClass, ImmutableList testCases) { + return new AutoValue_BugPatternTestExtractor_TestCases(source, testClass, testCases); + } + + abstract URI source(); + abstract String testClass(); abstract ImmutableList testCases(); } @AutoValue + @JsonDeserialize(as = AutoValue_BugPatternTestExtractor_TestCase.class) abstract static class TestCase { + static TestCase create(String classUnderTest, ImmutableList entries) { + return new AutoValue_BugPatternTestExtractor_TestCase(classUnderTest, entries); + } + abstract String classUnderTest(); abstract ImmutableList entries(); } + @JsonSubTypes({ + @JsonSubTypes.Type(AutoValue_BugPatternTestExtractor_IdentificationTestEntry.class), + @JsonSubTypes.Type(AutoValue_BugPatternTestExtractor_ReplacementTestEntry.class) + }) + @JsonTypeInfo(include = As.EXISTING_PROPERTY, property = "type", use = JsonTypeInfo.Id.DEDUCTION) + @JsonIgnoreProperties(ignoreUnknown = true) + @JsonPropertyOrder("type") interface TestEntry { + TestType type(); + String path(); + + enum TestType { + IDENTIFICATION, + REPLACEMENT + } } @AutoValue - abstract static class ReplacementTestEntry implements TestEntry { - abstract String input(); + abstract static class IdentificationTestEntry implements TestEntry { + static IdentificationTestEntry create(String path, String code) { + return new AutoValue_BugPatternTestExtractor_IdentificationTestEntry(path, code); + } - abstract String output(); + @JsonProperty + @Override + public final TestType type() { + return TestType.IDENTIFICATION; + } + + abstract String code(); } @AutoValue - abstract static class IdentificationTestEntry implements TestEntry { - abstract String code(); + abstract static class ReplacementTestEntry implements TestEntry { + static ReplacementTestEntry create(String path, String input, String output) { + return new AutoValue_BugPatternTestExtractor_ReplacementTestEntry(path, input, output); + } + + @JsonProperty + @Override + public final TestType type() { + return TestType.REPLACEMENT; + } + + abstract String input(); + + abstract String output(); } } diff --git a/documentation-support/src/main/java/tech/picnic/errorprone/documentation/DocumentationGeneratorTaskListener.java b/documentation-support/src/main/java/tech/picnic/errorprone/documentation/DocumentationGeneratorTaskListener.java index 07261650ee..2cad3acea4 100644 --- a/documentation-support/src/main/java/tech/picnic/errorprone/documentation/DocumentationGeneratorTaskListener.java +++ b/documentation-support/src/main/java/tech/picnic/errorprone/documentation/DocumentationGeneratorTaskListener.java @@ -1,10 +1,5 @@ package tech.picnic.errorprone.documentation; -import static java.nio.charset.StandardCharsets.UTF_8; - -import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; -import com.fasterxml.jackson.annotation.PropertyAccessor; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableList; import com.google.errorprone.VisitorState; import com.sun.source.tree.ClassTree; @@ -15,10 +10,7 @@ import com.sun.source.util.TreePath; import com.sun.tools.javac.api.JavacTrees; import com.sun.tools.javac.util.Context; -import java.io.File; -import java.io.FileWriter; import java.io.IOException; -import java.io.UncheckedIOException; import java.net.URI; import java.nio.file.Files; import java.nio.file.Path; @@ -39,9 +31,6 @@ final class DocumentationGeneratorTaskListener implements TaskListener { ServiceLoader.load( Extractor.class, DocumentationGeneratorTaskListener.class.getClassLoader())); - private static final ObjectMapper OBJECT_MAPPER = - new ObjectMapper().setVisibility(PropertyAccessor.FIELD, Visibility.ANY); - private final Context context; private final Path docsPath; @@ -94,13 +83,7 @@ private void createDocsDirectory() { } private void writeToFile(String identifier, String className, T data) { - File file = docsPath.resolve(String.format("%s-%s.json", identifier, className)).toFile(); - - try (FileWriter fileWriter = new FileWriter(file, UTF_8)) { - OBJECT_MAPPER.writeValue(fileWriter, data); - } catch (IOException e) { - throw new UncheckedIOException(String.format("Cannot write to file '%s'", file.getPath()), e); - } + Json.write(docsPath.resolve(String.format("%s-%s.json", identifier, className)), data); } private static String getSimpleClassName(URI path) { diff --git a/documentation-support/src/main/java/tech/picnic/errorprone/documentation/Json.java b/documentation-support/src/main/java/tech/picnic/errorprone/documentation/Json.java new file mode 100644 index 0000000000..f6624aff39 --- /dev/null +++ b/documentation-support/src/main/java/tech/picnic/errorprone/documentation/Json.java @@ -0,0 +1,45 @@ +package tech.picnic.errorprone.documentation; + +import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.guava.GuavaModule; +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; +import com.google.errorprone.annotations.FormatMethod; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Path; + +/** + * Utility class that offers mutually consistent JSON serialization and deserialization operations, + * without further specifying the exact schema used. + */ +final class Json { + private static final ObjectMapper OBJECT_MAPPER = + new ObjectMapper() + .setVisibility(PropertyAccessor.FIELD, Visibility.ANY) + .registerModules(new GuavaModule(), new ParameterNamesModule()); + + private Json() {} + + static T read(Path path, Class clazz) { + try { + return OBJECT_MAPPER.readValue(path.toFile(), clazz); + } catch (IOException e) { + throw failure(e, "Failure reading from '%s'", path); + } + } + + static void write(Path path, T object) { + try { + OBJECT_MAPPER.writeValue(path.toFile(), object); + } catch (IOException e) { + throw failure(e, "Failure writing to '%s'", path); + } + } + + @FormatMethod + private static UncheckedIOException failure(IOException cause, String format, Object... args) { + return new UncheckedIOException(String.format(format, args), cause); + } +} diff --git a/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternExtractorTest.java b/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternExtractorTest.java index 137b2aa88e..5ee3818e03 100644 --- a/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternExtractorTest.java +++ b/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternExtractorTest.java @@ -1,13 +1,17 @@ package tech.picnic.errorprone.documentation; -import static java.nio.charset.StandardCharsets.UTF_8; +import static com.google.errorprone.BugPattern.SeverityLevel.ERROR; +import static com.google.errorprone.BugPattern.SeverityLevel.SUGGESTION; +import static com.google.errorprone.BugPattern.SeverityLevel.WARNING; import static org.assertj.core.api.Assertions.assertThat; -import com.google.common.io.Resources; -import java.io.IOException; +import com.google.common.collect.ImmutableList; +import com.google.errorprone.BugPattern; +import java.net.URI; import java.nio.file.Path; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import tech.picnic.errorprone.documentation.BugPatternExtractor.BugPatternDocumentation; final class BugPatternExtractorTest { @Test @@ -23,7 +27,7 @@ void noBugPattern(@TempDir Path outputDirectory) { } @Test - void minimalBugPattern(@TempDir Path outputDirectory) throws IOException { + void minimalBugPattern(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "MinimalBugChecker.java", @@ -36,11 +40,25 @@ void minimalBugPattern(@TempDir Path outputDirectory) throws IOException { "@BugPattern(summary = \"MinimalBugChecker summary\", severity = SeverityLevel.ERROR)", "public final class MinimalBugChecker extends BugChecker {}"); - verifyGeneratedFileContent(outputDirectory, "MinimalBugChecker"); + verifyGeneratedFileContent( + outputDirectory, + "MinimalBugChecker", + BugPatternDocumentation.create( + URI.create("file:///MinimalBugChecker.java"), + "pkg.MinimalBugChecker", + "MinimalBugChecker", + ImmutableList.of(), + "", + ImmutableList.of(), + "MinimalBugChecker summary", + "", + ERROR, + /* canDisable= */ true, + ImmutableList.of(SuppressWarnings.class.getCanonicalName()))); } @Test - void completeBugPattern(@TempDir Path outputDirectory) throws IOException { + void completeBugPattern(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "CompleteBugChecker.java", @@ -64,11 +82,25 @@ void completeBugPattern(@TempDir Path outputDirectory) throws IOException { " suppressionAnnotations = {BugPattern.class, Test.class})", "public final class CompleteBugChecker extends BugChecker {}"); - verifyGeneratedFileContent(outputDirectory, "CompleteBugChecker"); + verifyGeneratedFileContent( + outputDirectory, + "CompleteBugChecker", + BugPatternDocumentation.create( + URI.create("file:///CompleteBugChecker.java"), + "pkg.CompleteBugChecker", + "OtherName", + ImmutableList.of("Check"), + "https://error-prone.picnic.tech", + ImmutableList.of("Simplification"), + "CompleteBugChecker summary", + "Example explanation", + SUGGESTION, + /* canDisable= */ false, + ImmutableList.of(BugPattern.class.getCanonicalName(), "org.junit.jupiter.api.Test"))); } @Test - void undocumentedSuppressionBugPattern(@TempDir Path outputDirectory) throws IOException { + void undocumentedSuppressionBugPattern(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "UndocumentedSuppressionBugPattern.java", @@ -84,23 +116,27 @@ void undocumentedSuppressionBugPattern(@TempDir Path outputDirectory) throws IOE " documentSuppression = false)", "public final class UndocumentedSuppressionBugPattern extends BugChecker {}"); - verifyGeneratedFileContent(outputDirectory, "UndocumentedSuppressionBugPattern"); - } - - private static void verifyGeneratedFileContent(Path outputDirectory, String testClass) - throws IOException { - String resourceName = String.format("bugpattern-%s.json", testClass); - assertThat(outputDirectory.resolve(resourceName)) - .content(UTF_8) - .isEqualToIgnoringWhitespace( - getResource( - String.join("-", BugPatternExtractorTest.class.getSimpleName(), resourceName))); + verifyGeneratedFileContent( + outputDirectory, + "UndocumentedSuppressionBugPattern", + BugPatternDocumentation.create( + URI.create("file:///UndocumentedSuppressionBugPattern.java"), + "pkg.UndocumentedSuppressionBugPattern", + "UndocumentedSuppressionBugPattern", + ImmutableList.of(), + "", + ImmutableList.of(), + "UndocumentedSuppressionBugPattern summary", + "", + WARNING, + /* canDisable= */ true, + ImmutableList.of())); } - // XXX: Once we support only JDK 15+, drop this method in favour of including the resources as - // text blocks in this class. - private static String getResource(String resourceName) throws IOException { - return Resources.toString( - Resources.getResource(BugPatternExtractorTest.class, resourceName), UTF_8); + private static void verifyGeneratedFileContent( + Path outputDirectory, String testClass, BugPatternDocumentation expected) { + assertThat(outputDirectory.resolve(String.format("bugpattern-%s.json", testClass))) + .exists() + .returns(expected, path -> Json.read(path, BugPatternDocumentation.class)); } } diff --git a/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest.java b/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest.java index ecd6d2032c..02d59b8146 100644 --- a/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest.java +++ b/documentation-support/src/test/java/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest.java @@ -1,13 +1,16 @@ package tech.picnic.errorprone.documentation; -import static java.nio.charset.StandardCharsets.UTF_8; import static org.assertj.core.api.Assertions.assertThat; -import com.google.common.io.Resources; -import java.io.IOException; +import com.google.common.collect.ImmutableList; +import java.net.URI; import java.nio.file.Path; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import tech.picnic.errorprone.documentation.BugPatternTestExtractor.IdentificationTestEntry; +import tech.picnic.errorprone.documentation.BugPatternTestExtractor.ReplacementTestEntry; +import tech.picnic.errorprone.documentation.BugPatternTestExtractor.TestCase; +import tech.picnic.errorprone.documentation.BugPatternTestExtractor.TestCases; final class BugPatternTestExtractorTest { @Test @@ -246,7 +249,7 @@ void noDiagnostics(@TempDir Path outputDirectory) { } @Test - void singleFileCompilationTestHelper(@TempDir Path outputDirectory) throws IOException { + void singleFileCompilationTestHelper(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "SingleFileCompilationTestHelperTest.java", @@ -263,12 +266,22 @@ void singleFileCompilationTestHelper(@TempDir Path outputDirectory) throws IOExc " }", "}"); - verifyGeneratedFileContent(outputDirectory, "SingleFileCompilationTestHelperTest"); + verifyGeneratedFileContent( + outputDirectory, + "SingleFileCompilationTestHelperTest", + TestCases.create( + URI.create("file:///SingleFileCompilationTestHelperTest.java"), + "SingleFileCompilationTestHelperTest", + ImmutableList.of( + TestCase.create( + "SingleFileCompilationTestHelperTest.TestChecker", + ImmutableList.of( + IdentificationTestEntry.create( + "A.java", "// BUG: Diagnostic contains:\nclass A {}\n")))))); } @Test - void singleFileCompilationTestHelperWithSetArgs(@TempDir Path outputDirectory) - throws IOException { + void singleFileCompilationTestHelperWithSetArgs(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "SingleFileCompilationTestHelperWithSetArgsTest.java", @@ -286,11 +299,22 @@ void singleFileCompilationTestHelperWithSetArgs(@TempDir Path outputDirectory) " }", "}"); - verifyGeneratedFileContent(outputDirectory, "SingleFileCompilationTestHelperWithSetArgsTest"); + verifyGeneratedFileContent( + outputDirectory, + "SingleFileCompilationTestHelperWithSetArgsTest", + TestCases.create( + URI.create("file:///SingleFileCompilationTestHelperWithSetArgsTest.java"), + "SingleFileCompilationTestHelperWithSetArgsTest", + ImmutableList.of( + TestCase.create( + "SingleFileCompilationTestHelperWithSetArgsTest.TestChecker", + ImmutableList.of( + IdentificationTestEntry.create( + "A.java", "// BUG: Diagnostic contains:\nclass A {}\n")))))); } @Test - void multiFileCompilationTestHelper(@TempDir Path outputDirectory) throws IOException { + void multiFileCompilationTestHelper(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "MultiFileCompilationTestHelperTest.java", @@ -308,11 +332,24 @@ void multiFileCompilationTestHelper(@TempDir Path outputDirectory) throws IOExce " }", "}"); - verifyGeneratedFileContent(outputDirectory, "MultiFileCompilationTestHelperTest"); + verifyGeneratedFileContent( + outputDirectory, + "MultiFileCompilationTestHelperTest", + TestCases.create( + URI.create("file:///MultiFileCompilationTestHelperTest.java"), + "MultiFileCompilationTestHelperTest", + ImmutableList.of( + TestCase.create( + "MultiFileCompilationTestHelperTest.TestChecker", + ImmutableList.of( + IdentificationTestEntry.create( + "A.java", "// BUG: Diagnostic contains:\nclass A {}\n"), + IdentificationTestEntry.create( + "B.java", "// BUG: Diagnostic contains:\nclass B {}\n")))))); } @Test - void singleFileBugCheckerRefactoringTestHelper(@TempDir Path outputDirectory) throws IOException { + void singleFileBugCheckerRefactoringTestHelper(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "SingleFileBugCheckerRefactoringTestHelperTest.java", @@ -330,12 +367,23 @@ void singleFileBugCheckerRefactoringTestHelper(@TempDir Path outputDirectory) th " }", "}"); - verifyGeneratedFileContent(outputDirectory, "SingleFileBugCheckerRefactoringTestHelperTest"); + verifyGeneratedFileContent( + outputDirectory, + "SingleFileBugCheckerRefactoringTestHelperTest", + TestCases.create( + URI.create("file:///SingleFileBugCheckerRefactoringTestHelperTest.java"), + "SingleFileBugCheckerRefactoringTestHelperTest", + ImmutableList.of( + TestCase.create( + "SingleFileBugCheckerRefactoringTestHelperTest.TestChecker", + ImmutableList.of( + ReplacementTestEntry.create( + "A.java", "class A {}\n", "class A { /* This is a change. */ }\n")))))); } @Test void singleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestMode( - @TempDir Path outputDirectory) throws IOException { + @TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest.java", @@ -359,11 +407,21 @@ void singleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTest verifyGeneratedFileContent( outputDirectory, - "SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest"); + "SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest", + TestCases.create( + URI.create( + "file:///SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest.java"), + "SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest", + ImmutableList.of( + TestCase.create( + "SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest.TestChecker", + ImmutableList.of( + ReplacementTestEntry.create( + "A.java", "class A {}\n", "class A { /* This is a change. */ }\n")))))); } @Test - void multiFileBugCheckerRefactoringTestHelper(@TempDir Path outputDirectory) throws IOException { + void multiFileBugCheckerRefactoringTestHelper(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "MultiFileBugCheckerRefactoringTestHelperTest.java", @@ -383,12 +441,24 @@ void multiFileBugCheckerRefactoringTestHelper(@TempDir Path outputDirectory) thr " }", "}"); - verifyGeneratedFileContent(outputDirectory, "MultiFileBugCheckerRefactoringTestHelperTest"); + verifyGeneratedFileContent( + outputDirectory, + "MultiFileBugCheckerRefactoringTestHelperTest", + TestCases.create( + URI.create("file:///MultiFileBugCheckerRefactoringTestHelperTest.java"), + "MultiFileBugCheckerRefactoringTestHelperTest", + ImmutableList.of( + TestCase.create( + "MultiFileBugCheckerRefactoringTestHelperTest.TestChecker", + ImmutableList.of( + ReplacementTestEntry.create( + "A.java", "class A {}\n", "class A { /* This is a change. */ }\n"), + ReplacementTestEntry.create( + "B.java", "class B {}\n", "class B { /* This is a change. */ }\n")))))); } @Test - void compilationAndBugCheckerRefactoringTestHelpers(@TempDir Path outputDirectory) - throws IOException { + void compilationAndBugCheckerRefactoringTestHelpers(@TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "CompilationAndBugCheckerRefactoringTestHelpersTest.java", @@ -412,12 +482,27 @@ void compilationAndBugCheckerRefactoringTestHelpers(@TempDir Path outputDirector "}"); verifyGeneratedFileContent( - outputDirectory, "CompilationAndBugCheckerRefactoringTestHelpersTest"); + outputDirectory, + "CompilationAndBugCheckerRefactoringTestHelpersTest", + TestCases.create( + URI.create("file:///CompilationAndBugCheckerRefactoringTestHelpersTest.java"), + "CompilationAndBugCheckerRefactoringTestHelpersTest", + ImmutableList.of( + TestCase.create( + "CompilationAndBugCheckerRefactoringTestHelpersTest.TestChecker", + ImmutableList.of( + IdentificationTestEntry.create( + "A.java", "// BUG: Diagnostic contains:\nclass A {}\n"))), + TestCase.create( + "CompilationAndBugCheckerRefactoringTestHelpersTest.TestChecker", + ImmutableList.of( + ReplacementTestEntry.create( + "A.java", "class A {}\n", "class A { /* This is a change. */ }\n")))))); } @Test void compilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNames( - @TempDir Path outputDirectory) throws IOException { + @TempDir Path outputDirectory) { Compilation.compileWithDocumentationGenerator( outputDirectory, "CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.java", @@ -446,23 +531,28 @@ void compilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNa verifyGeneratedFileContent( outputDirectory, - "CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest"); - } - - private static void verifyGeneratedFileContent(Path outputDirectory, String testClass) - throws IOException { - String resourceName = String.format("bugpattern-test-%s.json", testClass); - assertThat(outputDirectory.resolve(resourceName)) - .content(UTF_8) - .isEqualToIgnoringWhitespace( - getResource( - String.join("-", BugPatternTestExtractorTest.class.getSimpleName(), resourceName))); + "CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest", + TestCases.create( + URI.create( + "file:///CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.java"), + "pkg.CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest", + ImmutableList.of( + TestCase.create( + "pkg.CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.CustomTestChecker", + ImmutableList.of( + IdentificationTestEntry.create( + "A.java", "// BUG: Diagnostic contains:\nclass A {}\n"))), + TestCase.create( + "pkg.CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.CustomTestChecker2", + ImmutableList.of( + ReplacementTestEntry.create( + "A.java", "class A {}\n", "class A { /* This is a change. */ }\n")))))); } - // XXX: Once we support only JDK 15+, drop this method in favour of including the resources as - // text blocks in this class. - private static String getResource(String resourceName) throws IOException { - return Resources.toString( - Resources.getResource(BugPatternTestExtractorTest.class, resourceName), UTF_8); + private static void verifyGeneratedFileContent( + Path outputDirectory, String testClass, TestCases expected) { + assertThat(outputDirectory.resolve(String.format("bugpattern-test-%s.json", testClass))) + .exists() + .returns(expected, path -> Json.read(path, TestCases.class)); } } diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-CompleteBugChecker.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-CompleteBugChecker.json deleted file mode 100644 index eb29080c05..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-CompleteBugChecker.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "fullyQualifiedName": "pkg.CompleteBugChecker", - "name": "OtherName", - "altNames": [ - "Check" - ], - "link": "https://error-prone.picnic.tech", - "tags": [ - "Simplification" - ], - "summary": "CompleteBugChecker summary", - "explanation": "Example explanation", - "severityLevel": "SUGGESTION", - "canDisable": false, - "suppressionAnnotations": [ - "com.google.errorprone.BugPattern", - "org.junit.jupiter.api.Test" - ] -} diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-MinimalBugChecker.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-MinimalBugChecker.json deleted file mode 100644 index 8e64bdc887..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-MinimalBugChecker.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "fullyQualifiedName": "pkg.MinimalBugChecker", - "name": "MinimalBugChecker", - "altNames": [], - "link": "", - "tags": [], - "summary": "MinimalBugChecker summary", - "explanation": "", - "severityLevel": "ERROR", - "canDisable": true, - "suppressionAnnotations": [ - "java.lang.SuppressWarnings" - ] -} diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-UndocumentedSuppressionBugPattern.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-UndocumentedSuppressionBugPattern.json deleted file mode 100644 index b738dfd988..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternExtractorTest-bugpattern-UndocumentedSuppressionBugPattern.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "fullyQualifiedName": "pkg.UndocumentedSuppressionBugPattern", - "name": "UndocumentedSuppressionBugPattern", - "altNames": [], - "link": "", - "tags": [], - "summary": "UndocumentedSuppressionBugPattern summary", - "explanation": "", - "severityLevel": "WARNING", - "canDisable": true, - "suppressionAnnotations": [] -} diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-CompilationAndBugCheckerRefactoringTestHelpersTest.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-CompilationAndBugCheckerRefactoringTestHelpersTest.json deleted file mode 100644 index c7672cccc4..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-CompilationAndBugCheckerRefactoringTestHelpersTest.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "testClass": "CompilationAndBugCheckerRefactoringTestHelpersTest", - "testCases": [ - { - "classUnderTest": "CompilationAndBugCheckerRefactoringTestHelpersTest.TestChecker", - "entries": [ - { - "path": "A.java", - "code": "// BUG: Diagnostic contains:\nclass A {}\n" - } - ] - }, - { - "classUnderTest": "CompilationAndBugCheckerRefactoringTestHelpersTest.TestChecker", - "entries": [ - { - "path": "A.java", - "input": "class A {}\n", - "output": "class A { /* This is a change. */ }\n" - } - ] - } - ] -} diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.json deleted file mode 100644 index 49b1e6bb49..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "testClass": "pkg.CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest", - "testCases": [ - { - "classUnderTest": "pkg.CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.CustomTestChecker", - "entries": [ - { - "path": "A.java", - "code": "// BUG: Diagnostic contains:\nclass A {}\n" - } - ] - }, - { - "classUnderTest": "pkg.CompilationAndBugCheckerRefactoringTestHelpersWithCustomCheckerPackageAndNamesTest.CustomTestChecker2", - "entries": [ - { - "path": "A.java", - "input": "class A {}\n", - "output": "class A { /* This is a change. */ }\n" - } - ] - } - ] -} diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-MultiFileBugCheckerRefactoringTestHelperTest.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-MultiFileBugCheckerRefactoringTestHelperTest.json deleted file mode 100644 index 4f93dc9ce2..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-MultiFileBugCheckerRefactoringTestHelperTest.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "testClass": "MultiFileBugCheckerRefactoringTestHelperTest", - "testCases": [ - { - "classUnderTest": "MultiFileBugCheckerRefactoringTestHelperTest.TestChecker", - "entries": [ - { - "path": "A.java", - "input": "class A {}\n", - "output": "class A { /* This is a change. */ }\n" - }, - { - "path": "B.java", - "input": "class B {}\n", - "output": "class B { /* This is a change. */ }\n" - } - ] - } - ] -} diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-MultiFileCompilationTestHelperTest.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-MultiFileCompilationTestHelperTest.json deleted file mode 100644 index 608717802f..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-MultiFileCompilationTestHelperTest.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "testClass": "MultiFileCompilationTestHelperTest", - "testCases": [ - { - "classUnderTest": "MultiFileCompilationTestHelperTest.TestChecker", - "entries": [ - { - "path": "A.java", - "code": "// BUG: Diagnostic contains:\nclass A {}\n" - }, - { - "path": "B.java", - "code": "// BUG: Diagnostic contains:\nclass B {}\n" - } - ] - } - ] -} diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileBugCheckerRefactoringTestHelperTest.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileBugCheckerRefactoringTestHelperTest.json deleted file mode 100644 index 636e19ebdf..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileBugCheckerRefactoringTestHelperTest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "testClass": "SingleFileBugCheckerRefactoringTestHelperTest", - "testCases": [ - { - "classUnderTest": "SingleFileBugCheckerRefactoringTestHelperTest.TestChecker", - "entries": [ - { - "path": "A.java", - "input": "class A {}\n", - "output": "class A { /* This is a change. */ }\n" - } - ] - } - ] -} diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest.json deleted file mode 100644 index 4c2d66d89a..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "testClass": "SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest", - "testCases": [ - { - "classUnderTest": "SingleFileBugCheckerRefactoringTestHelperWithSetArgsFixChooserAndCustomTestModeTest.TestChecker", - "entries": [ - { - "path": "A.java", - "input": "class A {}\n", - "output": "class A { /* This is a change. */ }\n" - } - ] - } - ] -} diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileCompilationTestHelperTest.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileCompilationTestHelperTest.json deleted file mode 100644 index 37720e1ed5..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileCompilationTestHelperTest.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "testClass": "SingleFileCompilationTestHelperTest", - "testCases": [ - { - "classUnderTest": "SingleFileCompilationTestHelperTest.TestChecker", - "entries": [ - { - "path": "A.java", - "code": "// BUG: Diagnostic contains:\nclass A {}\n" - } - ] - } - ] -} diff --git a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileCompilationTestHelperWithSetArgsTest.json b/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileCompilationTestHelperWithSetArgsTest.json deleted file mode 100644 index ea543ab7ed..0000000000 --- a/documentation-support/src/test/resources/tech/picnic/errorprone/documentation/BugPatternTestExtractorTest-bugpattern-test-SingleFileCompilationTestHelperWithSetArgsTest.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "testClass": "SingleFileCompilationTestHelperWithSetArgsTest", - "testCases": [ - { - "classUnderTest": "SingleFileCompilationTestHelperWithSetArgsTest.TestChecker", - "entries": [ - { - "path": "A.java", - "code": "// BUG: Diagnostic contains:\nclass A {}\n" - } - ] - } - ] -}