1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.checks.header;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.checks.header.MultiFileRegexpHeaderCheck.MSG_HEADER_MISMATCH;
24 import static com.puppycrawl.tools.checkstyle.checks.header.MultiFileRegexpHeaderCheck.MSG_HEADER_MISSING;
25 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
26 import static com.puppycrawl.tools.checkstyle.utils.CommonUtil.EMPTY_STRING_ARRAY;
27 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
28
29 import java.io.File;
30 import java.io.IOException;
31 import java.net.URI;
32 import java.nio.charset.StandardCharsets;
33 import java.nio.file.Files;
34 import java.util.ArrayList;
35 import java.util.List;
36 import java.util.Set;
37
38 import org.junit.jupiter.api.Test;
39 import org.junit.jupiter.api.io.TempDir;
40
41 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
42 import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
43 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class MultiFileRegexpHeaderCheckTest extends AbstractModuleTestSupport {
58
59 @TempDir
60 public File temporaryFolder;
61
62 @Override
63 protected String getPackageLocation() {
64 return "com/puppycrawl/tools/checkstyle/checks/header/regexpheader";
65 }
66
67 @Test
68 public void testSetHeaderUriNotSupport() {
69 final MultiFileRegexpHeaderCheck instance = new MultiFileRegexpHeaderCheck();
70 try {
71 instance.setHeaderFiles(String.valueOf(URI.create("file://test")));
72 assertWithMessage("Expected exception for unsupported URI").fail();
73 }
74 catch (IllegalArgumentException exc) {
75 assertWithMessage("Invalid exception message")
76 .that(exc.getMessage())
77 .isEqualTo("unable to load header file file://test");
78 }
79 }
80
81 @Test
82 public void testSetHeaderFilesNull() throws CheckstyleException {
83 final DefaultConfiguration checkConfig =
84 createModuleConfig(MultiFileRegexpHeaderCheck.class);
85
86 final MultiFileRegexpHeaderCheck instance = new MultiFileRegexpHeaderCheck();
87
88 instance.configure(checkConfig);
89
90 assertWithMessage(
91 "Expected no header files to be configured when"
92 + " 'headerFiles' property is not set")
93 .that(instance.getExternalResourceLocations())
94 .isEmpty();
95 }
96
97 @Test
98 public void testSetHeaderFilesIsBlank() throws CheckstyleException {
99 final DefaultConfiguration checkConfig =
100 createModuleConfig(MultiFileRegexpHeaderCheck.class);
101 checkConfig.addProperty("headerFiles", " , ");
102
103 final MultiFileRegexpHeaderCheck instance = new MultiFileRegexpHeaderCheck();
104
105 instance.configure(checkConfig);
106
107 assertWithMessage(
108 "Expected no header files to be configured for a blank input string")
109 .that(instance.getExternalResourceLocations())
110 .isEmpty();
111 }
112
113 @Test
114 public void testEmptyFilename() throws Exception {
115 final DefaultConfiguration checkConfig =
116 createModuleConfig(MultiFileRegexpHeaderCheck.class);
117 checkConfig.addProperty("headerFiles", "");
118
119 final MultiFileRegexpHeaderCheck instance = new MultiFileRegexpHeaderCheck();
120 instance.configure(checkConfig);
121 assertWithMessage(
122 "Expected no header files to be configured for an empty input string")
123 .that(instance.getExternalResourceLocations())
124 .isEmpty();
125
126 verify(checkConfig, getPath("InputRegexpHeaderDefaultConfig.java"), EMPTY_STRING_ARRAY);
127 }
128
129 @Test
130 public void testDefaultConfiguration() throws Exception {
131 final DefaultConfiguration checkConfig =
132 createModuleConfig(MultiFileRegexpHeaderCheck.class);
133 createChecker(checkConfig);
134 verify(checkConfig,
135 getPath("InputRegexpHeaderDefaultConfig.java"), EMPTY_STRING_ARRAY);
136 }
137
138 @Test
139 public void testAllHeaderLinesMatchedWithEmptyLine() throws Exception {
140 final DefaultConfiguration checkConfig =
141 createModuleConfig(MultiFileRegexpHeaderCheck.class);
142 checkConfig.addProperty("headerFiles", getPath("InputRegexpHeaderNewLines.header"));
143
144 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
145 checkInstance.configure(checkConfig);
146 final String allConfiguredPaths = checkInstance.getConfiguredHeaderPaths();
147
148 final String[] expected = {
149 "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "^$", allConfiguredPaths),
150 };
151 verify(checkConfig,
152 getPath("InputRegexpHeaderConsecutiveNewLines.java"), expected);
153 }
154
155 @Test
156 public void testEmptyHeaderFile() throws IOException {
157 final File emptyFile = new File(temporaryFolder, "empty.header");
158 Files.write(emptyFile.toPath(), new ArrayList<>(), StandardCharsets.UTF_8);
159 final URI fileUri = emptyFile.toURI();
160
161 try {
162 MultiFileRegexpHeaderCheck.getLines("empty.header", fileUri);
163 assertWithMessage(
164 "Expected IllegalArgumentException when reading from an empty header file")
165 .fail();
166 }
167 catch (IllegalArgumentException exc) {
168 assertWithMessage("Unexpected exception message")
169 .that(exc.getMessage())
170 .contains("Header file is empty: empty.header");
171 }
172 }
173
174 @Test
175 public void testRegexpHeader() throws Exception {
176 final DefaultConfiguration checkConfig =
177 createModuleConfig(MultiFileRegexpHeaderCheck.class);
178 checkConfig.addProperty("headerFiles", getPath("InputRegexpHeader.header"));
179
180 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
181 checkInstance.configure(checkConfig);
182 final String allConfiguredPaths = checkInstance.getConfiguredHeaderPaths();
183
184 final String[] expected = {
185 "1: " + getCheckMessage(MSG_HEADER_MISMATCH, "^/*$", allConfiguredPaths),
186 };
187 verify(checkConfig, getPath("InputRegexpHeaderNonMatching.java"),
188 expected);
189 }
190
191 @Test
192 public void testRegexpHeaderUrl() throws Exception {
193 final DefaultConfiguration checkConfig =
194 createModuleConfig(MultiFileRegexpHeaderCheck.class);
195 checkConfig.addProperty("headerFiles", getUriString("InputRegexpHeader.header"));
196
197 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
198 checkInstance.configure(checkConfig);
199 final String allConfiguredPaths = checkInstance.getConfiguredHeaderPaths();
200
201 final String[] expected = {
202 "1: " + getCheckMessage(MSG_HEADER_MISMATCH, "^/*$", allConfiguredPaths),
203 };
204 verify(checkConfig, getPath("InputRegexpHeaderNonMatching.java"),
205 expected);
206 }
207
208 @Test
209 public void testInlineRegexpHeaderConsecutiveNewlinesThroughConfigFile() throws Exception {
210 final DefaultConfiguration checkConfig =
211 createModuleConfig(MultiFileRegexpHeaderCheck.class);
212 checkConfig.addProperty("headerFiles", getUriString("InputRegexpHeaderNewLines.header"));
213
214 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
215 checkInstance.configure(checkConfig);
216 final String allConfiguredPaths = checkInstance.getConfiguredHeaderPaths();
217
218 final String[] expected = {
219 "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "^$", allConfiguredPaths),
220 };
221 verify(checkConfig,
222 getPath("InputRegexpHeaderConsecutiveNewLines.java"), expected);
223 }
224
225 @Test
226 public void testLogFirstMismatchNoMismatch() throws Exception {
227 final DefaultConfiguration checkConfig =
228 createModuleConfig(MultiFileRegexpHeaderCheck.class);
229 checkConfig.addProperty("headerFiles",
230 getPath("InputRegexpHeader.header") + ","
231 + getPath("InputRegexpHeader1.header")
232 );
233 verify(checkConfig, getPath("InputRegexpHeaderIgnore.java"),
234 EMPTY_STRING_ARRAY);
235 }
236
237 @Test
238 public void testAllHeaderLinesMatchedExactly() throws Exception {
239 final DefaultConfiguration checkConfig =
240 createModuleConfig(MultiFileRegexpHeaderCheck.class);
241 checkConfig.addProperty("headerFiles",
242 getPath("InputRegexpHeader1.header"));
243 verify(checkConfig,
244 getPath("InputRegexpHeaderIgnore.java"), EMPTY_STRING_ARRAY);
245 }
246
247 @Test
248 public void testBlankPatternBranch() throws Exception {
249 final File headerFile = new File(temporaryFolder, "blankPattern.header");
250 Files.write(headerFile.toPath(),
251 List.of("// First line", "// Second line", " "),
252 StandardCharsets.UTF_8);
253
254 final File testFile = new File(temporaryFolder, "testFile.java");
255 Files.write(testFile.toPath(),
256 List.of("// First line", "// Second line", " "),
257 StandardCharsets.UTF_8);
258
259 final DefaultConfiguration checkConfig =
260 createModuleConfig(MultiFileRegexpHeaderCheck.class);
261 checkConfig.addProperty("headerFiles", headerFile.getPath());
262
263 verify(checkConfig, testFile.getPath(), EMPTY_STRING_ARRAY);
264 }
265
266 @Test
267 public void testMismatchInMiddleOfHeader() throws Exception {
268 final DefaultConfiguration checkConfig =
269 createModuleConfig(MultiFileRegexpHeaderCheck.class);
270 checkConfig.addProperty("headerFiles", getPath("InputRegexpHeader.header"));
271
272 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
273 checkInstance.configure(checkConfig);
274 final String allPaths = checkInstance.getConfiguredHeaderPaths();
275
276 final String[] expected = {
277 "2: " + getCheckMessage(MSG_HEADER_MISMATCH, "// .*", allPaths),
278 };
279 verify(checkConfig, getPath("InputRegexpHeaderMulti52.java"), expected);
280 }
281
282 @Test
283 public void testMismatchInHeaderLine() throws Exception {
284 final DefaultConfiguration checkConfig =
285 createModuleConfig(MultiFileRegexpHeaderCheck.class);
286 checkConfig.addProperty("headerFiles", getPath("InputRegexpHeader.header"));
287
288 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
289 checkInstance.configure(checkConfig);
290 final String allPaths2 = checkInstance.getConfiguredHeaderPaths();
291
292 final String[] expected = {
293 "2: " + getCheckMessage(MSG_HEADER_MISMATCH, "// .*", allPaths2),
294 };
295 verify(checkConfig, getPath("InputRegexpHeaderMulti52.java"), expected);
296 }
297
298 @Test
299 public void testNoWarningIfSingleLinedLeft() throws Exception {
300 final DefaultConfiguration checkConfig =
301 createModuleConfig(MultiFileRegexpHeaderCheck.class);
302 checkConfig.addProperty("headerFiles", getPath("InputRegexpHeader4.header"));
303 verify(checkConfig, getPath("InputRegexpHeaderMulti5.java"), EMPTY_STRING_ARRAY);
304 }
305
306 @Test
307 public void testEmptyPatternInHeader() throws Exception {
308 final File headerFile = new File(temporaryFolder, "headerFiles.header");
309 Files.write(headerFile.toPath(), List.of("", "valid"),
310 StandardCharsets.UTF_8);
311
312 final DefaultConfiguration checkConfig =
313 createModuleConfig(MultiFileRegexpHeaderCheck.class);
314 checkConfig.addProperty("headerFiles", headerFile.getPath() + "," + headerFile.getPath());
315
316 verify(checkConfig, headerFile.getPath(), EMPTY_STRING_ARRAY);
317 }
318
319 @Test
320 public void testGetExternalResourceLocationsWithNoPropertySet() throws Exception {
321 final DefaultConfiguration configNoHeaderFiles =
322 createModuleConfig(MultiFileRegexpHeaderCheck.class);
323 final MultiFileRegexpHeaderCheck checkNoHeaders = new MultiFileRegexpHeaderCheck();
324 checkNoHeaders.configure(configNoHeaderFiles);
325
326 final Set<String> locationsNoHeaders = checkNoHeaders.getExternalResourceLocations();
327 assertWithMessage(
328 "External locations should be empty when headerFiles property is not set")
329 .that(locationsNoHeaders)
330 .isEmpty();
331 }
332
333 @Test
334 public void testGetExternalResourceLocationsFromMultipleFilesSet() throws Exception {
335 final DefaultConfiguration configWithHeaderFiles =
336 createModuleConfig(MultiFileRegexpHeaderCheck.class);
337 final String header4Path = getPath("InputRegexpHeader4.header");
338 final String header1Path = getPath("InputRegexpHeader1.header");
339 configWithHeaderFiles.addProperty("headerFiles",
340 header4Path + "," + header1Path);
341
342 final MultiFileRegexpHeaderCheck checkWithHeaders = new MultiFileRegexpHeaderCheck();
343 checkWithHeaders.configure(configWithHeaderFiles);
344
345 final Set<String> locationsWithHeaders = checkWithHeaders.getExternalResourceLocations();
346 assertWithMessage("Should have two external resource locations")
347 .that(locationsWithHeaders.size())
348 .isEqualTo(2);
349
350 final String expectedUri4 = new File(header4Path).toURI().toASCIIString();
351 final String expectedUri1 = new File(header1Path).toURI().toASCIIString();
352
353 assertWithMessage(
354 "Locations should include URI for InputRegexpHeader4.header")
355 .that(locationsWithHeaders)
356 .contains(expectedUri4);
357 assertWithMessage(
358 "Locations should include URI for InputRegexpHeader1.header")
359 .that(locationsWithHeaders)
360 .contains(expectedUri1);
361 }
362
363 @Test
364 public void testAllLinesMatch() throws Exception {
365 final String[] fileLines = {
366 "// First line",
367 "// Second line",
368 "// Third line",
369 };
370
371 final File testFile = new File(temporaryFolder, "test.java");
372 Files.write(testFile.toPath(), List.of(fileLines), StandardCharsets.UTF_8);
373
374 final File headerFile = new File(temporaryFolder, "header.header");
375 Files.write(headerFile.toPath(), List.of(
376 "// First line",
377 "// Second line",
378 "// Third line"), StandardCharsets.UTF_8);
379
380 final DefaultConfiguration checkConfig =
381 createModuleConfig(MultiFileRegexpHeaderCheck.class);
382 checkConfig.addProperty("headerFiles", headerFile.getPath());
383
384 verify(checkConfig, testFile.getPath(), EMPTY_STRING_ARRAY);
385 }
386
387 @Test
388 public void testEmptyPatternMatch() throws Exception {
389 final File fileWithBlank = new File(temporaryFolder, "blank.java");
390 Files.write(fileWithBlank.toPath(), List.of(
391 "// First line",
392 "",
393 "// Third line"), StandardCharsets.UTF_8);
394
395 final File headerFile = new File(temporaryFolder, "header.header");
396 Files.write(headerFile.toPath(), List.of(
397 "// First line",
398 "^$",
399 "// Third line"), StandardCharsets.UTF_8);
400
401 final DefaultConfiguration checkConfig =
402 createModuleConfig(MultiFileRegexpHeaderCheck.class);
403 checkConfig.addProperty("headerFiles", headerFile.getPath());
404
405 verify(checkConfig, fileWithBlank.getPath(), EMPTY_STRING_ARRAY);
406 }
407
408 @Test
409 public void testBlankLineMismatch() throws Exception {
410 final File fileNoBlank = new File(temporaryFolder, "noblank.java");
411 Files.write(fileNoBlank.toPath(), List.of(
412 "// First line",
413 "// Second line",
414 "// Third line"), StandardCharsets.UTF_8);
415
416 final File headerFile = new File(temporaryFolder, "header.header");
417 Files.write(headerFile.toPath(), List.of(
418 "// First line",
419 "^$",
420 "// Third line"), StandardCharsets.UTF_8);
421
422 final DefaultConfiguration checkConfig =
423 createModuleConfig(MultiFileRegexpHeaderCheck.class);
424 checkConfig.addProperty("headerFiles", headerFile.getPath());
425
426 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
427 checkInstance.configure(checkConfig);
428 final String allPaths = checkInstance.getConfiguredHeaderPaths();
429
430 final String[] expected = {
431 "2: " + getCheckMessage(MSG_HEADER_MISMATCH, "^$", allPaths),
432 };
433 verify(checkConfig, fileNoBlank.getPath(), expected);
434 }
435
436 @Test
437 public void testMultipleHeaderFilesAllInvalid() throws Exception {
438 final File testFile = new File(temporaryFolder, "test.java");
439 Files.write(testFile.toPath(), List.of(
440 "// Different content",
441 "// Not matching any headers"), StandardCharsets.UTF_8);
442
443 final File header1File = new File(temporaryFolder, "header1.header");
444 Files.write(header1File.toPath(), List.of("// Header 1"),
445 StandardCharsets.UTF_8);
446
447 final File header2File = new File(temporaryFolder, "header2.header");
448 Files.write(header2File.toPath(), List.of("// Header 2"),
449 StandardCharsets.UTF_8);
450
451 final DefaultConfiguration checkConfig =
452 createModuleConfig(MultiFileRegexpHeaderCheck.class);
453 checkConfig.addProperty("headerFiles",
454 header1File.getPath() + "," + header2File.getPath());
455
456 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
457 checkInstance.configure(checkConfig);
458 final String allPaths = checkInstance.getConfiguredHeaderPaths();
459
460 final String[] expected = {
461 "1: " + getCheckMessage(MSG_HEADER_MISMATCH, "// Header 1", allPaths),
462 };
463 verify(checkConfig, testFile.getPath(), expected);
464 }
465
466 @Test
467 public void testMultipleHeaderFiles() throws Exception {
468 final File headerFile1 = new File(temporaryFolder, "header1.header");
469 Files.write(headerFile1.toPath(), List.of("Copyright", "Author: .*", ""),
470 StandardCharsets.UTF_8);
471
472 final File headerFile2 = new File(temporaryFolder, "header2.header");
473 Files.write(headerFile2.toPath(), List.of("License", "Year: \\d{4}", ""),
474 StandardCharsets.UTF_8);
475
476 final File testFile = new File(temporaryFolder, "TestFile.java");
477 Files.write(testFile.toPath(), List.of("Copyright", "Author: John Doe", ""),
478 StandardCharsets.UTF_8);
479
480 final DefaultConfiguration checkConfig =
481 createModuleConfig(MultiFileRegexpHeaderCheck.class);
482 checkConfig.addProperty("headerFiles",
483 headerFile1.getPath() + "," + headerFile2.getPath());
484
485 verify(checkConfig, testFile.getPath(), EMPTY_STRING_ARRAY);
486 }
487
488 @Test
489 public void testInvalidRegex() throws Exception {
490 final File corruptedHeaderFile = new File(temporaryFolder, "corrupted.header");
491 Files.write(corruptedHeaderFile.toPath(), List.of("Invalid regex [a-z"),
492 StandardCharsets.UTF_8);
493
494 final MultiFileRegexpHeaderCheck check = new MultiFileRegexpHeaderCheck();
495
496 try {
497 check.setHeaderFiles(corruptedHeaderFile.getPath());
498 assertWithMessage("Expected exception for corrupted header file").fail();
499 }
500 catch (IllegalArgumentException exc) {
501 assertWithMessage("Invalid exception message")
502 .that(exc.getMessage())
503 .isEqualTo("Invalid regex pattern: Invalid regex [a-z");
504 }
505 }
506
507 @Test
508 public void testInvalidFileName() {
509 final MultiFileRegexpHeaderCheck check = new MultiFileRegexpHeaderCheck();
510 final String headerFile = "UnExisted file";
511 final IllegalArgumentException thrown =
512 getExpectedThrowable(IllegalArgumentException.class, () -> {
513 check.setHeaderFiles(headerFile);
514 });
515 assertWithMessage("Exception message did not match for invalid file name.")
516 .that(thrown.getMessage())
517 .isEqualTo("Error reading or corrupted header file: " + headerFile);
518 }
519
520 @Test
521 public void testHeaderMoreLinesThanFile() throws Exception {
522 final File testFile = new File(temporaryFolder, "shortFile.java");
523 Files.write(testFile.toPath(), List.of(
524 "// Different content",
525 "// Not matching header"), StandardCharsets.UTF_8);
526
527 final File headerFile = new File(temporaryFolder, "longHeader.header");
528 Files.write(headerFile.toPath(), List.of(
529 "// First line",
530 "// Second line",
531 "// Third line",
532 "// Fourth line",
533 "// Fifth line"), StandardCharsets.UTF_8);
534
535 final DefaultConfiguration checkConfig =
536 createModuleConfig(MultiFileRegexpHeaderCheck.class);
537 checkConfig.addProperty("headerFiles", headerFile.getPath());
538
539 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
540 checkInstance.configure(checkConfig);
541 final String allPaths = checkInstance.getConfiguredHeaderPaths();
542
543 final String[] expected = {
544 "1: " + getCheckMessage(MSG_HEADER_MISSING, headerFile.getPath(), allPaths),
545 };
546 verify(checkConfig, testFile.getPath(), expected);
547 }
548
549 @Test
550 public void testMismatchLineCondition() throws Exception {
551 final File testFile = new File(temporaryFolder, "mismatchFile.java");
552 Files.write(testFile.toPath(), List.of(
553 "// First line matches",
554 "// This line doesn't match the header pattern",
555 "// Third line matches"), StandardCharsets.UTF_8);
556
557 final File headerFile = new File(temporaryFolder, "mismatchHeader.header");
558 Files.write(headerFile.toPath(), List.of(
559 "// First line matches",
560 "// Second line matches",
561 "// Third line matches"), StandardCharsets.UTF_8);
562
563 final DefaultConfiguration checkConfig =
564 createModuleConfig(MultiFileRegexpHeaderCheck.class);
565 checkConfig.addProperty("headerFiles", headerFile.getPath());
566
567 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
568 checkInstance.configure(checkConfig);
569 final String allPaths = checkInstance.getConfiguredHeaderPaths();
570
571 final String[] expected = {
572 "2: " + getCheckMessage(MSG_HEADER_MISMATCH,
573 "// Second line matches", allPaths),
574 };
575 verify(checkConfig, testFile.getPath(), expected);
576 }
577
578 @Test
579 public void testFindFirstMismatch() throws Exception {
580 final File testFile = new File(temporaryFolder, "test.java");
581 Files.write(testFile.toPath(), List.of(
582 "// First line",
583 "// Second line",
584 "// Third line"), StandardCharsets.UTF_8);
585
586 final File headerFile = new File(temporaryFolder, "header.header");
587 Files.write(headerFile.toPath(), List.of(
588 "// First line",
589 "// Different line",
590 "// Third line"), StandardCharsets.UTF_8);
591
592 final DefaultConfiguration checkConfig =
593 createModuleConfig(MultiFileRegexpHeaderCheck.class);
594 checkConfig.addProperty("headerFiles", headerFile.getPath());
595
596 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
597 checkInstance.configure(checkConfig);
598 final String allPaths = checkInstance.getConfiguredHeaderPaths();
599
600 final String[] expected = {
601 "2: " + getCheckMessage(MSG_HEADER_MISMATCH, "// Different line", allPaths),
602 };
603 verify(checkConfig, testFile.getPath(), expected);
604 }
605
606 @Test
607 public void testNoMatchingHeaderFile() throws Exception {
608 final File testFile = new File(temporaryFolder, "test.java");
609 Files.write(testFile.toPath(), List.of(
610 "// Different content",
611 "// Not matching any headers"), StandardCharsets.UTF_8);
612
613 final File headerFile = new File(temporaryFolder, "header.header");
614 Files.write(headerFile.toPath(), List.of(
615 "// Header content",
616 "// Another line"), StandardCharsets.UTF_8);
617
618 final DefaultConfiguration checkConfig =
619 createModuleConfig(MultiFileRegexpHeaderCheck.class);
620 checkConfig.addProperty("headerFiles", headerFile.getPath());
621
622 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
623 checkInstance.configure(checkConfig);
624 final String allPaths = checkInstance.getConfiguredHeaderPaths();
625
626 final String[] expected = {
627 "1: " + getCheckMessage(MSG_HEADER_MISMATCH, "// Header content", allPaths),
628 };
629 verify(checkConfig, testFile.getPath(), expected);
630 }
631
632 @Test
633 public void testNonEmptyPatternsWithMismatchedCardinality() throws Exception {
634 final File headerFile = new File(temporaryFolder, "header.header");
635 Files.write(headerFile.toPath(), List.of(
636 "// First line",
637 "// Second line",
638 "// Third line with different pattern"
639 ), StandardCharsets.UTF_8);
640
641 final File testFile = new File(temporaryFolder, "testFile.java");
642 Files.write(testFile.toPath(), List.of(
643 "// First line",
644 "// Second line",
645 "// Third line that does not match"
646 ), StandardCharsets.UTF_8);
647
648 final DefaultConfiguration checkConfig =
649 createModuleConfig(MultiFileRegexpHeaderCheck.class);
650 checkConfig.addProperty("headerFiles", headerFile.getPath());
651
652 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
653 checkInstance.configure(checkConfig);
654 final String allPaths = checkInstance.getConfiguredHeaderPaths();
655
656 final String[] expected = {
657 "3: " + getCheckMessage(MSG_HEADER_MISMATCH,
658 "// Third line with different pattern", allPaths),
659 };
660 verify(checkConfig, testFile.getPath(), expected);
661 }
662
663 @Test
664 public void testFileFailsWhenShorterThanHeader() throws Exception {
665 final File headerFile = new File(temporaryFolder, "longerHeader.header");
666 Files.write(headerFile.toPath(), List.of(
667 "// Line 1",
668 "// Line 2",
669 "// Line 3"
670 ), StandardCharsets.UTF_8);
671
672 final File testFile = new File(temporaryFolder, "shorterFile.java");
673 Files.write(testFile.toPath(), List.of(
674 "// Line 1"
675 ), StandardCharsets.UTF_8);
676
677 final DefaultConfiguration checkConfig =
678 createModuleConfig(MultiFileRegexpHeaderCheck.class);
679 checkConfig.addProperty("headerFiles", headerFile.getPath());
680
681 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
682 checkInstance.configure(checkConfig);
683 final String allPaths = checkInstance.getConfiguredHeaderPaths();
684
685 final String[] expected = {
686 "1: " + getCheckMessage(MSG_HEADER_MISSING, headerFile.getPath(), allPaths),
687 };
688 verify(checkConfig, testFile.getPath(), expected);
689 }
690
691 @Test
692 public void testHeaderWithTrailingBlanksFailsWhenFileIsShorter() throws Exception {
693 final File headerFile = new File(temporaryFolder, "headerWithBlanks.header");
694 Files.write(headerFile.toPath(), List.of(
695 "// Line 1",
696 "",
697 "// Line 3"
698 ), StandardCharsets.UTF_8);
699
700 final File testFile = new File(temporaryFolder, "shorterFile.java");
701 Files.write(testFile.toPath(), List.of(
702 "// Line 1"
703 ), StandardCharsets.UTF_8);
704
705 final DefaultConfiguration checkConfig =
706 createModuleConfig(MultiFileRegexpHeaderCheck.class);
707 checkConfig.addProperty("headerFiles", headerFile.getPath());
708
709 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
710 checkInstance.configure(checkConfig);
711 final String allPaths = checkInstance.getConfiguredHeaderPaths();
712
713 final String[] expected = {
714 "1: " + getCheckMessage(MSG_HEADER_MISSING, headerFile.getPath(), allPaths),
715 };
716 verify(checkConfig, testFile.getPath(), expected);
717 }
718
719 @Test
720 public void testFileSizeGreaterThanHeaderPatternSize() throws Exception {
721 final File headerFile = new File(temporaryFolder, "shorterHeader.header");
722 Files.write(headerFile.toPath(), List.of(
723 "// First line",
724 "// Second line",
725 "// Third line"), StandardCharsets.UTF_8);
726
727
728 final File testFile = new File(temporaryFolder, "longerFile.java");
729 Files.write(testFile.toPath(), List.of(
730 "// First line",
731 "// Second line",
732 "// Third line",
733 "// Fourth line",
734 "// Fifth line"), StandardCharsets.UTF_8);
735
736 final DefaultConfiguration checkConfig =
737 createModuleConfig(MultiFileRegexpHeaderCheck.class);
738 checkConfig.addProperty("headerFiles", headerFile.getPath());
739
740 verify(checkConfig, testFile.getPath(), EMPTY_STRING_ARRAY);
741 }
742
743 @Test
744 public void testFileSizeEqualHeaderPatternSize() throws Exception {
745 final File headerFile = new File(temporaryFolder, "shorterHeader.header");
746 Files.write(headerFile.toPath(), List.of(
747 "// First line",
748 "// Second line",
749 "// Third line"), StandardCharsets.UTF_8);
750
751 final File testFile = new File(temporaryFolder, "longerFile.java");
752 Files.write(testFile.toPath(), List.of(
753 "// First line",
754 "// Second line",
755 "// Third line"), StandardCharsets.UTF_8);
756
757 final DefaultConfiguration checkConfig =
758 createModuleConfig(MultiFileRegexpHeaderCheck.class);
759 checkConfig.addProperty("headerFiles", headerFile.getPath());
760
761 verify(checkConfig, testFile.getPath(), EMPTY_STRING_ARRAY);
762 }
763
764 @Test
765 public void testSpecificLineMismatch() throws Exception {
766 final File headerFile = new File(temporaryFolder, "multiline.header");
767 Files.write(headerFile.toPath(), List.of(
768 "// First line",
769 "// Second line",
770 "// Third line with pattern .*",
771 "// Fourth line",
772 "// Fifth line"), StandardCharsets.UTF_8);
773
774 final File testFile = new File(temporaryFolder, "mismatchThirdLine.java");
775 Files.write(testFile.toPath(), List.of(
776 "// First line",
777 "// Second line",
778 "This line doesn't match the pattern",
779 "// Fourth line",
780 "// Fifth line"), StandardCharsets.UTF_8);
781
782 final DefaultConfiguration checkConfig =
783 createModuleConfig(MultiFileRegexpHeaderCheck.class);
784 checkConfig.addProperty("headerFiles", headerFile.getPath());
785
786 final MultiFileRegexpHeaderCheck checkInstance = new MultiFileRegexpHeaderCheck();
787 checkInstance.configure(checkConfig);
788 final String allPaths = checkInstance.getConfiguredHeaderPaths();
789
790 final String[] expected = {
791 "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "// Third line with pattern .*", allPaths),
792 };
793 verify(checkConfig, testFile.getPath(), expected);
794 }
795
796 @Test
797 public void testMultipleHeaderFilesFirstMatchesSecondDoesnt() throws Exception {
798 final File matchingHeaderFile = new File(temporaryFolder, "matching.header");
799 Files.write(matchingHeaderFile.toPath(), List.of(
800 "// This header matches",
801 "// The file content"), StandardCharsets.UTF_8);
802
803 final File nonMatchingHeaderFile = new File(temporaryFolder, "nonMatching.header");
804 Files.write(nonMatchingHeaderFile.toPath(), List.of(
805 "// This header doesn't match",
806 "// Different content"), StandardCharsets.UTF_8);
807
808 final File testFile = new File(temporaryFolder, "TestFile.java");
809 Files.write(testFile.toPath(), List.of(
810 "// This header matches",
811 "// The file content"), StandardCharsets.UTF_8);
812
813 final DefaultConfiguration checkConfig =
814 createModuleConfig(MultiFileRegexpHeaderCheck.class);
815 checkConfig.addProperty("headerFiles",
816 matchingHeaderFile.getPath() + "," + nonMatchingHeaderFile.getPath());
817 verify(checkConfig, testFile.getPath(), EMPTY_STRING_ARRAY);
818 }
819
820 @Test
821 public void testMultipleHeaderFilesNoneMatch() throws Exception {
822 final File matchingHeader = new File(temporaryFolder, "nonMatching1.header");
823 Files.write(matchingHeader.toPath(), List.of(
824 "// First matching header",
825 "// Second matching header"), StandardCharsets.UTF_8);
826
827 final File nonMatchingHeader = new File(temporaryFolder, "nonMatching2.header");
828 Files.write(nonMatchingHeader.toPath(), List.of(
829 "// First matching header",
830 "// Second no-matching header"), StandardCharsets.UTF_8);
831
832 final File testFile = new File(temporaryFolder, "TestFile.java");
833 Files.write(testFile.toPath(), List.of(
834 "// First matching header",
835 "// Second matching header"), StandardCharsets.UTF_8);
836
837 final DefaultConfiguration checkConfig =
838 createModuleConfig(MultiFileRegexpHeaderCheck.class);
839 checkConfig.addProperty("headerFiles",
840 matchingHeader.getPath() + "," + nonMatchingHeader.getPath());
841
842 verify(checkConfig, testFile.getPath(), EMPTY_STRING_ARRAY);
843 }
844
845 @Test
846 public void testSetHeaderFilesWithNullPathThrowsException() {
847 final MultiFileRegexpHeaderCheck check = new MultiFileRegexpHeaderCheck();
848
849 final IllegalArgumentException thrown =
850 getExpectedThrowable(IllegalArgumentException.class, () -> {
851 check.setHeaderFiles((String) null);
852 });
853 assertWithMessage("Exception message mismatch for null header path")
854 .that(thrown.getMessage()).isEqualTo("Header file is not set");
855 }
856
857 @Test
858 public void testSetHeaderFilesWithNullVarargsArray() {
859 final MultiFileRegexpHeaderCheck check = new MultiFileRegexpHeaderCheck();
860
861 assertDoesNotThrow(() -> {
862 check.setHeaderFiles((String[]) null);
863 });
864
865 assertWithMessage(
866 "External locations should be empty when setHeaderFiles is called with null array")
867 .that(check.getExternalResourceLocations())
868 .isEmpty();
869 }
870
871 @Test
872 public void testSetHeaderFilesClearsPreviousConfiguration() throws IOException {
873 final MultiFileRegexpHeaderCheck check = new MultiFileRegexpHeaderCheck();
874
875 final File headerFileA = new File(temporaryFolder, "testHeaderA_clear_check.header");
876 Files.write(headerFileA.toPath(), List.of("// Header A for clear check"),
877 StandardCharsets.UTF_8);
878 final String pathA = headerFileA.getAbsolutePath();
879 final URI uriA = headerFileA.toURI();
880
881 check.setHeaderFiles(pathA);
882 assertWithMessage("After first set, only header A should be present")
883 .that(check.getExternalResourceLocations())
884 .containsExactly(uriA.toASCIIString());
885
886 final File headerFileB = new File(temporaryFolder, "testHeaderB_clear_check.header");
887 Files.write(headerFileB.toPath(), List.of("// Header B for clear check"),
888 StandardCharsets.UTF_8);
889 final String pathB = headerFileB.getAbsolutePath();
890 final URI uriB = headerFileB.toURI();
891
892 check.setHeaderFiles(pathB);
893 assertWithMessage("After second set, only header B should be present")
894 .that(check.getExternalResourceLocations())
895 .containsExactly(uriB.toASCIIString());
896 }
897
898 @Test
899 public void testHeaderFileMetadataMethods() throws Exception {
900 final File headerFile = new File(temporaryFolder, "header.header");
901 Files.write(headerFile.toPath(), List.of(
902 "// First line",
903 "",
904 "// Third line"), StandardCharsets.UTF_8);
905
906 final MultiFileRegexpHeaderCheck check = new MultiFileRegexpHeaderCheck();
907 check.setHeaderFiles(headerFile.getPath());
908
909 final Set<String> locations = check.getExternalResourceLocations();
910 assertWithMessage("Should have one external resource location")
911 .that(locations.size())
912 .isEqualTo(1);
913 assertWithMessage("Location should include header.header")
914 .that(locations.stream()
915 .anyMatch(loc -> loc.contains("header.header")))
916 .isTrue();
917 }
918
919 @Test
920 public void testIoExceptionInGetLines() {
921 final File nonExistentFile = new File(temporaryFolder, "nonexistent.header");
922 final URI fileUri = nonExistentFile.toURI();
923
924 try {
925 MultiFileRegexpHeaderCheck.getLines("nonexistent.header", fileUri);
926 assertWithMessage(
927 "Expected IllegalArgumentException when reading from a non-existent file")
928 .fail();
929 }
930 catch (IllegalArgumentException exc) {
931 assertWithMessage("Unexpected exception message")
932 .that(exc.getMessage())
933 .contains("unable to load header file nonexistent.header");
934 }
935 }
936
937 @Test
938 public void testConfiguredHeaderPathsNoFiles() {
939 final MultiFileRegexpHeaderCheck check = new MultiFileRegexpHeaderCheck();
940 assertWithMessage("Expected empty string when no header files are configured")
941 .that(check.getConfiguredHeaderPaths())
942 .isEmpty();
943 }
944
945 @Test
946 public void testConfiguredHeaderPathsSingleFile() throws IOException {
947 final MultiFileRegexpHeaderCheck check = new MultiFileRegexpHeaderCheck();
948 final File headerFile = new File(temporaryFolder, "singleTest.header");
949 Files.writeString(headerFile.toPath(), "// Single test header", StandardCharsets.UTF_8);
950 final String path = headerFile.getAbsolutePath();
951
952 check.setHeaderFiles(path);
953
954 assertWithMessage("Expected path of the single configured file")
955 .that(check.getConfiguredHeaderPaths())
956 .isEqualTo(path);
957 }
958
959 @Test
960 public void testConfiguredHeaderPathsMultipleFiles() throws IOException {
961 final MultiFileRegexpHeaderCheck check = new MultiFileRegexpHeaderCheck();
962 final File headerFile1 = new File(temporaryFolder, "multiTest1.header");
963 Files.writeString(headerFile1.toPath(), "// Multi test header 1", StandardCharsets.UTF_8);
964 final String path1 = headerFile1.getAbsolutePath();
965
966 final File headerFile2 = new File(temporaryFolder, "multiTest2.header");
967 Files.writeString(headerFile2.toPath(), "// Multi test header 2", StandardCharsets.UTF_8);
968 final String path2 = headerFile2.getAbsolutePath();
969
970 check.setHeaderFiles(path1, path2);
971
972 final String expectedPaths = path1 + ", " + path2;
973 assertWithMessage("Expected comma-separated paths of multiple configured files")
974 .that(check.getConfiguredHeaderPaths())
975 .isEqualTo(expectedPaths);
976
977 check.setHeaderFiles(path1, path2);
978 assertWithMessage("Expected comma-separated paths when set with distinct args")
979 .that(check.getConfiguredHeaderPaths())
980 .isEqualTo(expectedPaths);
981 }
982
983 }