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