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