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.ant;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
24
25 import java.io.File;
26 import java.io.IOException;
27 import java.net.URL;
28 import java.nio.charset.StandardCharsets;
29 import java.nio.file.Files;
30 import java.util.Arrays;
31 import java.util.List;
32 import java.util.Locale;
33 import java.util.Map;
34 import java.util.Optional;
35 import java.util.ResourceBundle;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38
39 import org.apache.tools.ant.BuildException;
40 import org.apache.tools.ant.Project;
41 import org.apache.tools.ant.types.FileSet;
42 import org.apache.tools.ant.types.Path;
43 import org.apache.tools.ant.types.resources.FileResource;
44 import org.junit.jupiter.api.Test;
45
46 import com.google.common.truth.StandardSubjectBuilder;
47 import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport;
48 import com.puppycrawl.tools.checkstyle.DefaultLogger;
49 import com.puppycrawl.tools.checkstyle.Definitions;
50 import com.puppycrawl.tools.checkstyle.SarifLogger;
51 import com.puppycrawl.tools.checkstyle.XMLLogger;
52 import com.puppycrawl.tools.checkstyle.internal.testmodules.CheckstyleAntTaskLogStub;
53 import com.puppycrawl.tools.checkstyle.internal.testmodules.CheckstyleAntTaskStub;
54 import com.puppycrawl.tools.checkstyle.internal.testmodules.MessageLevelPair;
55 import com.puppycrawl.tools.checkstyle.internal.testmodules.TestRootModuleChecker;
56
57 public class CheckstyleAntTaskTest extends AbstractPathTestSupport {
58
59 private static final String FLAWLESS_INPUT =
60 "InputCheckstyleAntTaskFlawless.java";
61 private static final String VIOLATED_INPUT =
62 "InputCheckstyleAntTaskError.java";
63 private static final String WARNING_INPUT =
64 "InputCheckstyleAntTaskWarning.java";
65 private static final String CONFIG_FILE =
66 "InputCheckstyleAntTaskTestChecks.xml";
67 private static final String CUSTOM_ROOT_CONFIG_FILE =
68 "InputCheckstyleAntTaskConfigCustomRootModule.xml";
69 private static final String NOT_EXISTING_FILE = "target/not_existing.xml";
70 private static final String FAILURE_PROPERTY_VALUE = "myValue";
71
72 @Override
73 protected String getPackageLocation() {
74 return "com/puppycrawl/tools/checkstyle/ant/checkstyleanttask/";
75 }
76
77 private CheckstyleAntTask getCheckstyleAntTask() throws IOException {
78 return getCheckstyleAntTask(CONFIG_FILE);
79 }
80
81 private CheckstyleAntTask getCheckstyleAntTask(String configFile) throws IOException {
82 final CheckstyleAntTask antTask = new CheckstyleAntTask();
83 antTask.setConfig(getPath(configFile));
84 antTask.setProject(new Project());
85 return antTask;
86 }
87
88 @Test
89 public final void testDefaultFlawless() throws IOException {
90 TestRootModuleChecker.reset();
91 final CheckstyleAntTask antTask = getCheckstyleAntTask(CUSTOM_ROOT_CONFIG_FILE);
92 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
93 antTask.execute();
94
95 assertWithMessage("Checker is not processed")
96 .that(TestRootModuleChecker.isProcessed())
97 .isTrue();
98 }
99
100 @Test
101 public final void testPathsOneFile() throws IOException {
102
103 TestRootModuleChecker.reset();
104
105 final CheckstyleAntTask antTask = getCheckstyleAntTask(CUSTOM_ROOT_CONFIG_FILE);
106 final FileSet examinationFileSet = new FileSet();
107 examinationFileSet.setFile(new File(getPath(FLAWLESS_INPUT)));
108 final Path sourcePath = new Path(antTask.getProject());
109 sourcePath.addFileset(examinationFileSet);
110 antTask.addPath(sourcePath);
111
112
113 antTask.execute();
114
115
116 assertWithMessage("Checker is not processed")
117 .that(TestRootModuleChecker.isProcessed())
118 .isTrue();
119 final List<File> filesToCheck = TestRootModuleChecker.getFilesToCheck();
120 assertWithMessage("There are more files to check than expected")
121 .that(filesToCheck)
122 .hasSize(1);
123 assertWithMessage("The path of file differs from expected")
124 .that(filesToCheck.get(0).getAbsolutePath())
125 .isEqualTo(getPath(FLAWLESS_INPUT));
126 }
127
128 @Test
129 public final void testPathsFileWithLogVerification() throws IOException {
130
131 TestRootModuleChecker.reset();
132 final CheckstyleAntTaskLogStub antTask = new CheckstyleAntTaskLogStub();
133 antTask.setConfig(getPath(CUSTOM_ROOT_CONFIG_FILE));
134 antTask.setProject(new Project());
135 final FileSet examinationFileSet = new FileSet();
136 examinationFileSet.setFile(new File(getPath(FLAWLESS_INPUT)));
137 final Path sourcePath = new Path(antTask.getProject());
138 sourcePath.addFileset(examinationFileSet);
139 antTask.addPath(sourcePath);
140 antTask.addPath(new Path(new Project()));
141
142
143 antTask.execute();
144
145
146 final List<MessageLevelPair> loggedMessages = antTask.getLoggedMessages();
147
148 assertWithMessage("Scanning path was not logged")
149 .that(loggedMessages.stream().filter(
150 msg -> msg.getMsg().startsWith("1) Scanning path")).count())
151 .isEqualTo(1);
152
153 assertWithMessage("Scanning path was not logged")
154 .that(loggedMessages.stream().filter(
155 msg -> msg.getMsg().startsWith("1) Adding 1 files from path")).count())
156 .isEqualTo(1);
157
158 assertWithMessage("Scanning empty was logged")
159 .that(loggedMessages.stream().filter(
160 msg -> msg.getMsg().startsWith("2) Adding 0 files from path ")).count())
161 .isEqualTo(0);
162
163 assertWithMessage("Checker is not processed")
164 .that(TestRootModuleChecker.isProcessed())
165 .isTrue();
166 final List<File> filesToCheck = TestRootModuleChecker.getFilesToCheck();
167 assertWithMessage("There are more files to check than expected")
168 .that(filesToCheck)
169 .hasSize(1);
170 assertWithMessage("The path of file differs from expected")
171 .that(filesToCheck.get(0).getAbsolutePath())
172 .isEqualTo(getPath(FLAWLESS_INPUT));
173 }
174
175 @Test
176 public final void testPathsDirectoryWithNestedFile() throws IOException {
177
178 TestRootModuleChecker.reset();
179
180 final CheckstyleAntTaskLogStub antTask = new CheckstyleAntTaskLogStub();
181 antTask.setConfig(getPath(CUSTOM_ROOT_CONFIG_FILE));
182 antTask.setProject(new Project());
183
184 final FileResource fileResource = new FileResource(
185 antTask.getProject(), getPath(""));
186 final Path sourcePath = new Path(antTask.getProject());
187 sourcePath.add(fileResource);
188 antTask.addPath(sourcePath);
189
190
191 antTask.execute();
192
193
194 assertWithMessage("Checker is not processed")
195 .that(TestRootModuleChecker.isProcessed())
196 .isTrue();
197 final List<File> filesToCheck = TestRootModuleChecker.getFilesToCheck();
198 assertWithMessage("There are more files to check than expected")
199 .that(filesToCheck)
200 .hasSize(9);
201 assertWithMessage("The path of file differs from expected")
202 .that(filesToCheck.get(6).getAbsolutePath())
203 .isEqualTo(getPath(FLAWLESS_INPUT));
204 assertWithMessage("Amount of logged messages in unexpected")
205 .that(antTask.getLoggedMessages())
206 .hasSize(8);
207 }
208
209 @Test
210 public final void testCustomRootModule() throws IOException {
211 TestRootModuleChecker.reset();
212
213 final CheckstyleAntTask antTask = getCheckstyleAntTask(CUSTOM_ROOT_CONFIG_FILE);
214 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
215 antTask.execute();
216
217 assertWithMessage("Checker is not processed")
218 .that(TestRootModuleChecker.isProcessed())
219 .isTrue();
220 }
221
222 @Test
223 public final void testFileSet() throws IOException {
224 TestRootModuleChecker.reset();
225 final CheckstyleAntTask antTask = getCheckstyleAntTask(CUSTOM_ROOT_CONFIG_FILE);
226 final FileSet examinationFileSet = new FileSet();
227 examinationFileSet.setFile(new File(getPath(FLAWLESS_INPUT)));
228 antTask.addFileset(examinationFileSet);
229 antTask.execute();
230
231 assertWithMessage("Checker is not processed")
232 .that(TestRootModuleChecker.isProcessed())
233 .isTrue();
234 final List<File> filesToCheck = TestRootModuleChecker.getFilesToCheck();
235 assertWithMessage("There are more files to check than expected")
236 .that(filesToCheck)
237 .hasSize(1);
238 assertWithMessage("The path of file differs from expected")
239 .that(filesToCheck.get(0).getAbsolutePath())
240 .isEqualTo(getPath(FLAWLESS_INPUT));
241 }
242
243 @Test
244 public final void testNoConfigFile() throws IOException {
245 final CheckstyleAntTask antTask = new CheckstyleAntTask();
246 antTask.setProject(new Project());
247 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
248 final BuildException ex = getExpectedThrowable(BuildException.class,
249 antTask::execute,
250 "BuildException is expected");
251 assertWithMessage("Error message is unexpected")
252 .that(ex.getMessage())
253 .isEqualTo("Must specify 'config'.");
254 }
255
256 @Test
257 public final void testNonExistentConfig() throws IOException {
258 final CheckstyleAntTask antTask = new CheckstyleAntTask();
259 antTask.setConfig(getPath(NOT_EXISTING_FILE));
260 antTask.setProject(new Project());
261 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
262 final BuildException ex = getExpectedThrowable(BuildException.class,
263 antTask::execute,
264 "BuildException is expected");
265 assertWithMessage("Error message is unexpected")
266 .that(ex.getMessage())
267 .startsWith("Unable to create Root Module: config");
268 }
269
270 @Test
271 public final void testEmptyConfigFile() throws IOException {
272 final CheckstyleAntTask antTask = new CheckstyleAntTask();
273 antTask.setConfig(getPath("InputCheckstyleAntTaskEmptyConfig.xml"));
274 antTask.setProject(new Project());
275 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
276 final BuildException ex = getExpectedThrowable(BuildException.class,
277 antTask::execute,
278 "BuildException is expected");
279 assertWithMessage("Error message is unexpected")
280 .that(ex.getMessage())
281 .startsWith("Unable to create Root Module: config");
282 }
283
284 @Test
285 public final void testNoFile() throws IOException {
286 final CheckstyleAntTask antTask = getCheckstyleAntTask();
287 final BuildException ex = getExpectedThrowable(BuildException.class,
288 antTask::execute,
289 "BuildException is expected");
290 assertWithMessage("Error message is unexpected")
291 .that(ex.getMessage())
292 .isEqualTo("Must specify at least one of 'file' or nested 'fileset' or 'path'.");
293 }
294
295 @Test
296 public final void testMaxWarningExceeded() throws IOException {
297 final CheckstyleAntTask antTask = getCheckstyleAntTask();
298 antTask.setFile(new File(getPath(WARNING_INPUT)));
299 antTask.setMaxWarnings(0);
300 final BuildException ex = getExpectedThrowable(BuildException.class,
301 antTask::execute,
302 "BuildException is expected");
303 assertWithMessage("Error message is unexpected")
304 .that(ex.getMessage())
305 .isEqualTo("Got 0 errors and 1 warnings.");
306 }
307
308 @Test
309 public final void testMaxErrors() throws IOException {
310 TestRootModuleChecker.reset();
311
312 final CheckstyleAntTask antTask = getCheckstyleAntTask(CUSTOM_ROOT_CONFIG_FILE);
313 antTask.setFile(new File(getPath(VIOLATED_INPUT)));
314 antTask.setMaxErrors(2);
315 antTask.execute();
316
317 assertWithMessage("Checker is not processed")
318 .that(TestRootModuleChecker.isProcessed())
319 .isTrue();
320 }
321
322 @Test
323 public final void testFailureProperty() throws IOException {
324 final CheckstyleAntTask antTask = new CheckstyleAntTask();
325 antTask.setConfig(getPath(CONFIG_FILE));
326 antTask.setFile(new File(getPath(VIOLATED_INPUT)));
327
328 final Project project = new Project();
329 final String failurePropertyName = "myProperty";
330 project.setProperty(failurePropertyName, FAILURE_PROPERTY_VALUE);
331
332 antTask.setProject(project);
333 antTask.setFailureProperty(failurePropertyName);
334 final BuildException ex = getExpectedThrowable(BuildException.class,
335 antTask::execute,
336 "BuildException is expected");
337 assertWithMessage("Error message is unexpected")
338 .that(ex.getMessage())
339 .isEqualTo("Got 2 errors and 0 warnings.");
340 final Map<String, Object> hashtable = project.getProperties();
341 final Object propertyValue = hashtable.get(failurePropertyName);
342 assertWithMessage("Number of errors is unexpected")
343 .that(propertyValue)
344 .isEqualTo("Got 2 errors and 0 warnings.");
345 }
346
347 @Test
348 public final void testOverrideProperty() throws IOException {
349 TestRootModuleChecker.reset();
350
351 final CheckstyleAntTask antTask = getCheckstyleAntTask(CUSTOM_ROOT_CONFIG_FILE);
352 antTask.setFile(new File(getPath(VIOLATED_INPUT)));
353 final CheckstyleAntTask.Property property = new CheckstyleAntTask.Property();
354 property.setKey("lineLength.severity");
355 property.setValue("ignore");
356 antTask.addProperty(property);
357 antTask.execute();
358
359 assertWithMessage("Checker is not processed")
360 .that(TestRootModuleChecker.isProcessed())
361 .isTrue();
362 }
363
364 @Test
365 public final void testExecuteIgnoredModules() throws IOException {
366 final CheckstyleAntTask antTask = getCheckstyleAntTask();
367 antTask.setFile(new File(getPath(VIOLATED_INPUT)));
368 antTask.setFailOnViolation(false);
369 antTask.setExecuteIgnoredModules(true);
370
371 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
372 final File outputFile = new File("target/ant_task_plain_output.txt");
373 formatter.setTofile(outputFile);
374 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
375 formatterType.setValue("plain");
376 formatter.setType(formatterType);
377 formatter.createListener(null);
378
379 antTask.addFormatter(formatter);
380 antTask.execute();
381
382 final ResourceBundle bundle = ResourceBundle.getBundle(
383 Definitions.CHECKSTYLE_BUNDLE, Locale.ROOT);
384 final String auditStartedMessage = bundle.getString(DefaultLogger.AUDIT_STARTED_MESSAGE);
385 final String auditFinishedMessage = bundle.getString(DefaultLogger.AUDIT_FINISHED_MESSAGE);
386 final List<String> output = readWholeFile(outputFile);
387 final String errorMessage = "Content of file with violations differs from expected";
388 assertWithMessage(errorMessage)
389 .that(output.get(0))
390 .isEqualTo(auditStartedMessage);
391 assertWithMessage(errorMessage)
392 .that(output.get(1))
393 .matches("^\\[WARN].*InputCheckstyleAntTaskError.java:4: .*"
394 + "@incomplete=Some javadoc \\[WriteTag]");
395 assertWithMessage(errorMessage)
396 .that(output.get(2))
397 .matches("^\\[ERROR].*InputCheckstyleAntTaskError.java:7: "
398 + "Line is longer than 70 characters \\(found 80\\). \\[LineLength]");
399 assertWithMessage(errorMessage)
400 .that(output.get(3))
401 .matches("^\\[ERROR].*InputCheckstyleAntTaskError.java:9: "
402 + "Line is longer than 70 characters \\(found 81\\). \\[LineLength]");
403 assertWithMessage(errorMessage)
404 .that(output.get(4))
405 .isEqualTo(auditFinishedMessage);
406 }
407
408 @Test
409 public final void testConfigurationByUrl() throws IOException {
410 final CheckstyleAntTask antTask = new CheckstyleAntTask();
411 antTask.setProject(new Project());
412 final URL url = new File(getPath(CONFIG_FILE)).toURI().toURL();
413 antTask.setConfig(url.toString());
414 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
415
416 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
417 final File outputFile = new File("target/ant_task_config_by_url.txt");
418 formatter.setTofile(outputFile);
419 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
420 formatterType.setValue("plain");
421 formatter.setType(formatterType);
422 formatter.createListener(null);
423 antTask.addFormatter(formatter);
424
425 antTask.execute();
426
427 final List<String> output = readWholeFile(outputFile);
428 final int sizeOfOutputWithNoViolations = 2;
429 assertWithMessage("No violations expected")
430 .that(output)
431 .hasSize(sizeOfOutputWithNoViolations);
432 }
433
434 @Test
435 public final void testConfigurationByResource() throws IOException {
436 final CheckstyleAntTask antTask = new CheckstyleAntTask();
437 antTask.setProject(new Project());
438 antTask.setConfig(getPath(CONFIG_FILE));
439 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
440
441 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
442 final File outputFile = new File("target/ant_task_config_by_url.txt");
443 formatter.setTofile(outputFile);
444 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
445 formatterType.setValue("plain");
446 formatter.setType(formatterType);
447 formatter.createListener(null);
448 antTask.addFormatter(formatter);
449
450 antTask.execute();
451
452 final List<String> output = readWholeFile(outputFile);
453 final int sizeOfOutputWithNoViolations = 2;
454 assertWithMessage("No violations expected")
455 .that(output)
456 .hasSize(sizeOfOutputWithNoViolations);
457 }
458
459 @Test
460 public final void testSimultaneousConfiguration() throws IOException {
461 final File file = new File(getPath(CONFIG_FILE));
462 final URL url = file.toURI().toURL();
463
464 final CheckstyleAntTask antTask = new CheckstyleAntTask();
465 antTask.setConfig(url.toString());
466 final BuildException ex = getExpectedThrowable(BuildException.class,
467 () -> antTask.setConfig("Any string value"),
468 "BuildException is expected");
469 final String expected = "Attribute 'config' has already been set";
470 assertWithMessage("Error message is unexpected")
471 .that(ex.getMessage())
472 .isEqualTo(expected);
473 }
474
475 @Test
476 public final void testSetPropertiesFile() throws IOException {
477 TestRootModuleChecker.reset();
478
479 final CheckstyleAntTask antTask = getCheckstyleAntTask(CUSTOM_ROOT_CONFIG_FILE);
480 antTask.setFile(new File(getPath(VIOLATED_INPUT)));
481 antTask.setProperties(new File(getPath(
482 "InputCheckstyleAntTaskCheckstyleAntTest.properties")));
483 antTask.execute();
484
485 assertWithMessage("Property is not set")
486 .that(TestRootModuleChecker.getProperty())
487 .isEqualTo("ignore");
488 }
489
490 @Test
491 public final void testSetPropertiesNonExistentFile() throws IOException {
492 final CheckstyleAntTask antTask = getCheckstyleAntTask();
493 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
494 antTask.setProperties(new File(getPath(NOT_EXISTING_FILE)));
495 final BuildException ex = getExpectedThrowable(BuildException.class,
496 antTask::execute,
497 "BuildException is expected");
498 assertWithMessage("Error message is unexpected")
499 .that(ex.getMessage())
500 .startsWith("Error loading Properties file");
501 }
502
503 @Test
504 public final void testXmlOutput() throws IOException {
505 final CheckstyleAntTask antTask = getCheckstyleAntTask();
506 antTask.setFile(new File(getPath(VIOLATED_INPUT)));
507 antTask.setFailOnViolation(false);
508 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
509 final File outputFile = new File("target/log.xml");
510 formatter.setTofile(outputFile);
511 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
512 formatterType.setValue("xml");
513 formatter.setType(formatterType);
514 antTask.addFormatter(formatter);
515 antTask.execute();
516
517 final List<String> expected = readWholeFile(
518 new File(getPath("ExpectedCheckstyleAntTaskXmlOutput.xml")));
519 final List<String> actual = readWholeFile(outputFile);
520 for (int i = 0; i < expected.size(); i++) {
521 final String line = expected.get(i);
522 if (!line.startsWith("<checkstyle version") && !line.startsWith("<file")) {
523 assertWithMessage("Content of file with violations differs from expected")
524 .that(actual.get(i))
525 .isEqualTo(line);
526 }
527 }
528 }
529
530 @Test
531 public final void testSarifOutput() throws IOException {
532 final CheckstyleAntTask antTask = getCheckstyleAntTask();
533 antTask.setFile(new File(getPath(VIOLATED_INPUT)));
534 antTask.setFailOnViolation(false);
535 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
536 final File outputFile = new File("target/log.sarif");
537 formatter.setTofile(outputFile);
538 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
539 formatterType.setValue("sarif");
540 formatter.setType(formatterType);
541 antTask.addFormatter(formatter);
542 antTask.execute();
543
544 final List<String> expected = readWholeFile(
545 new File(getPath("ExpectedCheckstyleAntTaskSarifOutput.sarif")));
546 final List<String> actual = readWholeFile(outputFile);
547 for (int lineNumber = 0; lineNumber < expected.size(); lineNumber++) {
548 final String line = expected.get(lineNumber);
549 final StandardSubjectBuilder assertWithMessage =
550 assertWithMessage("Content of file with violations differs from expected");
551 if (line.trim().startsWith("\"uri\"")) {
552 final String expectedPathEnd = line.split("\\*\\*")[1];
553
554 final String actualLine = actual.get(lineNumber).replaceAll("\\\\", "/");
555 assertWithMessage
556 .that(actualLine)
557 .endsWith(expectedPathEnd);
558 }
559 else {
560 assertWithMessage
561 .that(actual.get(lineNumber))
562 .isEqualTo(line);
563 }
564 }
565 }
566
567 @Test
568 public final void testCreateListenerException() throws IOException {
569 final CheckstyleAntTask antTask = getCheckstyleAntTask();
570 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
571 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
572 final File outputFile = new File("target/");
573 formatter.setTofile(outputFile);
574 antTask.addFormatter(formatter);
575 final BuildException ex = getExpectedThrowable(BuildException.class,
576 antTask::execute,
577 "BuildException is expected");
578 assertWithMessage("Error message is unexpected")
579 .that(ex.getMessage())
580 .startsWith("Unable to create listeners: formatters");
581 }
582
583 @Test
584 public final void testCreateListenerExceptionWithXmlLogger() throws IOException {
585 final CheckstyleAntTask antTask = getCheckstyleAntTask();
586 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
587 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
588 final File outputFile = new File("target/");
589 formatter.setTofile(outputFile);
590 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
591 formatterType.setValue("xml");
592 formatter.setType(formatterType);
593 antTask.addFormatter(formatter);
594 final BuildException ex = getExpectedThrowable(BuildException.class,
595 antTask::execute,
596 "BuildException is expected");
597 assertWithMessage("Error message is unexpected")
598 .that(ex.getMessage())
599 .startsWith("Unable to create listeners: formatters");
600 }
601
602 @Test
603 public final void testCreateListenerExceptionWithSarifLogger() throws IOException {
604 final CheckstyleAntTask antTask = getCheckstyleAntTask();
605 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
606 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
607 final File outputFile = new File("target/");
608 formatter.setTofile(outputFile);
609 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
610 formatterType.setValue("sarif");
611 formatter.setType(formatterType);
612 antTask.addFormatter(formatter);
613 final BuildException ex = getExpectedThrowable(BuildException.class,
614 antTask::execute,
615 "BuildException is expected");
616 assertWithMessage("Error message is unexpected")
617 .that(ex.getMessage())
618 .startsWith("Unable to create listeners: formatters");
619 }
620
621 @Test
622 public void testSetInvalidType() {
623 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
624 final BuildException ex = getExpectedThrowable(BuildException.class,
625 () -> formatterType.setValue("foo"),
626 "BuildException is expected");
627 assertWithMessage("Error message is unexpected")
628 .that(ex.getMessage())
629 .isEqualTo("foo is not a legal value for this attribute");
630 }
631
632 @Test
633 public void testSetFileValueByFile() throws IOException {
634 final String filename = getPath("InputCheckstyleAntTaskCheckstyleAntTest.properties");
635 final CheckstyleAntTask.Property property = new CheckstyleAntTask.Property();
636 property.setFile(new File(filename));
637 assertWithMessage("File path is unexpected")
638 .that(new File(filename).getAbsolutePath())
639 .isEqualTo(property.getValue());
640 }
641
642 @Test
643 public void testDefaultLoggerListener() throws IOException {
644 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
645 formatter.setUseFile(false);
646 assertWithMessage("Listener instance has unexpected type")
647 .that(formatter.createListener(null))
648 .isInstanceOf(DefaultLogger.class);
649 }
650
651 @Test
652 public void testDefaultLoggerListenerWithToFile() throws IOException {
653 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
654 formatter.setUseFile(false);
655 formatter.setTofile(new File("target/"));
656 assertWithMessage("Listener instance has unexpected type")
657 .that(formatter.createListener(null))
658 .isInstanceOf(DefaultLogger.class);
659 }
660
661 @Test
662 public void testXmlLoggerListener() throws IOException {
663 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
664 formatterType.setValue("xml");
665 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
666 formatter.setType(formatterType);
667 formatter.setUseFile(false);
668 assertWithMessage("Listener instance has unexpected type")
669 .that(formatter.createListener(null))
670 .isInstanceOf(XMLLogger.class);
671 }
672
673 @Test
674 public void testXmlLoggerListenerWithToFile() throws IOException {
675 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
676 formatterType.setValue("xml");
677 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
678 formatter.setType(formatterType);
679 formatter.setUseFile(false);
680 formatter.setTofile(new File("target/"));
681 assertWithMessage("Listener instance has unexpected type")
682 .that(formatter.createListener(null))
683 .isInstanceOf(XMLLogger.class);
684 }
685
686 @Test
687 public void testDefaultLoggerWithNullToFile() throws IOException {
688 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
689 formatter.setTofile(null);
690 assertWithMessage("Listener instance has unexpected type")
691 .that(formatter.createListener(null))
692 .isInstanceOf(DefaultLogger.class);
693 }
694
695 @Test
696 public void testXmlLoggerWithNullToFile() throws IOException {
697 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
698 formatterType.setValue("xml");
699 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
700 formatter.setType(formatterType);
701 formatter.setTofile(null);
702 assertWithMessage("Listener instance has unexpected type")
703 .that(formatter.createListener(null))
704 .isInstanceOf(XMLLogger.class);
705 }
706
707 @Test
708 public void testSarifLoggerListener() throws IOException {
709 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
710 formatterType.setValue("sarif");
711 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
712 formatter.setType(formatterType);
713 formatter.setUseFile(false);
714 assertWithMessage("Listener instance has unexpected type")
715 .that(formatter.createListener(null))
716 .isInstanceOf(SarifLogger.class);
717 }
718
719 @Test
720 public void testSarifLoggerListenerWithToFile() throws IOException {
721 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
722 formatterType.setValue("sarif");
723 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
724 formatter.setType(formatterType);
725 formatter.setUseFile(false);
726 formatter.setTofile(new File("target/"));
727 assertWithMessage("Listener instance has unexpected type")
728 .that(formatter.createListener(null))
729 .isInstanceOf(SarifLogger.class);
730 }
731
732 @Test
733 public void testSarifLoggerWithNullToFile() throws IOException {
734 final CheckstyleAntTask.FormatterType formatterType = new CheckstyleAntTask.FormatterType();
735 formatterType.setValue("sarif");
736 final CheckstyleAntTask.Formatter formatter = new CheckstyleAntTask.Formatter();
737 formatter.setType(formatterType);
738 formatter.setTofile(null);
739 assertWithMessage("Listener instance has unexpected type")
740 .that(formatter.createListener(null))
741 .isInstanceOf(SarifLogger.class);
742 }
743
744
745
746
747 @Test
748 public void testCreateClasspath() {
749 final CheckstyleAntTask antTask = new CheckstyleAntTask();
750
751 assertWithMessage("Invalid classpath")
752 .that(antTask.createClasspath().toString())
753 .isEmpty();
754 }
755
756 @Test
757 public void testDestroyed() throws IOException {
758 TestRootModuleChecker.reset();
759
760 final CheckstyleAntTask antTask = getCheckstyleAntTask(CUSTOM_ROOT_CONFIG_FILE);
761 antTask.setFile(new File(getPath(VIOLATED_INPUT)));
762 antTask.setMaxWarnings(0);
763 antTask.execute();
764
765 assertWithMessage("Checker is not destroyed")
766 .that(TestRootModuleChecker.isDestroyed())
767 .isTrue();
768 }
769
770 @Test
771 public void testMaxWarnings() throws IOException {
772 TestRootModuleChecker.reset();
773
774 final CheckstyleAntTask antTask = getCheckstyleAntTask(CUSTOM_ROOT_CONFIG_FILE);
775 antTask.setFile(new File(getPath(VIOLATED_INPUT)));
776 antTask.setMaxWarnings(0);
777 antTask.execute();
778
779 assertWithMessage("Checker is not processed")
780 .that(TestRootModuleChecker.isProcessed())
781 .isTrue();
782 }
783
784 @Test
785 public final void testExecuteLogOutput() throws Exception {
786 final URL url = new File(getPath(CONFIG_FILE)).toURI().toURL();
787 final ResourceBundle bundle = ResourceBundle.getBundle(
788 Definitions.CHECKSTYLE_BUNDLE, Locale.ROOT);
789 final String auditStartedMessage = bundle.getString(DefaultLogger.AUDIT_STARTED_MESSAGE);
790 final String auditFinishedMessage = bundle.getString(DefaultLogger.AUDIT_FINISHED_MESSAGE);
791
792 final List<MessageLevelPair> expectedList = Arrays.asList(
793 new MessageLevelPair("checkstyle version .*", Project.MSG_VERBOSE),
794 new MessageLevelPair("Adding standalone file for audit", Project.MSG_VERBOSE),
795 new MessageLevelPair("To locate the files took \\d+ ms.", Project.MSG_VERBOSE),
796 new MessageLevelPair("Running Checkstyle on 1 files", Project.MSG_INFO),
797 new MessageLevelPair("Using configuration file:.*", Project.MSG_VERBOSE),
798 new MessageLevelPair(auditStartedMessage, Project.MSG_DEBUG),
799 new MessageLevelPair(auditFinishedMessage, Project.MSG_DEBUG),
800 new MessageLevelPair("To process the files took \\d+ ms.", Project.MSG_VERBOSE),
801 new MessageLevelPair("Total execution took \\d+ ms.", Project.MSG_VERBOSE)
802 );
803
804 final CheckstyleAntTaskLogStub antTask = new CheckstyleAntTaskLogStub();
805 antTask.setProject(new Project());
806 antTask.setConfig(url.toString());
807 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
808
809 antTask.execute();
810
811 final List<MessageLevelPair> loggedMessages = antTask.getLoggedMessages();
812
813 assertWithMessage("Amount of log messages is unexpected")
814 .that(loggedMessages)
815 .hasSize(expectedList.size());
816
817 for (int i = 0; i < expectedList.size(); i++) {
818 final MessageLevelPair expected = expectedList.get(i);
819 final MessageLevelPair actual = loggedMessages.get(i);
820 assertWithMessage("Log messages should match")
821 .that(actual.getMsg())
822 .matches(expected.getMsg());
823 assertWithMessage("Log levels should be equal")
824 .that(actual.getLevel())
825 .isEqualTo(expected.getLevel());
826 }
827 }
828
829 @Test
830 public void testCheckerException() throws IOException {
831 final CheckstyleAntTask antTask = new CheckstyleAntTaskStub();
832 antTask.setConfig(getPath(CONFIG_FILE));
833 antTask.setProject(new Project());
834 antTask.setFile(new File(""));
835 final BuildException ex = getExpectedThrowable(BuildException.class,
836 antTask::execute,
837 "BuildException is expected");
838 assertWithMessage("Error message is unexpected")
839 .that(ex)
840 .hasMessageThat()
841 .startsWith("Unable to process files:");
842 }
843
844 @Test
845 public void testLoggedTime() throws IOException {
846 final CheckstyleAntTaskLogStub antTask = new CheckstyleAntTaskLogStub();
847 antTask.setConfig(getPath(CONFIG_FILE));
848 antTask.setProject(new Project());
849 antTask.setFile(new File(getPath(FLAWLESS_INPUT)));
850 final long startTime = System.currentTimeMillis();
851 antTask.execute();
852 final long endTime = System.currentTimeMillis();
853 final long testingTime = endTime - startTime;
854 final List<MessageLevelPair> loggedMessages = antTask.getLoggedMessages();
855
856 assertLoggedTime(loggedMessages, testingTime, "Total execution");
857 assertLoggedTime(loggedMessages, testingTime, "To locate the files");
858 assertLoggedTime(loggedMessages, testingTime, "To process the files");
859 }
860
861 private static void assertLoggedTime(List<MessageLevelPair> loggedMessages,
862 long testingTime, String expectedMsg) {
863
864 final Optional<MessageLevelPair> optionalMessageLevelPair = loggedMessages.stream()
865 .filter(msg -> msg.getMsg().startsWith(expectedMsg))
866 .findFirst();
867
868 assertWithMessage("Message should be present.")
869 .that(optionalMessageLevelPair.isPresent())
870 .isTrue();
871
872 final long actualTime = getNumberFromLine(optionalMessageLevelPair.orElseThrow().getMsg());
873
874 assertWithMessage("Logged time in '" + expectedMsg + "' "
875 + "must be less than the testing time")
876 .that(actualTime)
877 .isAtMost(testingTime);
878 }
879
880 private static List<String> readWholeFile(File outputFile) throws IOException {
881 return Files.readAllLines(outputFile.toPath(), StandardCharsets.UTF_8);
882 }
883
884 private static long getNumberFromLine(String line) {
885 final Matcher matcher = Pattern.compile("(\\d+)").matcher(line);
886 matcher.find();
887 return Long.parseLong(matcher.group(1));
888 }
889
890 }