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.utils;
21
22 import static com.google.common.truth.Truth.assertThat;
23 import static com.google.common.truth.Truth.assertWithMessage;
24 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.isUtilsClassHasPrivateConstructor;
25 import static org.junit.jupiter.api.Assertions.assertThrows;
26 import static org.mockito.Mockito.CALLS_REAL_METHODS;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.mockStatic;
29 import static org.mockito.Mockito.when;
30
31 import java.io.Closeable;
32 import java.io.File;
33 import java.io.IOException;
34 import java.lang.reflect.Constructor;
35 import java.net.URI;
36 import java.net.URISyntaxException;
37 import java.net.URL;
38 import java.nio.charset.StandardCharsets;
39 import java.util.Dictionary;
40 import java.util.Properties;
41 import java.util.regex.Pattern;
42
43 import org.apache.commons.io.IOUtils;
44 import org.junit.jupiter.api.Test;
45 import org.mockito.MockedStatic;
46
47 import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport;
48 import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
49 import com.puppycrawl.tools.checkstyle.PropertiesExpander;
50 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
51 import com.puppycrawl.tools.checkstyle.api.Configuration;
52
53 public class CommonUtilTest extends AbstractPathTestSupport {
54
55
56 private static final String PATH_DENORMALIZER = "/levelDown/.././";
57
58 @Override
59 protected String getPackageLocation() {
60 return "com/puppycrawl/tools/checkstyle/utils/commonutil";
61 }
62
63 @Test
64 public void testIsProperUtilsClass() throws ReflectiveOperationException {
65 assertWithMessage("Constructor is not private")
66 .that(isUtilsClassHasPrivateConstructor(CommonUtil.class))
67 .isTrue();
68 }
69
70
71
72
73 @Test
74 public void testLengthExpandedTabs() {
75 final String s1 = "\t";
76 assertWithMessage("Invalid expanded tabs length")
77 .that(CommonUtil.lengthExpandedTabs(s1, s1.length(), 8))
78 .isEqualTo(8);
79
80 final String s2 = " \t";
81 assertWithMessage("Invalid expanded tabs length")
82 .that(CommonUtil.lengthExpandedTabs(s2, s2.length(), 8))
83 .isEqualTo(8);
84
85 final String s3 = "\t\t";
86 assertWithMessage("Invalid expanded tabs length")
87 .that(CommonUtil.lengthExpandedTabs(s3, s3.length(), 8))
88 .isEqualTo(16);
89
90 final String s4 = " \t ";
91 assertWithMessage("Invalid expanded tabs length")
92 .that(CommonUtil.lengthExpandedTabs(s4, s4.length(), 8))
93 .isEqualTo(9);
94
95 assertWithMessage("Invalid expanded tabs length")
96 .that(CommonUtil.lengthMinusTrailingWhitespace(""))
97 .isEqualTo(0);
98 assertWithMessage("Invalid expanded tabs length")
99 .that(CommonUtil.lengthMinusTrailingWhitespace(" \t "))
100 .isEqualTo(0);
101 assertWithMessage("Invalid expanded tabs length")
102 .that(CommonUtil.lengthMinusTrailingWhitespace(" 23"))
103 .isEqualTo(3);
104 assertWithMessage("Invalid expanded tabs length")
105 .that(CommonUtil.lengthMinusTrailingWhitespace(" 23 \t "))
106 .isEqualTo(3);
107 }
108
109 @Test
110 public void testCreatePattern() {
111 assertWithMessage("invalid pattern")
112 .that(CommonUtil.createPattern("Test").pattern())
113 .isEqualTo("Test");
114 assertWithMessage("invalid pattern")
115 .that(CommonUtil.createPattern(".*Pattern.*")
116 .pattern())
117 .isEqualTo(".*Pattern.*");
118 }
119
120 @Test
121 public void testBadRegex() {
122 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> {
123 CommonUtil.createPattern("[");
124 });
125 assertWithMessage("Invalid exception message")
126 .that(ex)
127 .hasMessageThat()
128 .isEqualTo("Failed to initialise regular expression [");
129 }
130
131 @Test
132 public void testBadRegex2() {
133 final IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> {
134 CommonUtil.createPattern("[", Pattern.MULTILINE);
135 });
136 assertWithMessage("Invalid exception message")
137 .that(ex)
138 .hasMessageThat()
139 .isEqualTo("Failed to initialise regular expression [");
140 }
141
142 @Test
143 public void testFileExtensions() {
144 final String[] fileExtensions = {"java"};
145 final File pdfFile = new File("file.pdf");
146 assertWithMessage("Invalid file extension")
147 .that(CommonUtil.matchesFileExtension(pdfFile, fileExtensions))
148 .isFalse();
149 assertWithMessage("Invalid file extension")
150 .that(CommonUtil.matchesFileExtension(pdfFile))
151 .isTrue();
152 assertWithMessage("Invalid file extension")
153 .that(CommonUtil.matchesFileExtension(pdfFile, (String[]) null))
154 .isTrue();
155 final File javaFile = new File("file.java");
156 assertWithMessage("Invalid file extension")
157 .that(CommonUtil.matchesFileExtension(javaFile, fileExtensions))
158 .isTrue();
159 final File invalidJavaFile = new File("file,java");
160 assertWithMessage("Invalid file extension")
161 .that(CommonUtil.matchesFileExtension(invalidJavaFile, fileExtensions))
162 .isFalse();
163 final File emptyExtensionFile = new File("file.");
164 assertWithMessage("Invalid file extension")
165 .that(CommonUtil.matchesFileExtension(emptyExtensionFile, ""))
166 .isTrue();
167 assertWithMessage("Invalid file extension")
168 .that(CommonUtil.matchesFileExtension(pdfFile, ".noMatch"))
169 .isFalse();
170 assertWithMessage("Invalid file extension")
171 .that(CommonUtil.matchesFileExtension(pdfFile, ".pdf"))
172 .isTrue();
173 }
174
175 @Test
176 public void testHasWhitespaceBefore() {
177 assertWithMessage("Invalid result")
178 .that(CommonUtil.hasWhitespaceBefore(0, "a"))
179 .isTrue();
180 assertWithMessage("Invalid result")
181 .that(CommonUtil.hasWhitespaceBefore(4, " a"))
182 .isTrue();
183 assertWithMessage("Invalid result")
184 .that(CommonUtil.hasWhitespaceBefore(5, " a"))
185 .isFalse();
186 }
187
188 @Test
189 public void testBaseClassNameForCanonicalName() {
190 assertWithMessage("Invalid base class name")
191 .that(CommonUtil.baseClassName("java.util.List"))
192 .isEqualTo("List");
193 }
194
195 @Test
196 public void testBaseClassNameForSimpleName() {
197 assertWithMessage("Invalid base class name")
198 .that(CommonUtil.baseClassName("Set"))
199 .isEqualTo("Set");
200 }
201
202 @Test
203 public void testRelativeNormalizedPath() {
204 final String relativePath = CommonUtil.relativizePath("/home", "/home/test");
205
206 assertWithMessage("Invalid relative path")
207 .that(relativePath)
208 .isEqualTo("test");
209 }
210
211 @Test
212 public void testRelativeNormalizedPathWithNullBaseDirectory() {
213 final String relativePath = CommonUtil.relativizePath(null, "/tmp");
214
215 assertWithMessage("Invalid relative path")
216 .that(relativePath)
217 .isEqualTo("/tmp");
218 }
219
220 @Test
221 public void testRelativeNormalizedPathWithDenormalizedBaseDirectory() throws IOException {
222 final String sampleAbsolutePath = new File("src/main/java").getCanonicalPath();
223 final String absoluteFilePath = sampleAbsolutePath + "/SampleFile.java";
224 final String basePath = sampleAbsolutePath + PATH_DENORMALIZER;
225
226 final String relativePath = CommonUtil.relativizePath(basePath,
227 absoluteFilePath);
228
229 assertWithMessage("Invalid relative path")
230 .that(relativePath)
231 .isEqualTo("SampleFile.java");
232 }
233
234 @Test
235 public void testPattern() {
236 final boolean result = CommonUtil.isPatternValid("someValidPattern");
237 assertWithMessage("Should return true when pattern is valid")
238 .that(result)
239 .isTrue();
240 }
241
242 @Test
243 public void testInvalidPattern() {
244 final boolean result = CommonUtil.isPatternValid("some[invalidPattern");
245 assertWithMessage("Should return false when pattern is invalid")
246 .that(result)
247 .isFalse();
248 }
249
250 @Test
251 public void testGetExistingConstructor() throws NoSuchMethodException {
252 final Constructor<?> constructor = CommonUtil.getConstructor(String.class, String.class);
253
254 assertWithMessage("Invalid constructor")
255 .that(constructor)
256 .isEqualTo(String.class.getConstructor(String.class));
257 }
258
259 @Test
260 public void testGetNonExistentConstructor() {
261 final IllegalStateException ex = assertThrows(IllegalStateException.class, () -> {
262 CommonUtil.getConstructor(Math.class);
263 });
264 assertWithMessage("Invalid exception cause")
265 .that(ex)
266 .hasCauseThat()
267 .isInstanceOf(NoSuchMethodException.class);
268 }
269
270 @Test
271 public void testInvokeConstructor() throws NoSuchMethodException {
272 final Constructor<String> constructor = String.class.getConstructor(String.class);
273
274 final String constructedString = CommonUtil.invokeConstructor(constructor, "string");
275
276 assertWithMessage("Invalid construction result")
277 .that(constructedString)
278 .isEqualTo("string");
279 }
280
281 @SuppressWarnings("rawtypes")
282 @Test
283 public void testInvokeConstructorThatFails() throws NoSuchMethodException {
284 final Constructor<Dictionary> constructor = Dictionary.class.getConstructor();
285 final IllegalStateException ex = assertThrows(IllegalStateException.class, () -> {
286 CommonUtil.invokeConstructor(constructor);
287 });
288 assertWithMessage("Invalid exception cause")
289 .that(ex)
290 .hasCauseThat()
291 .isInstanceOf(InstantiationException.class);
292 }
293
294 @Test
295 public void testClose() {
296 final TestCloseable closeable = new TestCloseable();
297
298 CommonUtil.close(null);
299 CommonUtil.close(closeable);
300
301 assertWithMessage("Should be closed")
302 .that(closeable.closed)
303 .isTrue();
304 }
305
306 @Test
307 public void testCloseWithException() {
308 final IllegalStateException ex = assertThrows(IllegalStateException.class, () -> {
309 CommonUtil.close(() -> {
310 throw new IOException("Test IOException");
311 });
312 });
313 assertWithMessage("Invalid exception message")
314 .that(ex)
315 .hasMessageThat()
316 .isEqualTo("Cannot close the stream");
317 }
318
319 @Test
320 public void testFillTemplateWithStringsByRegexp() {
321 assertWithMessage("invalid result")
322 .that(CommonUtil.fillTemplateWithStringsByRegexp("template",
323 "lineToPlaceInTemplate", Pattern.compile("NO MATCH")))
324 .isEqualTo("template");
325 assertWithMessage("invalid result")
326 .that(CommonUtil.fillTemplateWithStringsByRegexp("before $0 after", "word",
327 Pattern.compile("\\w+")))
328 .isEqualTo("before word after");
329 assertWithMessage("invalid result")
330 .that(CommonUtil.fillTemplateWithStringsByRegexp("before $0 after1 $1 after2 $2 after3",
331 "word 123", Pattern.compile("(\\w+) (\\d+)")))
332 .isEqualTo("before word 123 after1 word after2 123 after3");
333 }
334
335 @Test
336 public void testGetFileNameWithoutExtension() {
337 assertWithMessage("invalid result")
338 .that(CommonUtil.getFileNameWithoutExtension("filename"))
339 .isEqualTo("filename");
340 assertWithMessage("invalid result")
341 .that(CommonUtil.getFileNameWithoutExtension("filename.extension"))
342 .isEqualTo("filename");
343 assertWithMessage("invalid result")
344 .that(CommonUtil.getFileNameWithoutExtension("filename.subext.extension"))
345 .isEqualTo("filename.subext");
346 }
347
348 @Test
349 public void testGetFileExtension() {
350 assertWithMessage("Invalid extension")
351 .that(CommonUtil.getFileExtension("filename"))
352 .isEqualTo("");
353 assertWithMessage("Invalid extension")
354 .that(CommonUtil.getFileExtension("filename.extension"))
355 .isEqualTo("extension");
356 assertWithMessage("Invalid extension")
357 .that(CommonUtil.getFileExtension("filename.subext.extension"))
358 .isEqualTo("extension");
359 }
360
361 @Test
362 public void testIsIdentifier() {
363 assertWithMessage("Should return true when valid identifier is passed")
364 .that(CommonUtil.isIdentifier("aValidIdentifier"))
365 .isTrue();
366 }
367
368 @Test
369 public void testIsIdentifierEmptyString() {
370 assertWithMessage("Should return false when empty string is passed")
371 .that(CommonUtil.isIdentifier(""))
372 .isFalse();
373 }
374
375 @Test
376 public void testIsIdentifierInvalidFirstSymbol() {
377 assertWithMessage("Should return false when invalid identifier is passed")
378 .that(CommonUtil.isIdentifier("1InvalidIdentifier"))
379 .isFalse();
380 }
381
382 @Test
383 public void testIsIdentifierInvalidSymbols() {
384 assertWithMessage("Should return false when invalid identifier is passed")
385 .that(CommonUtil.isIdentifier("invalid#Identifier"))
386 .isFalse();
387 }
388
389 @Test
390 public void testIsName() {
391 assertWithMessage("Should return true when valid name is passed")
392 .that(CommonUtil.isName("a.valid.Nam3"))
393 .isTrue();
394 }
395
396 @Test
397 public void testIsNameEmptyString() {
398 assertWithMessage("Should return false when empty string is passed")
399 .that(CommonUtil.isName(""))
400 .isFalse();
401 }
402
403 @Test
404 public void testIsNameInvalidFirstSymbol() {
405 assertWithMessage("Should return false when invalid name is passed")
406 .that(CommonUtil.isName("1.invalid.name"))
407 .isFalse();
408 }
409
410 @Test
411 public void testIsNameEmptyPart() {
412 assertWithMessage("Should return false when name has empty part")
413 .that(CommonUtil.isName("invalid..name"))
414 .isFalse();
415 }
416
417 @Test
418 public void testIsNameEmptyLastPart() {
419 assertWithMessage("Should return false when name has empty part")
420 .that(CommonUtil.isName("invalid.name."))
421 .isFalse();
422 }
423
424 @Test
425 public void testIsNameInvalidSymbol() {
426 assertWithMessage("Should return false when invalid name is passed")
427 .that(CommonUtil.isName("invalid.name#42"))
428 .isFalse();
429 }
430
431 @Test
432 public void testIsBlank() {
433 assertWithMessage("Should return false when string is not empty")
434 .that(CommonUtil.isBlank("string"))
435 .isFalse();
436 }
437
438 @Test
439 public void testIsBlankAheadWhitespace() {
440 assertWithMessage("Should return false when string is not empty")
441 .that(CommonUtil.isBlank(" string"))
442 .isFalse();
443 }
444
445 @Test
446 public void testIsBlankBehindWhitespace() {
447 assertWithMessage("Should return false when string is not empty")
448 .that(CommonUtil.isBlank("string "))
449 .isFalse();
450 }
451
452 @Test
453 public void testIsBlankWithWhitespacesAround() {
454 assertWithMessage("Should return false when string is not empty")
455 .that(CommonUtil.isBlank(" string "))
456 .isFalse();
457 }
458
459 @Test
460 public void testIsBlankWhitespaceInside() {
461 assertWithMessage("Should return false when string is not empty")
462 .that(CommonUtil.isBlank("str ing"))
463 .isFalse();
464 }
465
466 @Test
467 public void testIsBlankNullString() {
468 assertWithMessage("Should return true when string is null")
469 .that(CommonUtil.isBlank(null))
470 .isTrue();
471 }
472
473 @Test
474 public void testIsBlankWithEmptyString() {
475 assertWithMessage("Should return true when string is empty")
476 .that(CommonUtil.isBlank(""))
477 .isTrue();
478 }
479
480 @Test
481 public void testIsBlankWithWhitespacesOnly() {
482 assertWithMessage("Should return true when string contains only spaces")
483 .that(CommonUtil.isBlank(" "))
484 .isTrue();
485 }
486
487 @Test
488 public void testGetUriByFilenameFindsAbsoluteResourceOnClasspath() throws Exception {
489 final String filename =
490 "/" + getPackageLocation() + "/InputCommonUtilTest_empty_checks.xml";
491 final URI uri = CommonUtil.getUriByFilename(filename);
492
493 final Properties properties = System.getProperties();
494 final Configuration config = ConfigurationLoader.loadConfiguration(uri.toASCIIString(),
495 new PropertiesExpander(properties));
496 assertWithMessage("Unexpected config name!")
497 .that(config.getName())
498 .isEqualTo("Checker");
499 }
500
501 @Test
502 public void testGetUriByFilenameFindsRelativeResourceOnClasspath() throws Exception {
503 final String filename =
504 getPackageLocation() + "/InputCommonUtilTest_empty_checks.xml";
505 final URI uri = CommonUtil.getUriByFilename(filename);
506
507 final Properties properties = System.getProperties();
508 final Configuration config = ConfigurationLoader.loadConfiguration(uri.toASCIIString(),
509 new PropertiesExpander(properties));
510 assertWithMessage("Unexpected config name!")
511 .that(config.getName())
512 .isEqualTo("Checker");
513 }
514
515
516
517
518
519
520
521
522 @Test
523 public void testGetUriByFilenameFindsResourceRelativeToRootClasspath() throws Exception {
524 final String filename =
525 getPackageLocation() + "/InputCommonUtilTest_resource.txt";
526 final URI uri = CommonUtil.getUriByFilename(filename);
527 assertWithMessage("URI is null for: " + filename)
528 .that(uri)
529 .isNotNull();
530 final String uriRelativeToPackage =
531 "com/puppycrawl/tools/checkstyle/utils/"
532 + getPackageLocation() + "/InputCommonUtilTest_resource.txt";
533 assertWithMessage("URI is relative to package " + uriRelativeToPackage)
534 .that(uri.toASCIIString())
535 .doesNotContain(uriRelativeToPackage);
536 final String content = IOUtils.toString(uri.toURL(), StandardCharsets.UTF_8);
537 assertWithMessage("Content mismatches for: " + uri.toASCIIString())
538 .that(content)
539 .startsWith("good");
540 }
541
542 @Test
543 public void testGetUriByFilenameClasspathPrefixLoadConfig() throws Exception {
544 final String filename = CommonUtil.CLASSPATH_URL_PROTOCOL
545 + getPackageLocation() + "/InputCommonUtilTestWithChecks.xml";
546 final URI uri = CommonUtil.getUriByFilename(filename);
547
548 final Properties properties = System.getProperties();
549 final Configuration config = ConfigurationLoader.loadConfiguration(uri.toASCIIString(),
550 new PropertiesExpander(properties));
551 assertWithMessage("Unexpected config name!")
552 .that(config.getName())
553 .isEqualTo("Checker");
554 }
555
556 @Test
557 public void testGetUriByFilenameFindsRelativeResourceOnClasspathPrefix() throws Exception {
558 final String filename = CommonUtil.CLASSPATH_URL_PROTOCOL
559 + getPackageLocation() + "/InputCommonUtilTest_empty_checks.xml";
560 final URI uri = CommonUtil.getUriByFilename(filename);
561
562 final Properties properties = System.getProperties();
563 final Configuration config = ConfigurationLoader.loadConfiguration(uri.toASCIIString(),
564 new PropertiesExpander(properties));
565 assertWithMessage("Unexpected config name!")
566 .that(config.getName())
567 .isEqualTo("Checker");
568 }
569
570 @Test
571 public void testIsCodePointWhitespace() {
572 final int[] codePoints = " 123".codePoints().toArray();
573 assertThat(CommonUtil.isCodePointWhitespace(codePoints, 0))
574 .isTrue();
575 assertThat(CommonUtil.isCodePointWhitespace(codePoints, 1))
576 .isFalse();
577 }
578
579 @Test
580 public void testLoadSuppressionsUriSyntaxException() throws Exception {
581 final URL configUrl = mock();
582 when(configUrl.toURI()).thenThrow(URISyntaxException.class);
583 try (MockedStatic<CommonUtil> utilities =
584 mockStatic(CommonUtil.class, CALLS_REAL_METHODS)) {
585 final String fileName = "/suppressions_none.xml";
586 utilities.when(() -> CommonUtil.getCheckstyleResource(fileName))
587 .thenReturn(configUrl);
588
589 final CheckstyleException ex = assertThrows(CheckstyleException.class, () -> {
590 CommonUtil.getUriByFilename(fileName);
591 });
592 assertWithMessage("Invalid exception cause")
593 .that(ex)
594 .hasCauseThat()
595 .isInstanceOf(URISyntaxException.class);
596 assertWithMessage("Invalid exception message")
597 .that(ex)
598 .hasMessageThat()
599 .isEqualTo("Unable to find: " + fileName);
600 }
601 }
602
603 private static final class TestCloseable implements Closeable {
604
605 private boolean closed;
606
607 @Override
608 public void close() {
609 closed = true;
610 }
611
612 }
613
614 }