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 import static org.junit.jupiter.api.Assertions.assertThrows;
24 import static org.junit.jupiter.api.Assumptions.assumeFalse;
25
26 import java.io.ByteArrayOutputStream;
27 import java.io.IOException;
28 import java.io.OutputStream;
29 import java.nio.charset.StandardCharsets;
30 import java.text.MessageFormat;
31 import java.util.Arrays;
32 import java.util.Locale;
33 import java.util.ResourceBundle;
34
35 import org.junit.jupiter.api.AfterEach;
36 import org.junit.jupiter.api.Test;
37
38 import com.puppycrawl.tools.checkstyle.AbstractAutomaticBean.OutputStreamOptions;
39 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
40 import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
41 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
42 import com.puppycrawl.tools.checkstyle.api.Violation;
43 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
44
45 public class DefaultLoggerTest extends AbstractModuleTestSupport {
46
47 private static final Locale DEFAULT_LOCALE = Locale.ENGLISH;
48
49 @Override
50 protected String getPackageLocation() {
51 return "com/puppycrawl/tools/checkstyle/defaultlogger";
52 }
53
54 @AfterEach
55 public void tearDown() {
56 ResourceBundle.clearCache();
57 }
58
59 @Test
60 public void testException() throws Exception {
61 final String inputFile = "InputDefaultLoggerTestException.java";
62 final String expectedInfoFile = "ExpectedDefaultLoggerInfoDefaultOutput.txt";
63 final String expectedErrorFile = "ExpectedDefaultLoggerErrorsTestException.txt";
64
65 final ByteArrayOutputStream infoStream = new ByteArrayOutputStream();
66 final ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
67 final DefaultLogger dl = new DefaultLogger(infoStream, OutputStreamOptions.CLOSE,
68 errorStream, OutputStreamOptions.CLOSE);
69
70 verifyWithInlineConfigParserAndDefaultLogger(
71 getNonCompilablePath(inputFile),
72 getPath(expectedInfoFile),
73 getPath(expectedErrorFile),
74 dl, infoStream, errorStream);
75 }
76
77 @Test
78 public void testSingleError() throws Exception {
79 final String inputFile = "InputDefaultLoggerTestSingleError.java";
80 final String expectedInfoFile = "ExpectedDefaultLoggerInfoDefaultOutput.txt";
81 final String expectedErrorFile = "ExpectedDefaultLoggerErrorsTestSingleError.txt";
82
83 final ByteArrayOutputStream infoStream = new ByteArrayOutputStream();
84 final ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
85 final DefaultLogger dl = new DefaultLogger(infoStream, OutputStreamOptions.CLOSE,
86 errorStream, OutputStreamOptions.CLOSE);
87
88 verifyWithInlineConfigParserAndDefaultLogger(
89 getPath(inputFile),
90 getPath(expectedInfoFile),
91 getPath(expectedErrorFile),
92 dl, infoStream, errorStream);
93 }
94
95 @Test
96 public void testMultipleErrors() throws Exception {
97 final String inputFile = "InputDefaultLoggerTestMultipleErrors.java";
98 final String expectedInfoFile = "ExpectedDefaultLoggerInfoDefaultOutput.txt";
99 final String expectedErrorFile = "ExpectedDefaultLoggerErrorsTestMultipleErrors.txt";
100
101 final ByteArrayOutputStream infoStream = new ByteArrayOutputStream();
102 final ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
103 final DefaultLogger dl = new DefaultLogger(infoStream, OutputStreamOptions.CLOSE,
104 errorStream, OutputStreamOptions.CLOSE);
105
106 verifyWithInlineConfigParserAndDefaultLogger(
107 getPath(inputFile),
108 getPath(expectedInfoFile),
109 getPath(expectedErrorFile),
110 dl, infoStream, errorStream);
111 }
112
113 @Test
114 public void testCtorWithTwoParametersCloseStreamOptions() throws Exception {
115 final String inputFile = "InputDefaultLoggerTestSingleError.java";
116 final String expectedOutputFile = "ExpectedDefaultLoggerOutputSingleError.txt";
117
118 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
119 final DefaultLogger dl = new DefaultLogger(outputStream, OutputStreamOptions.CLOSE);
120
121 verifyWithInlineConfigParserAndDefaultLogger(
122 getPath(inputFile),
123 getPath(expectedOutputFile),
124 dl, outputStream);
125 }
126
127 @Test
128 public void testCtorWithTwoParametersNoneStreamOptions() throws Exception {
129 final String inputFile = "InputDefaultLoggerTestSingleError.java";
130 final String expectedOutputFile = "ExpectedDefaultLoggerOutputSingleError.txt";
131
132 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
133 final DefaultLogger dl = new DefaultLogger(outputStream, OutputStreamOptions.NONE);
134
135 verifyWithInlineConfigParserAndDefaultLogger(
136 getPath(inputFile),
137 getPath(expectedOutputFile),
138 dl, outputStream);
139 }
140
141
142
143
144
145
146 @Test
147 public void testOldCtorWithTwoParametersCloseStreamOptions() {
148 final OutputStream infoStream = new ByteArrayOutputStream();
149 final DefaultLogger dl = new DefaultLogger(infoStream,
150 AutomaticBean.OutputStreamOptions.CLOSE);
151 final boolean closeInfo = TestUtil.getInternalState(dl, "closeInfo");
152
153 assertWithMessage("closeInfo should be true")
154 .that(closeInfo)
155 .isTrue();
156 }
157
158
159
160
161
162
163 @Test
164 public void testOldCtorWithTwoParametersNoneStreamOptions() {
165 final OutputStream infoStream = new ByteArrayOutputStream();
166 final DefaultLogger dl = new DefaultLogger(infoStream,
167 AutomaticBean.OutputStreamOptions.NONE);
168 final boolean closeInfo = TestUtil.getInternalState(dl, "closeInfo");
169
170 assertWithMessage("closeInfo should be false")
171 .that(closeInfo)
172 .isFalse();
173 }
174
175 @Test
176 public void testCtorWithNullParameter() {
177 final OutputStream infoStream = new ByteArrayOutputStream();
178 final DefaultLogger dl = new DefaultLogger(infoStream, OutputStreamOptions.CLOSE);
179 dl.addException(new AuditEvent(5000), new IllegalStateException("upsss"));
180 dl.auditFinished(new AuditEvent(6000));
181 final String output = infoStream.toString();
182 assertWithMessage("Message should contain exception info")
183 .that(output)
184 .contains("java.lang.IllegalStateException: upsss");
185 }
186
187 @Test
188 public void testNullInfoStreamOptions() {
189 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
190 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
191 () -> new DefaultLogger(outputStream, (OutputStreamOptions) null),
192 "IllegalArgumentException expected");
193 assertWithMessage("Invalid error message")
194 .that(ex)
195 .hasMessageThat()
196 .isEqualTo("Parameter infoStreamOptions can not be null");
197 }
198
199 @Test
200 public void testNullErrorStreamOptions() {
201 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
202 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class,
203 () -> {
204 final DefaultLogger defaultLogger = new DefaultLogger(outputStream,
205 OutputStreamOptions.CLOSE, outputStream, null);
206
207
208 assertWithMessage("defaultLogger should be non-null")
209 .that(defaultLogger)
210 .isNotNull();
211 },
212 "IllegalArgumentException expected");
213 assertWithMessage("Invalid error message")
214 .that(ex)
215 .hasMessageThat()
216 .isEqualTo("Parameter errorStreamOptions can not be null");
217 }
218
219 @Test
220 public void testAddError() {
221 final OutputStream infoStream = new ByteArrayOutputStream();
222 final OutputStream errorStream = new ByteArrayOutputStream();
223 final String auditStartMessage = getAuditStartMessage();
224 final String auditFinishMessage = getAuditFinishMessage();
225 final DefaultLogger dl = new DefaultLogger(infoStream,
226 OutputStreamOptions.CLOSE, errorStream,
227 OutputStreamOptions.CLOSE);
228 dl.finishLocalSetup();
229 dl.auditStarted(null);
230 dl.addError(new AuditEvent(this, "fileName", new Violation(1, 2, "bundle", "key",
231 null, null, getClass(), "customViolation")));
232 dl.auditFinished(null);
233 assertWithMessage("expected output")
234 .that(infoStream.toString())
235 .isEqualTo(auditStartMessage
236 + System.lineSeparator()
237 + auditFinishMessage
238 + System.lineSeparator());
239 assertWithMessage("expected output")
240 .that(errorStream.toString())
241 .isEqualTo("[ERROR] fileName:1:2: customViolation [DefaultLoggerTest]"
242 + System.lineSeparator());
243 }
244
245 @Test
246 public void testAddErrorModuleId() {
247 final OutputStream infoStream = new ByteArrayOutputStream();
248 final OutputStream errorStream = new ByteArrayOutputStream();
249 final String auditFinishMessage = getAuditFinishMessage();
250 final String auditStartMessage = getAuditStartMessage();
251 final DefaultLogger dl = new DefaultLogger(infoStream, OutputStreamOptions.CLOSE,
252 errorStream, OutputStreamOptions.CLOSE);
253 dl.finishLocalSetup();
254 dl.auditStarted(null);
255 dl.addError(new AuditEvent(this, "fileName", new Violation(1, 2, "bundle", "key",
256 null, "moduleId", getClass(), "customViolation")));
257 dl.auditFinished(null);
258 assertWithMessage("expected output")
259 .that(infoStream.toString())
260 .isEqualTo(auditStartMessage
261 + System.lineSeparator()
262 + auditFinishMessage
263 + System.lineSeparator());
264 assertWithMessage("expected output")
265 .that(errorStream.toString())
266 .isEqualTo("[ERROR] fileName:1:2: customViolation [moduleId]"
267 + System.lineSeparator());
268 }
269
270 @Test
271 public void testAddErrorIgnoreSeverityLevel() {
272 final OutputStream infoStream = new ByteArrayOutputStream();
273 final OutputStream errorStream = new ByteArrayOutputStream();
274 final DefaultLogger defaultLogger = new DefaultLogger(
275 infoStream, OutputStreamOptions.CLOSE,
276 errorStream, OutputStreamOptions.CLOSE);
277 defaultLogger.finishLocalSetup();
278 defaultLogger.auditStarted(null);
279 final Violation ignorableViolation = new Violation(1, 2, "bundle", "key",
280 null, SeverityLevel.IGNORE, null,
281 getClass(), "customViolation");
282 defaultLogger.addError(new AuditEvent(this, "fileName", ignorableViolation));
283 defaultLogger.auditFinished(null);
284 assertWithMessage("No violation was expected")
285 .that(errorStream.toString())
286 .isEmpty();
287 }
288
289 @Test
290 public void testFinishLocalSetup() {
291 final OutputStream infoStream = new ByteArrayOutputStream();
292 final DefaultLogger dl = new DefaultLogger(infoStream,
293 OutputStreamOptions.CLOSE);
294 dl.finishLocalSetup();
295 dl.auditStarted(null);
296 dl.auditFinished(null);
297 assertWithMessage("instance should not be null")
298 .that(dl)
299 .isNotNull();
300 }
301
302
303
304
305 @Test
306 public void testLanguageIsValid() {
307 final String language = DEFAULT_LOCALE.getLanguage();
308 assumeFalse(language.isEmpty(), "Locale not set");
309 assertWithMessage("Invalid language")
310 .that(Arrays.asList(Locale.getISOLanguages()))
311 .contains(language);
312 }
313
314
315
316
317 @Test
318 public void testCountryIsValid() {
319 final String country = DEFAULT_LOCALE.getCountry();
320 assumeFalse(country.isEmpty(), "Locale not set");
321 assertWithMessage("Invalid country")
322 .that(Arrays.asList(Locale.getISOCountries()))
323 .contains(country);
324 }
325
326 @Test
327 public void testNewCtor() throws Exception {
328 final ResourceBundle bundle = ResourceBundle.getBundle(
329 Definitions.CHECKSTYLE_BUNDLE, Locale.ENGLISH);
330 final String auditStartedMessage = bundle.getString(DefaultLogger.AUDIT_STARTED_MESSAGE);
331 final String auditFinishedMessage = bundle.getString(DefaultLogger.AUDIT_FINISHED_MESSAGE);
332 final String addExceptionMessage = new MessageFormat(bundle.getString(
333 DefaultLogger.ADD_EXCEPTION_MESSAGE), Locale.ENGLISH).format(new String[] {"myfile"}
334 );
335 final String infoOutput;
336 final String errorOutput;
337 try (MockByteArrayOutputStream infoStream = new MockByteArrayOutputStream()) {
338 try (MockByteArrayOutputStream errorStream = new MockByteArrayOutputStream()) {
339 final DefaultLogger dl = new DefaultLogger(
340 infoStream, OutputStreamOptions.CLOSE,
341 errorStream, OutputStreamOptions.CLOSE);
342 dl.auditStarted(null);
343 dl.addException(new AuditEvent(5000, "myfile"),
344 new IllegalStateException("upsss"));
345 dl.auditFinished(new AuditEvent(6000, "myfile"));
346 infoOutput = infoStream.toString(StandardCharsets.UTF_8);
347 errorOutput = errorStream.toString(StandardCharsets.UTF_8);
348
349 assertWithMessage("Info stream should be closed")
350 .that(infoStream.closedCount)
351 .isGreaterThan(0);
352 assertWithMessage("Error stream should be closed")
353 .that(errorStream.closedCount)
354 .isGreaterThan(0);
355 }
356 }
357 assertWithMessage("Violation should contain message `audit started`")
358 .that(infoOutput)
359 .contains(auditStartedMessage);
360 assertWithMessage("Violation should contain message `audit finished`")
361 .that(infoOutput)
362 .contains(auditFinishedMessage);
363 assertWithMessage("Violation should contain exception info")
364 .that(errorOutput)
365 .contains(addExceptionMessage);
366 assertWithMessage("Violation should contain exception message")
367 .that(errorOutput)
368 .contains("java.lang.IllegalStateException: upsss");
369 }
370
371 @Test
372 public void testStreamsNotClosedByLogger() throws IOException {
373 try (MockByteArrayOutputStream infoStream = new MockByteArrayOutputStream();
374 MockByteArrayOutputStream errorStream = new MockByteArrayOutputStream()) {
375 final DefaultLogger defaultLogger = new DefaultLogger(
376 infoStream, OutputStreamOptions.NONE,
377 errorStream, OutputStreamOptions.NONE);
378 defaultLogger.auditStarted(null);
379 defaultLogger.auditFinished(null);
380 assertWithMessage("Info stream should be open")
381 .that(infoStream.closedCount)
382 .isEqualTo(0);
383 assertWithMessage("Error stream should be open")
384 .that(errorStream.closedCount)
385 .isEqualTo(0);
386 }
387 }
388
389 private static LocalizedMessage getAuditStartMessageClass() {
390 return new LocalizedMessage(Definitions.CHECKSTYLE_BUNDLE,
391 DefaultLogger.class, "DefaultLogger.auditStarted");
392 }
393
394 private static LocalizedMessage getAuditFinishMessageClass() {
395 return new LocalizedMessage(Definitions.CHECKSTYLE_BUNDLE,
396 DefaultLogger.class, "DefaultLogger.auditFinished");
397 }
398
399 private static String getAuditStartMessage() {
400 final LocalizedMessage auditStartMessage = getAuditStartMessageClass();
401 return auditStartMessage.getMessage();
402 }
403
404 private static String getAuditFinishMessage() {
405 final LocalizedMessage auditFinishMessage = getAuditFinishMessageClass();
406 return auditFinishMessage.getMessage();
407 }
408
409 private static final class MockByteArrayOutputStream extends ByteArrayOutputStream {
410
411 private int closedCount;
412
413 @Override
414 public void close() throws IOException {
415 super.close();
416 ++closedCount;
417 }
418
419 }
420
421 }