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.internal;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23
24 import java.beans.PropertyDescriptor;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Set;
31 import java.util.stream.Collectors;
32
33 import org.apache.commons.beanutils.PropertyUtils;
34 import org.junit.jupiter.api.Test;
35
36 import com.puppycrawl.tools.checkstyle.internal.utils.CheckUtil;
37 import com.puppycrawl.tools.checkstyle.internal.utils.XdocUtil;
38
39 public class XdocsExampleFileTest {
40
41 private static final Set<String> COMMON_PROPERTIES = Set.of(
42 "severity",
43 "id",
44 "fileExtensions",
45 "tabWidth",
46 "fileContents",
47 "tokens",
48 "javadocTokens",
49 "violateExecutionOnNonTightHtml"
50 );
51
52
53
54 private static final Map<String, Set<String>> SUPPRESSED_PROPERTIES_BY_CHECK = Map.ofEntries(
55 Map.entry("TrailingCommentCheck", Set.of("legalComment")),
56 Map.entry("IllegalTypeCheck", Set.of("legalAbstractClassNames")),
57 Map.entry("MissingJavadocTypeCheck", Set.of("skipAnnotations")),
58 Map.entry("JavadocStyleCheck", Set.of("endOfSentenceFormat", "checkEmptyJavadoc")),
59 Map.entry("ConstantNameCheck", Set.of("applyToPackage", "applyToPrivate")),
60 Map.entry("JavaNCSSCheck", Set.of("recordMaximum")),
61 Map.entry("WhitespaceAroundCheck", Set.of("allowEmptySwitchBlockStatements")),
62 Map.entry("FinalLocalVariableCheck", Set.of("validateUnnamedVariables")),
63 Map.entry("SuppressWarningsHolder", Set.of("aliasList")),
64 Map.entry("IllegalTokenTextCheck", Set.of("message")),
65 Map.entry("IndentationCheck", Set.of(
66 "basicOffset",
67 "lineWrappingIndentation",
68 "throwsIndent",
69 "arrayInitIndent",
70 "braceAdjustment"
71 )),
72 Map.entry("MethodCountCheck", Set.of("maxPrivate", "maxPackage", "maxProtected")),
73 Map.entry("ClassMemberImpliedModifierCheck", Set.of(
74 "violateImpliedStaticOnNestedEnum",
75 "violateImpliedStaticOnNestedRecord",
76 "violateImpliedStaticOnNestedInterface"
77 )),
78 Map.entry("DescendantTokenCheck", Set.of("minimumMessage")),
79 Map.entry("InterfaceMemberImpliedModifierCheck", Set.of(
80 "violateImpliedFinalField",
81 "violateImpliedPublicField",
82 "violateImpliedStaticField",
83 "violateImpliedPublicMethod",
84 "violateImpliedAbstractMethod"
85 ))
86 );
87
88 @Test
89 public void testAllCheckPropertiesAreUsedInXdocsExamples() throws Exception {
90 final Map<String, Set<String>> usedPropertiesByCheck =
91 XdocUtil.extractUsedPropertiesFromXdocsExamples();
92 final List<String> failures = new ArrayList<>();
93
94 for (Class<?> checkClass : CheckUtil.getCheckstyleChecks()) {
95 final String checkSimpleName = checkClass.getSimpleName();
96
97 final Set<String> definedProperties = Arrays.stream(
98 PropertyUtils.getPropertyDescriptors(checkClass))
99 .filter(descriptor -> descriptor.getWriteMethod() != null)
100 .map(PropertyDescriptor::getName)
101 .filter(property -> !COMMON_PROPERTIES.contains(property))
102 .collect(Collectors.toUnmodifiableSet());
103
104 final Set<String> usedProperties =
105 usedPropertiesByCheck.getOrDefault(checkSimpleName, Collections.emptySet());
106
107 final Set<String> suppressedProps =
108 SUPPRESSED_PROPERTIES_BY_CHECK.getOrDefault(
109 checkSimpleName, Collections.emptySet());
110
111 for (String property : definedProperties) {
112 if (!usedProperties.contains(property)
113 && !suppressedProps.contains(property)) {
114 failures.add("Missing property in xdoc: '"
115 + property + "' of " + checkSimpleName);
116 }
117 }
118 }
119 if (!failures.isEmpty()) {
120 assertWithMessage("Xdocs are missing properties:\n" + String.join("\n", failures))
121 .fail();
122 }
123 }
124 }