Skip to content

Commit b3c1664

Browse files
committed
changes
1 parent c8034d3 commit b3c1664

File tree

6 files changed

+141
-50
lines changed

6 files changed

+141
-50
lines changed

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,13 @@
6565
</dependency>
6666

6767
<!-- Test dependencies -->
68+
<dependency>
69+
<groupId>com.puppycrawl.tools</groupId>
70+
<artifactId>checkstyle</artifactId>
71+
<version>${checkstyle.version}</version>
72+
<classifier>tests</classifier>
73+
<scope>test</scope>
74+
</dependency>
6875
<dependency>
6976
<groupId>org.openrewrite</groupId>
7077
<artifactId>rewrite-test</artifactId>

src/main/java/org/checkstyle/autofix/parser/ConfigurationLoader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private ConfigurationLoader() {
3434
// utility class
3535
}
3636

37-
private static CheckConfiguration mapConfiguration(Configuration config) {
37+
public static CheckConfiguration mapConfiguration(Configuration config) {
3838
final Map<String, String> properties = new HashMap<>();
3939
final String[] propertyNames = config.getPropertyNames();
4040
for (String propertyName : propertyNames) {
Lines changed: 107 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,133 @@
1-
///////////////////////////////////////////////////////////////////////////////////////////////
2-
// checkstyle-openrewrite-recipes: Automatically fix Checkstyle violations with OpenRewrite.
3-
// Copyright (C) 2025 The Checkstyle OpenRewrite Recipes Authors
4-
//
5-
// Licensed under the Apache License, Version 2.0 (the "License");
6-
// you may not use this file except in compliance with the License.
7-
// You may obtain a copy of the License at
8-
//
9-
// http://www.apache.org/licenses/LICENSE-2.0
10-
//
11-
// Unless required by applicable law or agreed to in writing, software
12-
// distributed under the License is distributed on an "AS IS" BASIS,
13-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14-
// See the License for the specific language governing permissions and
15-
// limitations under the License.
16-
///////////////////////////////////////////////////////////////////////////////////////////////
17-
181
package org.checkstyle.autofix.recipe;
192

203
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
214
import static org.openrewrite.java.Assertions.java;
225

23-
import java.io.IOException;
6+
import java.io.ByteArrayOutputStream;
7+
import java.io.File;
248
import java.nio.file.Files;
25-
import java.nio.file.Paths;
9+
import java.nio.file.Path;
10+
import java.util.ArrayList;
11+
import java.util.Collections;
12+
import java.util.List;
2613

2714
import org.checkstyle.autofix.InputClassRenamer;
15+
import org.checkstyle.autofix.parser.CheckConfiguration;
16+
import org.checkstyle.autofix.parser.CheckstyleReportParser;
17+
import org.checkstyle.autofix.parser.CheckstyleViolation;
18+
import org.checkstyle.autofix.parser.ConfigurationLoader;
2819
import org.openrewrite.Recipe;
2920
import org.openrewrite.test.RewriteTest;
3021

31-
public abstract class AbstractRecipeTest implements RewriteTest {
22+
import com.puppycrawl.tools.checkstyle.AbstractXmlTestSupport;
23+
import com.puppycrawl.tools.checkstyle.Checker;
24+
import com.puppycrawl.tools.checkstyle.XMLLogger;
25+
import com.puppycrawl.tools.checkstyle.api.Configuration;
26+
import com.puppycrawl.tools.checkstyle.bdd.InlineConfigParser;
27+
import com.puppycrawl.tools.checkstyle.bdd.TestInputConfiguration;
3228

33-
private static final String BASE_TEST_RESOURCES_PATH = "src/test/resources/org"
34-
+ "/checkstyle/autofix/recipe/";
29+
/**
30+
* Simple base class for recipe tests that extends Checkstyle's AbstractXmlTestSupport.
31+
*/
32+
public abstract class AbstractRecipeTest extends AbstractXmlTestSupport implements RewriteTest {
3533

36-
private Recipe createPreprocessingRecipe() {
37-
return new InputClassRenamer();
38-
}
34+
/**
35+
* Returns the subpackage name for test resources.
36+
*/
37+
protected abstract String getSubpackage();
3938

40-
protected abstract Recipe getRecipe();
39+
/**
40+
* Creates the recipe with violations and configs.
41+
*/
42+
protected abstract Recipe createRecipe(List<CheckstyleViolation> violations,
43+
List<CheckConfiguration> checkConfigs);
4144

42-
protected void testRecipe(String recipePath, String testCaseName) throws IOException {
43-
final String testCaseDir = testCaseName.toLowerCase();
45+
@Override
46+
protected String getPackageLocation() {
47+
return "org/checkstyle/autofix/recipe/" + getSubpackage();
48+
}
49+
50+
/**
51+
* Main verification method.
52+
*/
53+
protected void verify(String testCaseName) throws Exception {
4454
final String inputFileName = "Input" + testCaseName + ".java";
4555
final String outputFileName = "Output" + testCaseName + ".java";
56+
final String inputPath = testCaseName.toLowerCase() + "/" + inputFileName;
57+
final String outputPath = testCaseName.toLowerCase() + "/" + outputFileName;
58+
59+
final List<CheckstyleViolation> violations = runCheckstyleAndGetViolations(inputPath);
60+
61+
final List<CheckConfiguration> checkConfigs = getAllCheckConfigurations(inputPath);
62+
63+
final String beforeCode = readFile(getPath(inputPath));
64+
final String expectedAfterCode = readFile(getPath(outputPath));
65+
66+
final Recipe preprocessingRecipe = new InputClassRenamer();
67+
final Recipe mainRecipe = createRecipe(violations, checkConfigs);
68+
69+
testRecipe(beforeCode, expectedAfterCode, preprocessingRecipe, mainRecipe);
70+
}
4671

47-
final String beforeCode = Files.readString(Paths.get(BASE_TEST_RESOURCES_PATH
48-
+ recipePath + "/" + testCaseDir + "/" + inputFileName));
72+
private List<CheckstyleViolation> runCheckstyleAndGetViolations(String inputPath)
73+
throws Exception {
4974

50-
final String afterCode = Files.readString(Paths.get(BASE_TEST_RESOURCES_PATH
51-
+ recipePath + "/" + testCaseDir + "/" + outputFileName));
75+
final String configFilePath = getPath(inputPath);
76+
final TestInputConfiguration testInputConfiguration =
77+
InlineConfigParser.parse(configFilePath);
78+
final Configuration parsedConfig = testInputConfiguration.createConfiguration();
5279

53-
final Recipe preprocessing = createPreprocessingRecipe();
54-
final Recipe mainRecipe = getRecipe();
80+
final Checker checker = createChecker(parsedConfig);
81+
final ByteArrayOutputStream xmlOutput = new ByteArrayOutputStream();
82+
final XMLLogger logger = new XMLLogger(xmlOutput, XMLLogger.OutputStreamOptions.CLOSE);
83+
checker.addListener(logger);
84+
85+
final List<File> filesToCheck = Collections.singletonList(new File(configFilePath));
86+
checker.process(filesToCheck);
87+
88+
final Path tempXmlPath = Files.createTempFile("checkstyle-report", ".xml");
89+
try {
90+
Files.write(tempXmlPath, xmlOutput.toByteArray());
91+
return CheckstyleReportParser.parse(tempXmlPath);
92+
} finally {
93+
Files.deleteIfExists(tempXmlPath);
94+
}
95+
}
96+
97+
private List<CheckConfiguration> getAllCheckConfigurations(String inputPath) throws Exception {
98+
final String configFilePath = getPath(inputPath);
99+
final TestInputConfiguration testInputConfiguration =
100+
InlineConfigParser.parse(configFilePath);
101+
final Configuration parsedConfig = testInputConfiguration.createConfiguration();
102+
103+
final List<CheckConfiguration> checkConfigs = new ArrayList<>();
104+
105+
for (Configuration child : parsedConfig.getChildren()) {
106+
if ("TreeWalker".equals(child.getName())) {
107+
for (Configuration check : child.getChildren()) {
108+
final CheckConfiguration checkConfig = ConfigurationLoader.mapConfiguration(check);
109+
checkConfigs.add(checkConfig);
110+
}
111+
}
112+
}
113+
114+
if (checkConfigs.isEmpty()) {
115+
throw new IllegalStateException("No check configurations found");
116+
}
117+
118+
return checkConfigs;
119+
}
55120

121+
/**
122+
* Helper method to test recipes using OpenRewrite testing framework.
123+
*/
124+
private void testRecipe(String beforeCode, String expectedAfterCode,
125+
Recipe... recipes) {
56126
assertDoesNotThrow(() -> {
57127
rewriteRun(
58-
spec -> spec.recipes(preprocessing, mainRecipe),
59-
java(beforeCode, afterCode)
128+
spec -> spec.recipes(recipes),
129+
java(beforeCode, expectedAfterCode)
60130
);
61131
});
62132
}
63-
}
133+
}

src/test/java/org/checkstyle/autofix/recipe/UpperEllTest.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.nio.file.Path;
2222
import java.util.List;
2323

24+
import org.checkstyle.autofix.parser.CheckConfiguration;
2425
import org.checkstyle.autofix.parser.CheckstyleReportParser;
2526
import org.checkstyle.autofix.parser.CheckstyleViolation;
2627
import org.junit.jupiter.api.Test;
@@ -29,27 +30,29 @@
2930
public class UpperEllTest extends AbstractRecipeTest {
3031

3132
@Override
32-
protected Recipe getRecipe() {
33-
final String reportPath = "src/test/resources/org/checkstyle/autofix/recipe/upperell"
34-
+ "/report.xml";
33+
protected String getSubpackage() {
34+
return "upperell";
35+
}
36+
37+
@Override
38+
protected Recipe createRecipe(List<CheckstyleViolation> violations,
39+
List<CheckConfiguration> checkConfigs) {
3540

36-
final List<CheckstyleViolation> violations =
37-
CheckstyleReportParser.parse(Path.of(reportPath));
3841
return new UpperEll(violations);
3942
}
4043

4144
@Test
42-
void hexOctalLiteralTest() throws IOException {
43-
testRecipe("upperell", "HexOctalLiteral");
45+
void hexOctalLiteral() throws Exception {
46+
verify("HexOctalLiteral");
4447
}
4548

4649
@Test
47-
void complexLongLiterals() throws IOException {
48-
testRecipe("upperell", "ComplexLongLiterals");
50+
void complexLongLiterals() throws Exception {
51+
verify("ComplexLongLiterals");
4952
}
5053

5154
@Test
52-
void stringAndCommentTest() throws IOException {
53-
testRecipe("upperell", "StringAndComments");
55+
void stringAndComments() throws Exception {
56+
verify("StringAndComments");
5457
}
5558
}

src/test/resources/org/checkstyle/autofix/recipe/upperell/hexoctalliteral/InputHexOctalLiteral.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/*
2+
UpperEll
3+
*/
4+
5+
16
package org.checkstyle.autofix.recipe.upperell.hexoctalliteral;
27

38
public class InputHexOctalLiteral {
@@ -12,4 +17,4 @@ public void calculateValues() {
1217
long octalResult = 01234l + 0xDEADBEEFl; //suppressed violation for 0xDEADBEFl
1318
long binaryResult = 0b11110000l;
1419
}
15-
}
20+
}

src/test/resources/org/checkstyle/autofix/recipe/upperell/hexoctalliteral/OutputHexOctalLiteral.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
/*
2+
UpperEll
3+
4+
5+
*/
6+
17
package org.checkstyle.autofix.recipe.upperell.hexoctalliteral;
28

39
public class OutputHexOctalLiteral {

0 commit comments

Comments
 (0)