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