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