2929import java .io .LineNumberReader ;
3030import java .nio .charset .StandardCharsets ;
3131import java .nio .file .Files ;
32- import java .nio .file .Path ;
33- import java .nio .file .Paths ;
32+ import java .util .ArrayList ;
3433import java .util .Arrays ;
3534import java .util .Collections ;
3635import java .util .List ;
36+ import java .util .regex .Matcher ;
37+ import java .util .regex .Pattern ;
3738
3839import com .puppycrawl .tools .checkstyle .AbstractModuleTestSupport ;
3940import com .puppycrawl .tools .checkstyle .ConfigurationLoader ;
@@ -48,6 +49,14 @@ abstract class AbstractPatchFilterEvaluationTest extends AbstractModuleTestSuppo
4849
4950 private static final String CONTEXT_CONFIG_PATTERN = "(default|zero)ContextConfig.xml" ;
5051
52+ /**
53+ * Pattern to match inline violation comments in test files.
54+ * Matches: // violation 'message'
55+ * or: // filtered violation below 'message'
56+ */
57+ private static final Pattern VIOLATION_PATTERN = Pattern .compile (
58+ "//\\ s*(?:filtered\\ s+)?violation(?:\\ s+below)?\\ s+'([^']+)'" );
59+
5160 protected abstract String getPatchFileLocation ();
5261
5362 protected void testByConfig (String configPath )
@@ -95,18 +104,76 @@ private void assertResults(String configPath, String path, int errorCounter,
95104 try (ByteArrayInputStream inputStream = new ByteArrayInputStream (stream .toByteArray ());
96105 LineNumberReader lnr = new LineNumberReader (
97106 new InputStreamReader (inputStream , StandardCharsets .UTF_8 ))) {
98- final String expectedFile = configPath .replaceFirst (CONTEXT_CONFIG_PATTERN ,
99- "expected.txt" );
100- final Path expectedFilePath = Paths .get (getPath (expectedFile ));
101- final List <String > expected = Files .readAllLines (expectedFilePath );
102- final List <String > actuals = lnr .lines ().toList ();
107+
108+ final List <String > expected = extractExpectedViolations (path );
109+ final List <String > actuals = lnr .lines ()
110+ .filter (line -> !line .equals ("Audit done." ))
111+ .toList ();
112+
113+ assertEquals (expected .size (), actuals .size (),
114+ "Number of violations does not match" );
103115
104116 for (int index = 0 ; index < expected .size (); index ++) {
105- final String expectedResult = path + File .separator + expected .get (index );
106- assertEquals (expectedResult , actuals .get (index ),
107- "error message " + index + ". Expected file: " + expectedFilePath );
117+ final String expectedViolation = expected .get (index );
118+ final String actualViolation = actuals .get (index );
119+ final String expectedResult = path + File .separator + expectedViolation ;
120+ assertEquals (expectedResult , actualViolation , "error message " + index );
108121 }
109- assertEquals (expected .size (), errorCounter , "unexpected output: " + lnr .readLine ());
122+ assertEquals (expected .size (), errorCounter ,
123+ "unexpected output: " + lnr .readLine ());
110124 }
111125 }
126+
127+ /**
128+ * Extracts expected violation messages from inline comments in test files.
129+ * Falls back to expected.txt if no inline violations are found.
130+ * Parses comments like: // violation 'message'
131+ *
132+ * @param path the directory path containing test files
133+ * @return list of expected violation messages in format "filename:line: message"
134+ * @throws IOException if file reading fails
135+ */
136+ private List <String > extractExpectedViolations (String path ) throws IOException {
137+ final List <String > violations = new ArrayList <>();
138+ final File directory = new File (path );
139+ final File [] files = directory .listFiles ((dir , name ) -> {
140+ return name .endsWith (".java" ) || name .endsWith (".properties" );
141+ });
142+
143+ if (files != null ) {
144+ Arrays .sort (files );
145+
146+ for (File file : files ) {
147+ final List <String > lines =
148+ Files .readAllLines (file .toPath (), StandardCharsets .UTF_8 );
149+ for (int index = 0 ; index < lines .size (); index ++) {
150+ final String line = lines .get (index );
151+ final Matcher matcher = VIOLATION_PATTERN .matcher (line );
152+ if (matcher .find ()) {
153+ final String violationMessage = matcher .group (1 );
154+ final int lineNumber = index + 1 ;
155+ violations .add (file .getName () + ":" + lineNumber
156+ + ": " + violationMessage );
157+ }
158+ }
159+ }
160+ }
161+
162+ // Fallback to expected.txt if no inline violations found
163+ final List <String > result ;
164+ if (violations .isEmpty ()) {
165+ final File expectedFile = new File (path , "expected.txt" );
166+ if (expectedFile .exists ()) {
167+ result = Files .readAllLines (expectedFile .toPath (), StandardCharsets .UTF_8 );
168+ }
169+ else {
170+ result = violations ;
171+ }
172+ }
173+ else {
174+ result = violations ;
175+ }
176+
177+ return result ;
178+ }
112179}
0 commit comments