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.Assumptions.assumeFalse;
24
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.io.OutputStream;
28 import java.nio.charset.StandardCharsets;
29 import java.text.MessageFormat;
30 import java.util.Arrays;
31 import java.util.Locale;
32 import java.util.ResourceBundle;
33
34 import org.junit.jupiter.api.AfterEach;
35 import org.junit.jupiter.api.Test;
36
37 import com.puppycrawl.tools.checkstyle.AbstractAutomaticBean.OutputStreamOptions;
38 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
39 import com.puppycrawl.tools.checkstyle.api.AutomaticBean;
40 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
41 import com.puppycrawl.tools.checkstyle.api.Violation;
42 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
43
44 public class DefaultLoggerTest extends AbstractModuleTestSupport {
45
46 private static final Locale DEFAULT_LOCALE = Locale.ENGLISH;
47
48 @Override
49 protected String getPackageLocation() {
50 return "com/puppycrawl/tools/checkstyle/defaultlogger";
51 }
52
53 @AfterEach
54 public void tearDown() {
55 ResourceBundle.clearCache();
56 }
57
58 @Test
59 public void testException() throws Exception {
60 final String inputFile = "InputDefaultLoggerTestException.java";
61 final String expectedInfoFile = "ExpectedDefaultLoggerInfoDefaultOutput.txt";
62 final String expectedErrorFile = "ExpectedDefaultLoggerErrorsTestException.txt";
63
64 final ByteArrayOutputStream infoStream = new ByteArrayOutputStream();
65 final ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
66 final DefaultLogger dl = new DefaultLogger(infoStream, OutputStreamOptions.CLOSE,
67 errorStream, OutputStreamOptions.CLOSE);
68
69 verifyWithInlineConfigParserAndDefaultLogger(
70 getNonCompilablePath(inputFile),
71 getPath(expectedInfoFile),
72 getPath(expectedErrorFile),
73 dl, infoStream, errorStream);
74 }
75
76 @Test
77 public void testSingleError() throws Exception {
78 final String inputFile = "InputDefaultLoggerTestSingleError.java";
79 final String expectedInfoFile = "ExpectedDefaultLoggerInfoDefaultOutput.txt";
80 final String expectedErrorFile = "ExpectedDefaultLoggerErrorsTestSingleError.txt";
81
82 final ByteArrayOutputStream infoStream = new ByteArrayOutputStream();
83 final ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
84 final DefaultLogger dl = new DefaultLogger(infoStream, OutputStreamOptions.CLOSE,
85 errorStream, OutputStreamOptions.CLOSE);
86
87 verifyWithInlineConfigParserAndDefaultLogger(
88 getPath(inputFile),
89 getPath(expectedInfoFile),
90 getPath(expectedErrorFile),
91 dl, infoStream, errorStream);
92 }
93
94 @Test
95 public void testMultipleErrors() throws Exception {
96 final String inputFile = "InputDefaultLoggerTestMultipleErrors.java";
97 final String expectedInfoFile = "ExpectedDefaultLoggerInfoDefaultOutput.txt";
98 final String expectedErrorFile = "ExpectedDefaultLoggerErrorsTestMultipleErrors.txt";
99
100 final ByteArrayOutputStream infoStream = new ByteArrayOutputStream();
101 final ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
102 final DefaultLogger dl = new DefaultLogger(infoStream, OutputStreamOptions.CLOSE,
103 errorStream, OutputStreamOptions.CLOSE);
104
105 verifyWithInlineConfigParserAndDefaultLogger(
106 getPath(inputFile),
107 getPath(expectedInfoFile),
108 getPath(expectedErrorFile),
109 dl, infoStream, errorStream);
110 }
111
112 @Test
113 public void testCtorWithTwoParametersCloseStreamOptions() throws Exception {
114 final String inputFile = "InputDefaultLoggerTestSingleError.java";
115 final String expectedOutputFile = "ExpectedDefaultLoggerOutputSingleError.txt";
116
117 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
118 final DefaultLogger dl = new DefaultLogger(outputStream, OutputStreamOptions.CLOSE);
119
120 verifyWithInlineConfigParserAndDefaultLogger(
121 getPath(inputFile),
122 getPath(expectedOutputFile),
123 dl, outputStream);
124 }
125
126 @Test
127 public void testCtorWithTwoParametersNoneStreamOptions() throws Exception {
128 final String inputFile = "InputDefaultLoggerTestSingleError.java";
129 final String expectedOutputFile = "ExpectedDefaultLoggerOutputSingleError.txt";
130
131 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
132 final DefaultLogger dl = new DefaultLogger(outputStream, OutputStreamOptions.NONE);
133
134 verifyWithInlineConfigParserAndDefaultLogger(
135 getPath(inputFile),
136 getPath(expectedOutputFile),
137 dl, outputStream);
138 }
139
140
141
142
143
144
145 @Test
146 public void testOldCtorWithTwoParametersCloseStreamOptions() {
147 final OutputStream infoStream = new ByteArrayOutputStream();
148 final DefaultLogger dl = new DefaultLogger(infoStream,
149 AutomaticBean.OutputStreamOptions.CLOSE);
150 final boolean closeInfo = TestUtil.getInternalState(dl, "closeInfo", Boolean.class);
151
152 assertWithMessage("closeInfo should be true")
153 .that(closeInfo)
154 .isTrue();
155 }
156
157
158
159
160
161
162 @Test
163 public void testOldCtorWithTwoParametersNoneStreamOptions() {
164 final OutputStream infoStream = new ByteArrayOutputStream();
165 final DefaultLogger dl = new DefaultLogger(infoStream,
166 AutomaticBean.OutputStreamOptions.NONE);
167 final boolean closeInfo = TestUtil.getInternalState(dl, "closeInfo", Boolean.class);
168
169 assertWithMessage("closeInfo should be false")
170 .that(closeInfo)
171 .isFalse();
172 }
173
174 @Test
175 public void testCtorWithNullParameter() {
176 final OutputStream infoStream = new ByteArrayOutputStream();
177 final DefaultLogger dl = new DefaultLogger(infoStream, OutputStreamOptions.CLOSE);
178 dl.addException(new AuditEvent(5000), new IllegalStateException("upsss"));
179 dl.auditFinished(new AuditEvent(6000));
180 final String output = infoStream.toString();
181 assertWithMessage("Message should contain exception info")
182 .that(output)
183 .contains("java.lang.IllegalStateException: upsss");
184 }
185
186 @Test
187 public void testNullInfoStreamOptions() {
188 final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
189 final IllegalArgumentException ex =
190 TestUtil.getExpectedThrowable(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 =
203 TestUtil.getExpectedThrowable(IllegalArgumentException.class, () -> {
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 }