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