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;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23
24 import java.io.IOException;
25 import java.io.PrintWriter;
26 import java.util.List;
27
28 import org.junit.jupiter.api.Test;
29
30 import com.puppycrawl.tools.checkstyle.AbstractAutomaticBean.OutputStreamOptions;
31 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
32 import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
33 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
34 import com.puppycrawl.tools.checkstyle.api.Violation;
35 import com.puppycrawl.tools.checkstyle.internal.utils.CloseAndFlushTestByteArrayOutputStream;
36 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
37
38
39
40
41
42 public class XMLLoggerTest extends AbstractXmlTestSupport {
43
44
45
46
47
48
49 private final CloseAndFlushTestByteArrayOutputStream outStream =
50 new CloseAndFlushTestByteArrayOutputStream();
51
52 @Override
53 protected String getPackageLocation() {
54 return "com/puppycrawl/tools/checkstyle/xmllogger";
55 }
56
57 @Test
58 public void testEncode()
59 throws IOException {
60 final XMLLogger test = new XMLLogger(outStream, OutputStreamOptions.NONE);
61 assertWithMessage("should be able to create XMLLogger without issue")
62 .that(test)
63 .isNotNull();
64 final String[][] encodings = {
65 {"<", "<"},
66 {">", ">"},
67 {"'", "'"},
68 {"\"", """},
69 {"&", "&"},
70 {"<", "&lt;"},
71 {"abc;", "abc;"},
72 {"�", "&#0;"},
73 {"�", "&#0"},
74 {"�", "&#X0;"},
75 {"\u0001", "#x1;"},
76 {"\u0080", "#x80;"},
77 };
78 for (String[] encoding : encodings) {
79 final String encoded = XMLLogger.encode(encoding[0]);
80 assertWithMessage("\"" + encoding[0] + "\"")
81 .that(encoded)
82 .isEqualTo(encoding[1]);
83 }
84 outStream.close();
85 }
86
87 @Test
88 public void testIsReference()
89 throws IOException {
90 final XMLLogger test = new XMLLogger(outStream, OutputStreamOptions.NONE);
91 assertWithMessage("should be able to create XMLLogger without issue")
92 .that(test)
93 .isNotNull();
94 final String[] references = {
95 "�",
96 "�",
97 "<",
98 ">",
99 "'",
100 """,
101 "&",
102 };
103 for (String reference : references) {
104 assertWithMessage("reference: " + reference)
105 .that(XMLLogger.isReference(reference))
106 .isTrue();
107 }
108 final String[] noReferences = {
109 "&",
110 "&;",
111 "&#;",
112 "&#a;",
113 "�",
114 "&#x;",
115 "&#xg;",
116 "ramp;",
117 "ref",
118 };
119 for (String noReference : noReferences) {
120 assertWithMessage("no reference: " + noReference)
121 .that(XMLLogger.isReference(noReference))
122 .isFalse();
123 }
124
125 outStream.close();
126 }
127
128 @Test
129 public void testCloseStream()
130 throws Exception {
131 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
132 logger.auditStarted(null);
133 logger.auditFinished(null);
134
135 assertWithMessage("Invalid close count")
136 .that(outStream.getCloseCount())
137 .isEqualTo(1);
138
139 verifyXml(getPath("ExpectedXMLLoggerEmpty.xml"), outStream);
140 }
141
142 @Test
143 public void testNoCloseStream()
144 throws Exception {
145 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.NONE);
146 logger.auditStarted(null);
147 logger.auditFinished(null);
148
149 assertWithMessage("Invalid close count")
150 .that(outStream.getCloseCount())
151 .isEqualTo(0);
152
153 outStream.close();
154 verifyXml(getPath("ExpectedXMLLoggerEmpty.xml"), outStream);
155 }
156
157 @Test
158 public void testFileStarted()
159 throws Exception {
160 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
161 logger.auditStarted(null);
162 final AuditEvent ev = new AuditEvent(this, "Test.java");
163 logger.fileStarted(ev);
164 logger.fileFinished(ev);
165 logger.auditFinished(null);
166 verifyXml(getPath("ExpectedXMLLogger.xml"), outStream);
167 }
168
169 @Test
170 public void testFileFinished()
171 throws Exception {
172 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
173 logger.auditStarted(null);
174 final AuditEvent ev = new AuditEvent(this, "Test.java");
175 logger.fileFinished(ev);
176 logger.auditFinished(null);
177 verifyXml(getPath("ExpectedXMLLogger.xml"), outStream);
178 }
179
180 @Test
181 public void testAddError() throws Exception {
182 verifyWithInlineConfigParserAndXmlLogger("InputXMLLoggerAddError.java",
183 "ExpectedXMLLoggerAddError.xml");
184 }
185
186 @Test
187 public void testAddErrorWithNullFileName() throws Exception {
188 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
189 logger.auditStarted(null);
190 final Violation violation =
191 new Violation(1, 1,
192 "messages.properties", "key", null, SeverityLevel.ERROR, null,
193 getClass(), null);
194 final AuditEvent ev = new AuditEvent(this, null, violation);
195 logger.addError(ev);
196 logger.auditFinished(null);
197 verifyXml(getPath("ExpectedXMLLoggerErrorNullFileName.xml"), outStream,
198 violation.getViolation());
199 }
200
201 @Test
202 public void testAddErrorModuleId() throws Exception {
203 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
204 logger.auditStarted(null);
205 final Violation violation =
206 new Violation(1, 1,
207 "messages.properties", "key", null, SeverityLevel.ERROR, "<i></i>-->",
208 getClass(), null);
209 final AuditEvent ev = new AuditEvent(this, "Test.java", violation);
210 logger.addError(ev);
211 logger.auditFinished(null);
212 verifyXml(getPath("ExpectedXMLLoggerErrorModuleId.xml"), outStream,
213 violation.getViolation());
214 }
215
216 @Test
217 public void testAddErrorWithEncodedMessage() throws Exception {
218 final String inputFileWithConfig = "InputXMLLoggerEncodedMessage.java";
219 final String expectedXmlReport = "ExpectedXMLLoggerEncodedMessage.xml";
220 verifyWithInlineConfigParserAndXmlLogger(inputFileWithConfig, expectedXmlReport);
221 }
222
223 @Test
224 public void testAddErrorOnZeroColumns() throws Exception {
225 verifyWithInlineConfigParserAndXmlLogger("InputXMLLoggerErrorOnZeroColumn.java",
226 "ExpectedXMLLoggerErrorZeroColumn.xml");
227 }
228
229 @Test
230 public void testAddIgnored() throws Exception {
231 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
232 logger.auditStarted(null);
233 final Violation violation =
234 new Violation(1, 1,
235 "messages.properties", "key", null, SeverityLevel.IGNORE, null,
236 getClass(), null);
237 final AuditEvent ev = new AuditEvent(this, "Test.java", violation);
238 logger.addError(ev);
239 logger.auditFinished(null);
240 verifyXml(getPath("ExpectedXMLLoggerEmpty.xml"), outStream);
241 }
242
243 @Test
244 public void testAddException()
245 throws Exception {
246 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
247 logger.auditStarted(null);
248 final Violation violation =
249 new Violation(1, 1,
250 "messages.properties", null, null, null, getClass(), null);
251 final AuditEvent ev = new AuditEvent(this, "Test.java", violation);
252 logger.addException(ev, new TestException("msg", new RuntimeException("msg")));
253 logger.auditFinished(null);
254 verifyXml(getPath("ExpectedXMLLoggerException.xml"), outStream);
255 assertWithMessage("Invalid close count")
256 .that(outStream.getCloseCount())
257 .isEqualTo(1);
258 }
259
260 @Test
261 public void testAddExceptionWithNullFileName()
262 throws Exception {
263 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
264 logger.auditStarted(null);
265 final Violation violation =
266 new Violation(1, 1,
267 "messages.properties", null, null, null, getClass(), null);
268 final AuditEvent ev = new AuditEvent(this, null, violation);
269 logger.addException(ev, new TestException("msg", new RuntimeException("msg")));
270 logger.auditFinished(null);
271 verifyXml(getPath("ExpectedXMLLoggerExceptionNullFileName.xml"), outStream);
272 assertWithMessage("Invalid close count")
273 .that(outStream.getCloseCount())
274 .isEqualTo(1);
275 }
276
277 @Test
278 public void testAddExceptionAfterFileStarted()
279 throws Exception {
280 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
281 logger.auditStarted(null);
282
283 final AuditEvent fileStartedEvent = new AuditEvent(this, "Test.java");
284 logger.fileStarted(fileStartedEvent);
285
286 final Violation violation =
287 new Violation(1, 1,
288 "messages.properties", null, null, null, getClass(), null);
289 final AuditEvent ev = new AuditEvent(this, "Test.java", violation);
290 logger.addException(ev, new TestException("msg", new RuntimeException("msg")));
291
292 logger.fileFinished(ev);
293 logger.auditFinished(null);
294 verifyXml(getPath("ExpectedXMLLoggerException2.xml"), outStream);
295 assertWithMessage("Invalid close count")
296 .that(outStream.getCloseCount())
297 .isEqualTo(1);
298 }
299
300 @Test
301 public void testAddExceptionBeforeFileFinished()
302 throws Exception {
303 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
304 logger.auditStarted(null);
305 final Violation violation =
306 new Violation(1, 1,
307 "messages.properties", null, null, null, getClass(), null);
308 final AuditEvent ev = new AuditEvent(this, "Test.java", violation);
309 logger.addException(ev, new TestException("msg", new RuntimeException("msg")));
310 final AuditEvent fileFinishedEvent = new AuditEvent(this, "Test.java");
311 logger.fileFinished(fileFinishedEvent);
312 logger.auditFinished(null);
313 verifyXml(getPath("ExpectedXMLLoggerException3.xml"), outStream);
314 assertWithMessage("Invalid close count")
315 .that(outStream.getCloseCount())
316 .isEqualTo(1);
317 }
318
319 @Test
320 public void testAddExceptionBetweenFileStartedAndFinished()
321 throws Exception {
322 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
323 logger.auditStarted(null);
324 final Violation violation =
325 new Violation(1, 1,
326 "messages.properties", null, null, null, getClass(), null);
327 final AuditEvent fileStartedEvent = new AuditEvent(this, "Test.java");
328 logger.fileStarted(fileStartedEvent);
329 final AuditEvent ev = new AuditEvent(this, "Test.java", violation);
330 logger.addException(ev, new TestException("msg", new RuntimeException("msg")));
331 final AuditEvent fileFinishedEvent = new AuditEvent(this, "Test.java");
332 logger.fileFinished(fileFinishedEvent);
333 logger.auditFinished(null);
334 verifyXml(getPath("ExpectedXMLLoggerException2.xml"), outStream);
335 assertWithMessage("Invalid close count")
336 .that(outStream.getCloseCount())
337 .isEqualTo(1);
338 }
339
340 @Test
341 public void testAuditFinishedWithoutFileFinished() throws Exception {
342 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
343 logger.auditStarted(null);
344 final AuditEvent fileStartedEvent = new AuditEvent(this, "Test.java");
345 logger.fileStarted(fileStartedEvent);
346
347 final Violation violation =
348 new Violation(1, 1,
349 "messages.properties", "key", null, SeverityLevel.ERROR, null,
350 getClass(), null);
351 final AuditEvent errorEvent = new AuditEvent(this, "Test.java", violation);
352 logger.addError(errorEvent);
353
354 logger.fileFinished(errorEvent);
355 logger.auditFinished(null);
356 verifyXml(getPath("ExpectedXMLLoggerError.xml"), outStream, violation.getViolation());
357 }
358
359 @Test
360 public void testFileOpenTag()
361 throws Exception {
362 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
363 logger.auditStarted(null);
364 final AuditEvent ev = new AuditEvent(this, "Test&.java");
365 logger.fileFinished(ev);
366 logger.auditFinished(null);
367 verifyXml(getPath("ExpectedXMLLoggerSpecialName.xml"),
368 outStream, "<file name=" + "Test&.java" + ">");
369
370 }
371
372 @Test
373 public void testVerifyLogger()
374 throws Exception {
375 final String inputFileWithConfig = "InputXMLLogger.java";
376 final String xmlReport = "ExpectedXMLLoggerWithChecker.xml";
377 verifyWithInlineConfigParserAndXmlLogger(inputFileWithConfig, xmlReport);
378 }
379
380 @Test
381 public void testVerifyLoggerWithMultipleInput()
382 throws Exception {
383 final String inputFileWithConfig = "InputXMLLogger.java";
384 final String expectedXmlReport = "ExpectedXMLLoggerDuplicatedFile.xml";
385 verifyWithInlineConfigParserAndXmlLogger(
386 inputFileWithConfig,
387 expectedXmlReport,
388 List.of(inputFileWithConfig, inputFileWithConfig));
389 }
390
391 @Test
392 public void testNullOutputStreamOptions() {
393 try {
394 final XMLLogger logger = new XMLLogger(outStream,
395 (OutputStreamOptions) null);
396
397 assertWithMessage("Null instance")
398 .that(logger)
399 .isNotNull();
400 assertWithMessage("Exception was expected").fail();
401 }
402 catch (IllegalArgumentException exception) {
403 assertWithMessage("Invalid error message")
404 .that(exception.getMessage())
405 .isEqualTo("Parameter outputStreamOptions can not be null");
406 }
407 }
408
409 @Test
410 public void testFinishLocalSetup() {
411 final XMLLogger logger = new XMLLogger(outStream, OutputStreamOptions.CLOSE);
412 logger.finishLocalSetup();
413 logger.auditStarted(null);
414 logger.auditFinished(null);
415 assertWithMessage("instance should not be null")
416 .that(logger)
417 .isNotNull();
418 }
419
420
421
422
423 @Test
424 public void testCtorWithTwoParametersCloseStreamOptions() {
425 final XMLLogger logger = new XMLLogger(outStream, AutomaticBean.OutputStreamOptions.CLOSE);
426 final boolean closeStream = TestUtil.getInternalState(logger, "closeStream");
427
428 assertWithMessage("closeStream should be true")
429 .that(closeStream)
430 .isTrue();
431 }
432
433
434
435
436 @Test
437 public void testCtorWithTwoParametersNoneStreamOptions() {
438 final XMLLogger logger = new XMLLogger(outStream, AutomaticBean.OutputStreamOptions.NONE);
439 final boolean closeStream = TestUtil.getInternalState(logger, "closeStream");
440
441 assertWithMessage("closeStream should be false")
442 .that(closeStream)
443 .isFalse();
444 }
445
446 private static final class TestException extends RuntimeException {
447
448 private static final long serialVersionUID = 1L;
449
450 private TestException(String msg, Throwable cause) {
451 super(msg, cause);
452 }
453
454 @Override
455 public void printStackTrace(PrintWriter printWriter) {
456 printWriter.print("stackTrace\r\nexample");
457 }
458
459 }
460
461 }