diff --git a/config/suppressions.xml b/config/suppressions.xml index 5b5b9f3..51629b6 100644 --- a/config/suppressions.xml +++ b/config/suppressions.xml @@ -9,5 +9,6 @@ + diff --git a/pom.xml b/pom.xml index be97b7a..94d7ab6 100644 --- a/pom.xml +++ b/pom.xml @@ -65,6 +65,13 @@ + + com.puppycrawl.tools + checkstyle + ${checkstyle.version} + tests + test + org.openrewrite rewrite-test diff --git a/src/test/java/org/checkstyle/autofix/recipe/AbstractRecipeTestSupport.java b/src/test/java/org/checkstyle/autofix/recipe/AbstractRecipeTestSupport.java new file mode 100644 index 0000000..500e47a --- /dev/null +++ b/src/test/java/org/checkstyle/autofix/recipe/AbstractRecipeTestSupport.java @@ -0,0 +1,116 @@ +/////////////////////////////////////////////////////////////////////////////////////////////// +// checkstyle-openrewrite-recipes: Automatically fix Checkstyle violations with OpenRewrite. +// Copyright (C) 2025 The Checkstyle OpenRewrite Recipes 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 +// +// http://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.checkstyle.autofix.recipe; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.openrewrite.java.Assertions.java; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.List; + +import org.checkstyle.autofix.InputClassRenamer; +import org.checkstyle.autofix.parser.CheckstyleReportParser; +import org.checkstyle.autofix.parser.CheckstyleViolation; +import org.openrewrite.Recipe; +import org.openrewrite.test.RewriteTest; + +import com.puppycrawl.tools.checkstyle.AbstractXmlTestSupport; +import com.puppycrawl.tools.checkstyle.Checker; +import com.puppycrawl.tools.checkstyle.XMLLogger; +import com.puppycrawl.tools.checkstyle.api.Configuration; +import com.puppycrawl.tools.checkstyle.bdd.InlineConfigParser; +import com.puppycrawl.tools.checkstyle.bdd.TestInputConfiguration; + +public abstract class AbstractRecipeTestSupport extends AbstractXmlTestSupport + implements RewriteTest { + + protected abstract String getSubpackage(); + + protected abstract String getCheckName(); + + protected abstract Recipe createRecipe(List violations); + + @Override + protected String getPackageLocation() { + return "org/checkstyle/autofix/recipe/" + getSubpackage(); + } + + private Recipe createPreprocessingRecipe() { + return new InputClassRenamer(); + } + + protected void verify(String testCaseName) throws Exception { + final String inputFileName = "Input" + testCaseName + ".java"; + final String outputFileName = "Output" + testCaseName + ".java"; + final String inputPath = testCaseName.toLowerCase() + "/" + inputFileName; + final String outputPath = testCaseName.toLowerCase() + "/" + outputFileName; + + final Configuration config = getCheckConfigurations(inputPath); + final List violations = runCheckstyle(inputPath, config); + + final String beforeCode = readFile(getPath(inputPath)); + final String expectedAfterCode = readFile(getPath(outputPath)); + + final Recipe mainRecipe = createRecipe(violations); + + testRecipe(beforeCode, expectedAfterCode, + getPath(inputPath), createPreprocessingRecipe(), mainRecipe); + } + + private List runCheckstyle(String inputPath, + Configuration config) throws Exception { + + final Checker checker = createChecker(config); + final ByteArrayOutputStream xmlOutput = new ByteArrayOutputStream(); + final XMLLogger logger = new XMLLogger(xmlOutput, XMLLogger.OutputStreamOptions.CLOSE); + checker.addListener(logger); + + final List filesToCheck = Collections.singletonList(new File(getPath(inputPath))); + checker.process(filesToCheck); + + final Path tempXmlPath = Files.createTempFile("checkstyle-report", ".xml"); + try { + Files.write(tempXmlPath, xmlOutput.toByteArray()); + return CheckstyleReportParser.parse(tempXmlPath); + } + finally { + Files.deleteIfExists(tempXmlPath); + } + } + + private Configuration getCheckConfigurations(String inputPath) throws Exception { + final String configFilePath = getPath(inputPath); + final TestInputConfiguration testInputConfiguration = + InlineConfigParser.parse(configFilePath); + return testInputConfiguration.createConfiguration(); + } + + private void testRecipe(String beforeCode, String expectedAfterCode, + String filePath, Recipe... recipes) { + assertDoesNotThrow(() -> { + rewriteRun( + spec -> spec.recipes(recipes), + java(beforeCode, expectedAfterCode, spec -> spec.path(filePath)) + ); + }); + } +}