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.mockito.Mockito.mockConstruction;
24 import static org.mockito.Mockito.when;
25
26 import java.io.File;
27 import java.nio.file.Files;
28 import java.nio.file.Path;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.List;
33 import java.util.Properties;
34
35 import org.junit.jupiter.api.Test;
36 import org.mockito.MockedConstruction;
37 import org.xml.sax.InputSource;
38 import org.xml.sax.SAXException;
39
40 import com.puppycrawl.tools.checkstyle.ConfigurationLoader.IgnoredModulesOptions;
41 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
42 import com.puppycrawl.tools.checkstyle.api.Configuration;
43 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
44
45
46
47
48 public class ConfigurationLoaderTest extends AbstractPathTestSupport {
49
50 @Override
51 protected String getPackageLocation() {
52 return "com/puppycrawl/tools/checkstyle/configurationloader";
53 }
54
55 private Configuration loadConfiguration(String name) throws Exception {
56 return loadConfiguration(name, new Properties());
57 }
58
59 private Configuration loadConfiguration(
60 String name, Properties props) throws Exception {
61 final String fName = getPath(name);
62
63 return ConfigurationLoader.loadConfiguration(fName, new PropertiesExpander(props));
64 }
65
66 private static Object getInternalLoaderInstance(PropertyResolver resolver)
67 throws Exception {
68
69 final ConfigurationLoader loader = TestUtil.instantiate(ConfigurationLoader.class,
70 resolver, false, ThreadModeSettings.SINGLE_THREAD_MODE_INSTANCE);
71
72 return TestUtil.getInternalState(loader, "saxHandler", Object.class);
73 }
74
75 private static String invokeReplacePropertiesMethod(
76 Object internalLoader, String value, String defaultValue)
77 throws ReflectiveOperationException {
78 return TestUtil.invokeMethod(internalLoader, "replaceProperties", value, defaultValue);
79 }
80
81 private static void invokeParsePropertyStringMethod(
82 Object internalLoader,
83 String value,
84 Collection<String> fragments,
85 Collection<String> propertyRefs)
86 throws ReflectiveOperationException {
87 TestUtil.invokeMethod(
88 internalLoader, "parsePropertyString", value, fragments, propertyRefs);
89 }
90
91 @Test
92 public void testReplacePropertiesNoReplace() throws Exception {
93 final String[] testValues = {"", "a", "$a", "{a",
94 "{a}", "a}", "$a}", "$", "a$b", };
95 final Properties props = initProperties();
96 final Object internalLoader = getInternalLoaderInstance(new PropertiesExpander(props));
97
98 for (String testValue : testValues) {
99 final String value = invokeReplacePropertiesMethod(internalLoader, testValue, null);
100 assertWithMessage("\"" + testValue + "\"")
101 .that(testValue)
102 .isEqualTo(value);
103 }
104 }
105
106 @Test
107 public void testReplacePropertiesSyntaxError() throws Exception {
108 final Properties props = initProperties();
109 final Object internalLoader = getInternalLoaderInstance(new PropertiesExpander(props));
110
111 try {
112 final String value = invokeReplacePropertiesMethod(internalLoader, "${a", null);
113 assertWithMessage("expected to fail, instead got: " + value).fail();
114 }
115 catch (ReflectiveOperationException exc) {
116 assertWithMessage("Invalid exception cause message")
117 .that(exc.getCause())
118 .isInstanceOf(CheckstyleException.class);
119 assertWithMessage("Invalid exception message")
120 .that(exc.getCause().getMessage())
121 .isEqualTo("Syntax error in property: ${a");
122 }
123 }
124
125 @Test
126 public void testReplacePropertiesMissingProperty() throws Exception {
127 final Properties props = initProperties();
128 final Object internalLoader = getInternalLoaderInstance(new PropertiesExpander(props));
129
130 try {
131 final String value = invokeReplacePropertiesMethod(internalLoader, "${c}", null);
132 assertWithMessage("expected to fail, instead got: " + value).fail();
133 }
134 catch (ReflectiveOperationException exc) {
135 assertWithMessage("Invalid exception cause message")
136 .that(exc.getCause())
137 .isInstanceOf(CheckstyleException.class);
138 assertWithMessage("Invalid exception message")
139 .that(exc.getCause().getMessage())
140 .isEqualTo("Property ${c} has not been set");
141 }
142 }
143
144 @Test
145 public void testReplacePropertiesReplace() throws Exception {
146 final String[][] testValues = {
147 {"${a}", "A"},
148 {"x${a}", "xA"},
149 {"${a}x", "Ax"},
150 {"${a}${b}", "AB"},
151 {"x${a}${b}", "xAB"},
152 {"${a}x${b}", "AxB"},
153 {"${a}${b}x", "ABx"},
154 {"x${a}y${b}", "xAyB"},
155 {"${a}x${b}y", "AxBy"},
156 {"x${a}${b}y", "xABy"},
157 {"x${a}y${b}z", "xAyBz"},
158 {"$$", "$"},
159 };
160 final Properties props = initProperties();
161 final Object internalLoader = getInternalLoaderInstance(new PropertiesExpander(props));
162
163 for (String[] testValue : testValues) {
164 final String value = invokeReplacePropertiesMethod(internalLoader, testValue[0], null);
165 assertWithMessage("\"" + testValue[0] + "\"")
166 .that(value)
167 .isEqualTo(testValue[1]);
168 }
169 }
170
171 @Test
172 public void testReplacePropertiesDefault() throws Exception {
173 final Properties props = new Properties();
174 final String defaultValue = "defaultValue";
175 final Object internalLoader = getInternalLoaderInstance(new PropertiesExpander(props));
176
177 final String value =
178 invokeReplacePropertiesMethod(
179 internalLoader, "${checkstyle.basedir}", defaultValue);
180
181 assertWithMessage("Invalid property value")
182 .that(value)
183 .isEqualTo(defaultValue);
184 }
185
186 @Test
187 public void testParsePropertyString() throws Exception {
188 final Properties props = initProperties();
189 final Object internalLoader = getInternalLoaderInstance(new PropertiesExpander(props));
190
191 final List<String> propertyRefs = new ArrayList<>();
192 final List<String> fragments = new ArrayList<>();
193
194 invokeParsePropertyStringMethod(internalLoader, "$", fragments, propertyRefs);
195 assertWithMessage("Fragments list has unexpected amount of items")
196 .that(fragments)
197 .hasSize(1);
198 }
199
200 private static Properties initProperties() {
201 final Properties props = new Properties();
202 props.setProperty("a", "A");
203 props.setProperty("b", "B");
204 return props;
205 }
206
207 @Test
208 public void testResourceLoadConfiguration() throws Exception {
209 final Properties props = new Properties();
210 props.setProperty("checkstyle.basedir", "basedir");
211
212
213 final DefaultConfiguration config =
214 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
215 getPath("InputConfigurationLoaderChecks.xml"), new PropertiesExpander(props));
216
217
218 final Properties attributes = new Properties();
219 attributes.setProperty("tabWidth", "4");
220 attributes.setProperty("basedir", "basedir");
221 verifyConfigNode(config, "Checker", 3, attributes);
222 }
223
224 @Test
225 public void testResourceLoadConfigurationWithMultiThreadConfiguration() throws Exception {
226 final Properties props = new Properties();
227 props.setProperty("checkstyle.basedir", "basedir");
228
229 final PropertiesExpander propertiesExpander = new PropertiesExpander(props);
230 final String configPath = getPath("InputConfigurationLoaderChecks.xml");
231 final ThreadModeSettings multiThreadModeSettings =
232 new ThreadModeSettings(4, 2);
233
234 try {
235 ConfigurationLoader.loadConfiguration(
236 configPath, propertiesExpander, multiThreadModeSettings);
237 assertWithMessage("An exception is expected").fail();
238 }
239 catch (IllegalArgumentException exc) {
240 assertWithMessage("Invalid exception message")
241 .that(exc.getMessage())
242 .isEqualTo("Multi thread mode for Checker module is not implemented");
243 }
244 }
245
246 @Test
247 public void testResourceLoadConfigurationWithSingleThreadConfiguration() throws Exception {
248 final Properties props = new Properties();
249 props.setProperty("checkstyle.basedir", "basedir");
250
251 final PropertiesExpander propertiesExpander = new PropertiesExpander(props);
252 final String configPath = getPath("InputConfigurationLoaderChecks.xml");
253 final ThreadModeSettings singleThreadModeSettings =
254 ThreadModeSettings.SINGLE_THREAD_MODE_INSTANCE;
255
256 final DefaultConfiguration config =
257 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
258 configPath, propertiesExpander, singleThreadModeSettings);
259
260 final Properties attributes = new Properties();
261 attributes.setProperty("tabWidth", "4");
262 attributes.setProperty("basedir", "basedir");
263 verifyConfigNode(config, "Checker", 3, attributes);
264 }
265
266 @Test
267 public void testEmptyConfiguration() throws Exception {
268 final DefaultConfiguration config =
269 (DefaultConfiguration) loadConfiguration("InputConfigurationLoaderEmpty.xml");
270 verifyConfigNode(config, "Checker", 0, new Properties());
271 }
272
273 @Test
274 public void testEmptyModuleResolver() throws Exception {
275 final DefaultConfiguration config =
276 (DefaultConfiguration) loadConfiguration(
277 "InputConfigurationLoaderEmpty.xml", new Properties());
278 verifyConfigNode(config, "Checker", 0, new Properties());
279 }
280
281 @Test
282 public void testMissingPropertyName() throws Exception {
283 try {
284 loadConfiguration("InputConfigurationLoaderMissingPropertyName.xml");
285 assertWithMessage("missing property name").fail();
286 }
287 catch (CheckstyleException exc) {
288 assertWithMessage("Invalid exception message: " + exc.getMessage())
289 .that(exc.getMessage())
290 .contains("\"name\"");
291 assertWithMessage("Invalid exception message: " + exc.getMessage())
292 .that(exc.getMessage())
293 .contains("\"property\"");
294 assertWithMessage("Invalid exception message: " + exc.getMessage())
295 .that(exc.getMessage())
296 .endsWith(":8:41");
297 }
298 }
299
300 @Test
301 public void testMissingPropertyNameInMethodWithBooleanParameter() throws Exception {
302 try {
303 final String fName = getPath("InputConfigurationLoaderMissingPropertyName.xml");
304 ConfigurationLoader.loadConfiguration(fName, new PropertiesExpander(new Properties()),
305 IgnoredModulesOptions.EXECUTE);
306
307 assertWithMessage("missing property name").fail();
308 }
309 catch (CheckstyleException exc) {
310 assertWithMessage("Invalid exception message: " + exc.getMessage())
311 .that(exc.getMessage())
312 .contains("\"name\"");
313 assertWithMessage("Invalid exception message: " + exc.getMessage())
314 .that(exc.getMessage())
315 .contains("\"property\"");
316 assertWithMessage("Invalid exception message: " + exc.getMessage())
317 .that(exc.getMessage())
318 .endsWith(":8:41");
319 }
320 }
321
322 @Test
323 public void testMissingPropertyValue() throws Exception {
324 try {
325 loadConfiguration("InputConfigurationLoaderMissingPropertyValue.xml");
326 assertWithMessage("missing property value").fail();
327 }
328 catch (CheckstyleException exc) {
329 assertWithMessage("Invalid exception message: " + exc.getMessage())
330 .that(exc.getMessage())
331 .contains("\"value\"");
332 assertWithMessage("Invalid exception message: " + exc.getMessage())
333 .that(exc.getMessage())
334 .contains("\"property\"");
335 assertWithMessage("Invalid exception message: " + exc.getMessage())
336 .that(exc.getMessage())
337 .endsWith(":8:43");
338 }
339 }
340
341 @Test
342 public void testMissingConfigName() throws Exception {
343 try {
344 loadConfiguration("InputConfigurationLoaderMissingConfigName.xml");
345 assertWithMessage("missing module name").fail();
346 }
347 catch (CheckstyleException exc) {
348 assertWithMessage("Invalid exception message: " + exc.getMessage())
349 .that(exc.getMessage())
350 .contains("\"name\"");
351 assertWithMessage("Invalid exception message: " + exc.getMessage())
352 .that(exc.getMessage())
353 .contains("\"module\"");
354 assertWithMessage("Invalid exception message: " + exc.getMessage())
355 .that(exc.getMessage())
356 .endsWith(":7:23");
357 }
358 }
359
360 @Test
361 public void testMissingConfigParent() throws Exception {
362 try {
363 loadConfiguration("InputConfigurationLoaderMissingConfigParent.xml");
364 assertWithMessage("missing module parent").fail();
365 }
366 catch (CheckstyleException exc) {
367 assertWithMessage("Invalid exception message: " + exc.getMessage())
368 .that(exc.getMessage())
369 .contains("\"property\"");
370 assertWithMessage("Invalid exception message: " + exc.getMessage())
371 .that(exc.getMessage())
372 .contains("\"module\"");
373 assertWithMessage("Invalid exception message: " + exc.getMessage())
374 .that(exc.getMessage())
375 .endsWith(":8:38");
376 }
377 }
378
379 @Test
380 public void testCheckstyleChecks() throws Exception {
381 final Properties props = new Properties();
382 props.setProperty("checkstyle.basedir", "basedir");
383
384 final DefaultConfiguration config =
385 (DefaultConfiguration) loadConfiguration(
386 "InputConfigurationLoaderChecks.xml", props);
387
388
389 final Properties atts = new Properties();
390 atts.setProperty("tabWidth", "4");
391 atts.setProperty("basedir", "basedir");
392 verifyConfigNode(config, "Checker", 3, atts);
393
394
395 final Configuration[] children = config.getChildren();
396 atts.clear();
397 verifyConfigNode(
398 (DefaultConfiguration) children[1], "JavadocPackage", 0, atts);
399 verifyConfigNode(
400 (DefaultConfiguration) children[2], "Translation", 0, atts);
401 atts.setProperty("testName", "testValue");
402 verifyConfigNode(
403 (DefaultConfiguration) children[0],
404 "TreeWalker",
405 8,
406 atts);
407
408
409 final Configuration[] grandchildren = children[0].getChildren();
410 atts.clear();
411 verifyConfigNode(
412 (DefaultConfiguration) grandchildren[0],
413 "AvoidStarImport",
414 0,
415 atts);
416 atts.setProperty("format", "System.out.println");
417 verifyConfigNode(
418 (DefaultConfiguration) grandchildren[grandchildren.length - 1],
419 "GenericIllegalRegexp",
420 0,
421 atts);
422 atts.clear();
423 atts.setProperty("tokens", "DOT");
424 atts.setProperty("allowLineBreaks", "true");
425 verifyConfigNode(
426 (DefaultConfiguration) grandchildren[6],
427 "NoWhitespaceAfter",
428 0,
429 atts);
430 }
431
432 @Test
433 public void testCustomMessages() throws Exception {
434 final Properties props = new Properties();
435 props.setProperty("checkstyle.basedir", "basedir");
436
437 final DefaultConfiguration config =
438 (DefaultConfiguration) loadConfiguration(
439 "InputConfigurationLoaderCustomMessages.xml", props);
440
441 final Configuration[] children = config.getChildren();
442 final Configuration[] grandchildren = children[0].getChildren();
443 final List<String> messages = new ArrayList<>(grandchildren[0].getMessages().values());
444 final String expectedKey = "name.invalidPattern";
445 final List<String> expectedMessages = Collections
446 .singletonList("Member ''{0}'' must start with ''m'' (checked pattern ''{1}'').");
447 assertWithMessage("Messages should contain key: " + expectedKey)
448 .that(grandchildren[0].getMessages())
449 .containsKey(expectedKey);
450 assertWithMessage("Message is not expected")
451 .that(messages)
452 .isEqualTo(expectedMessages);
453 }
454
455 private static void verifyConfigNode(
456 DefaultConfiguration config, String name, int childrenLength,
457 Properties atts) throws Exception {
458 assertWithMessage("name.")
459 .that(config.getName())
460 .isEqualTo(name);
461 assertWithMessage("children.length.")
462 .that(config.getChildren().length)
463 .isEqualTo(childrenLength);
464
465 final String[] attNames = config.getPropertyNames();
466 assertWithMessage("attributes.length")
467 .that(attNames.length)
468 .isEqualTo(atts.size());
469
470 for (String attName : attNames) {
471 final String attribute = config.getProperty(attName);
472 assertWithMessage("attribute[" + attName + "]")
473 .that(attribute)
474 .isEqualTo(atts.getProperty(attName));
475 }
476 }
477
478 @Test
479 public void testSystemEntity() throws Exception {
480 final Properties props = new Properties();
481 props.setProperty("checkstyle.basedir", "basedir");
482
483 final DefaultConfiguration config =
484 (DefaultConfiguration) loadConfiguration(
485 "InputConfigurationLoaderSystemDoctype.xml", props);
486
487 final Properties atts = new Properties();
488 atts.setProperty("tabWidth", "4");
489
490 verifyConfigNode(config, "Checker", 0, atts);
491 }
492
493 @Test
494 public void testExternalEntity() throws Exception {
495 final Properties props = new Properties();
496 props.setProperty("checkstyle.basedir", "basedir");
497
498 System.setProperty(
499 XmlLoader.LoadExternalDtdFeatureProvider.ENABLE_EXTERNAL_DTD_LOAD, "true");
500
501 final DefaultConfiguration config =
502 (DefaultConfiguration) loadConfiguration(
503 "InputConfigurationLoaderExternalEntity.xml", props);
504
505 final Properties atts = new Properties();
506 atts.setProperty("tabWidth", "4");
507 atts.setProperty("basedir", "basedir");
508 verifyConfigNode(config, "Checker", 2, atts);
509 }
510
511 @Test
512 public void testExternalEntitySubdirectory() throws Exception {
513 final Properties props = new Properties();
514 props.setProperty("checkstyle.basedir", "basedir");
515
516 System.setProperty(
517 XmlLoader.LoadExternalDtdFeatureProvider.ENABLE_EXTERNAL_DTD_LOAD, "true");
518
519 final DefaultConfiguration config =
520 (DefaultConfiguration) loadConfiguration(
521 "subdir/InputConfigurationLoaderExternalEntitySubDir.xml", props);
522
523 final Properties attributes = new Properties();
524 attributes.setProperty("tabWidth", "4");
525 attributes.setProperty("basedir", "basedir");
526 verifyConfigNode(config, "Checker", 2, attributes);
527 }
528
529 @Test
530 public void testExternalEntityFromUri() throws Exception {
531 final Properties props = new Properties();
532 props.setProperty("checkstyle.basedir", "basedir");
533
534 System.setProperty(
535 XmlLoader.LoadExternalDtdFeatureProvider.ENABLE_EXTERNAL_DTD_LOAD, "true");
536
537 final File file = new File(
538 getPath("subdir/InputConfigurationLoaderExternalEntitySubDir.xml"));
539 final DefaultConfiguration config =
540 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
541 file.toURI().toString(), new PropertiesExpander(props));
542
543 final Properties atts = new Properties();
544 atts.setProperty("tabWidth", "4");
545 atts.setProperty("basedir", "basedir");
546 verifyConfigNode(config, "Checker", 2, atts);
547 }
548
549 @Test
550 public void testIncorrectTag() throws Exception {
551 final Class<?> aClassParent = ConfigurationLoader.class;
552 final Object objParent = TestUtil.instantiate(aClassParent, null, true, null);
553
554 final Class<?> aClass = Class.forName("com.puppycrawl.tools.checkstyle."
555 + "ConfigurationLoader$InternalLoader");
556 final Object obj = TestUtil.instantiate(aClass, objParent);
557
558 try {
559 TestUtil.invokeMethod(obj, "startElement", "", "", "hello", null);
560
561 assertWithMessage("InvocationTargetException is expected").fail();
562 }
563 catch (ReflectiveOperationException exc) {
564 assertWithMessage("Invalid exception cause message")
565 .that(exc)
566 .hasCauseThat()
567 .hasMessageThat()
568 .isEqualTo("Unknown name:" + "hello" + ".");
569 }
570 }
571
572 @Test
573 public void testNonExistentPropertyName() throws Exception {
574 try {
575 loadConfiguration("InputConfigurationLoaderNonexistentProperty.xml");
576 assertWithMessage("exception in expected").fail();
577 }
578 catch (CheckstyleException exc) {
579 assertWithMessage("Invalid exception message")
580 .that(exc.getMessage())
581 .isEqualTo("unable to parse configuration stream");
582 assertWithMessage("Expected cause of type SAXException")
583 .that(exc.getCause())
584 .isInstanceOf(SAXException.class);
585 assertWithMessage("Expected cause of type CheckstyleException")
586 .that(exc.getCause().getCause())
587 .isInstanceOf(CheckstyleException.class);
588 assertWithMessage("Invalid exception cause message")
589 .that(exc)
590 .hasCauseThat()
591 .hasCauseThat()
592 .hasMessageThat()
593 .isEqualTo("Property ${nonexistent} has not been set");
594 }
595 }
596
597 @Test
598 public void testConfigWithIgnore() throws Exception {
599 final DefaultConfiguration config =
600 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
601 getPath("InputConfigurationLoaderModuleIgnoreSeverity.xml"),
602 new PropertiesExpander(new Properties()), IgnoredModulesOptions.OMIT);
603
604 final Configuration[] children = config.getChildren();
605 final int length = children[0].getChildren().length;
606 assertWithMessage("Invalid children count")
607 .that(length)
608 .isEqualTo(0);
609 }
610
611 @Test
612 public void testConfigWithIgnoreUsingInputSource() throws Exception {
613 final DefaultConfiguration config =
614 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(new InputSource(
615 new File(getPath("InputConfigurationLoaderModuleIgnoreSeverity.xml"))
616 .toURI().toString()),
617 new PropertiesExpander(new Properties()), IgnoredModulesOptions.OMIT);
618
619 final Configuration[] children = config.getChildren();
620 final int length = children[0].getChildren().length;
621 assertWithMessage("Invalid children count")
622 .that(length)
623 .isEqualTo(0);
624 }
625
626 @Test
627 public void testConfigCheckerWithIgnore() throws Exception {
628 final DefaultConfiguration config =
629 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
630 getPath("InputConfigurationLoaderCheckerIgnoreSeverity.xml"),
631 new PropertiesExpander(new Properties()), IgnoredModulesOptions.OMIT);
632
633 final Configuration[] children = config.getChildren();
634 assertWithMessage("Invalid children count")
635 .that(children.length)
636 .isEqualTo(0);
637 }
638
639 @Test
640 public void testLoadConfigurationWrongUrl() {
641 try {
642 ConfigurationLoader.loadConfiguration(
643 ";InputConfigurationLoaderModuleIgnoreSeverity.xml",
644 new PropertiesExpander(new Properties()), IgnoredModulesOptions.OMIT);
645
646 assertWithMessage("Exception is expected").fail();
647 }
648 catch (CheckstyleException exc) {
649 assertWithMessage("Invalid exception message")
650 .that(exc.getMessage())
651 .isEqualTo("Unable to find: ;InputConfigurationLoaderModuleIgnoreSeverity.xml");
652 }
653 }
654
655 @Test
656 public void testLoadConfigurationDeprecated() throws Exception {
657 final DefaultConfiguration config =
658 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
659 new InputSource(Files.newInputStream(Path.of(
660 getPath("InputConfigurationLoaderModuleIgnoreSeverity.xml")))),
661 new PropertiesExpander(new Properties()), IgnoredModulesOptions.OMIT);
662
663 final Configuration[] children = config.getChildren();
664 final int length = children[0].getChildren().length;
665 assertWithMessage("Invalid children count")
666 .that(length)
667 .isEqualTo(0);
668 }
669
670 @Test
671 public void testLoadConfigurationFromClassPath() throws Exception {
672 final DefaultConfiguration config =
673 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
674 getPath("InputConfigurationLoaderModuleIgnoreSeverity.xml"),
675 new PropertiesExpander(new Properties()), IgnoredModulesOptions.OMIT);
676
677 final Configuration[] children = config.getChildren();
678 final int length = children[0].getChildren().length;
679 assertWithMessage("Invalid children count")
680 .that(length)
681 .isEqualTo(0);
682 }
683
684 @Test
685 public void testLoadConfigurationFromClassPathWithNonAsciiSymbolsInPath() throws Exception {
686 final DefaultConfiguration config =
687 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
688 getResourcePath("棵¥/InputConfigurationLoaderDefaultProperty.xml"),
689 new PropertiesExpander(new Properties()));
690
691 final Properties expectedPropertyValues = new Properties();
692 expectedPropertyValues.setProperty("tabWidth", "2");
693 expectedPropertyValues.setProperty("basedir", ".");
694
695 expectedPropertyValues.setProperty("charset", "ASCII");
696 verifyConfigNode(config, "Checker", 0, expectedPropertyValues);
697 }
698
699 @Test
700 public void testConstructors() throws Exception {
701 final Properties props = new Properties();
702 props.setProperty("checkstyle.basedir", "basedir");
703 final String fName = getPath("InputConfigurationLoaderChecks.xml");
704
705 final Configuration configuration = ConfigurationLoader.loadConfiguration(fName,
706 new PropertiesExpander(props), ConfigurationLoader.IgnoredModulesOptions.OMIT);
707 assertWithMessage("Name is not expected")
708 .that(configuration.getName())
709 .isEqualTo("Checker");
710
711 final DefaultConfiguration configuration1 =
712 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
713 new InputSource(Files.newInputStream(Path.of(
714 getPath("InputConfigurationLoaderModuleIgnoreSeverity.xml")))),
715 new PropertiesExpander(new Properties()),
716 ConfigurationLoader.IgnoredModulesOptions.EXECUTE);
717
718 final Configuration[] children = configuration1.getChildren();
719 final int length = children[0].getChildren().length;
720 assertWithMessage("Unexpected children size")
721 .that(length)
722 .isEqualTo(1);
723 }
724
725 @Test
726 public void testConfigWithIgnoreExceptionalAttributes() {
727 try (MockedConstruction<DefaultConfiguration> mocked = mockConstruction(
728 DefaultConfiguration.class, (mock, context) -> {
729 when(mock.getPropertyNames()).thenReturn(new String[] {"severity"});
730 when(mock.getName()).thenReturn("MemberName");
731 when(mock.getProperty("severity")).thenThrow(CheckstyleException.class);
732 })) {
733 final CheckstyleException ex =
734 TestUtil.getExpectedThrowable(CheckstyleException.class, () -> {
735 ConfigurationLoader.loadConfiguration(
736 getPath("InputConfigurationLoaderModuleIgnoreSeverity.xml"),
737 new PropertiesExpander(
738 new Properties()), IgnoredModulesOptions.OMIT);
739 });
740 final String expectedMessage =
741 "Problem during accessing 'severity' attribute for MemberName";
742 assertWithMessage("Invalid exception cause message")
743 .that(ex)
744 .hasCauseThat()
745 .hasMessageThat()
746 .isEqualTo(expectedMessage);
747 }
748 }
749
750 @Test
751 public void testLoadConfiguration3() throws Exception {
752 final String[] configFiles = {
753 "InputConfigurationLoaderOldConfig0.xml",
754 "InputConfigurationLoaderOldConfig1.xml",
755 "InputConfigurationLoaderOldConfig2.xml",
756 "InputConfigurationLoaderOldConfig3.xml",
757 "InputConfigurationLoaderOldConfig4.xml",
758 "InputConfigurationLoaderOldConfig5.xml",
759 "InputConfigurationLoaderOldConfig6.xml",
760 "InputConfigurationLoaderOldConfig7.xml",
761 };
762
763 for (String configFile : configFiles) {
764 final DefaultConfiguration config =
765 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
766 new InputSource(Files.newInputStream(Path.of(
767 getPath(configFile)))),
768 new PropertiesExpander(new Properties()),
769 IgnoredModulesOptions.OMIT);
770
771 assertWithMessage("should have properties")
772 .that(config.getPropertyNames()).asList()
773 .contains("severity");
774
775 assertWithMessage("should have properties")
776 .that(config.getPropertyNames()).asList()
777 .contains("fileExtensions");
778
779 assertWithMessage("")
780 .that(config.getAttribute("severity"))
781 .isEqualTo("error");
782
783 assertWithMessage("")
784 .that(config.getAttribute("fileExtensions"))
785 .isEqualTo("java, properties, xml");
786
787 assertWithMessage("")
788 .that(config.getChildren().length)
789 .isEqualTo(1);
790
791 final Configuration[] children = config.getChildren();
792 final Configuration[] grandchildren = children[0].getChildren();
793
794 assertWithMessage("")
795 .that(children[0].getPropertyNames()).asList()
796 .contains("severity");
797
798 assertWithMessage("")
799 .that(grandchildren[0].getPropertyNames()).asList()
800 .contains("query");
801 }
802 }
803
804 @Test
805 public void testDefaultValuesForNonDefinedProperties() throws Exception {
806 final Properties props = new Properties();
807 props.setProperty("checkstyle.charset.base", "UTF");
808
809 final File file = new File(
810 getPath("InputConfigurationLoaderDefaultProperty.xml"));
811 final DefaultConfiguration config =
812 (DefaultConfiguration) ConfigurationLoader.loadConfiguration(
813 file.toURI().toString(), new PropertiesExpander(props));
814
815 final Properties expectedPropertyValues = new Properties();
816 expectedPropertyValues.setProperty("tabWidth", "2");
817 expectedPropertyValues.setProperty("basedir", ".");
818
819 expectedPropertyValues.setProperty("charset", "ASCII");
820 verifyConfigNode(config, "Checker", 0, expectedPropertyValues);
821 }
822
823 }