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("MissingJavadocTypeCheck", Set.of("skipAnnotations")),
56 Map.entry("JavadocStyleCheck", Set.of("endOfSentenceFormat", "checkEmptyJavadoc")),
57 Map.entry("ConstantNameCheck", Set.of("applyToPackage", "applyToPrivate")),
58 Map.entry("JavaNCSSCheck", Set.of("recordMaximum")),
59 Map.entry("WhitespaceAroundCheck", Set.of("allowEmptySwitchBlockStatements")),
60 Map.entry("FinalLocalVariableCheck", Set.of("validateUnnamedVariables")),
61 Map.entry("SuppressWarningsHolder", Set.of("aliasList")),
62 Map.entry("IllegalTokenTextCheck", Set.of("message")),
63 Map.entry("IndentationCheck", Set.of(
64 "basicOffset",
65 "lineWrappingIndentation",
66 "throwsIndent",
67 "arrayInitIndent",
68 "braceAdjustment"
69 )),
70 Map.entry("MethodCountCheck", Set.of("maxPrivate", "maxPackage", "maxProtected")),
71 Map.entry("ClassMemberImpliedModifierCheck", Set.of(
72 "violateImpliedStaticOnNestedEnum",
73 "violateImpliedStaticOnNestedRecord",
74 "violateImpliedStaticOnNestedInterface"
75 )),
76 Map.entry("DescendantTokenCheck", Set.of("minimumMessage")),
77 Map.entry("InterfaceMemberImpliedModifierCheck", Set.of(
78 "violateImpliedFinalField",
79 "violateImpliedPublicField",
80 "violateImpliedStaticField",
81 "violateImpliedPublicMethod",
82 "violateImpliedAbstractMethod"
83 ))
84 );
85
86 @Test
87 public void testAllCheckPropertiesAreUsedInXdocsExamples() throws Exception {
88 final Map<String, Set<String>> usedPropertiesByCheck =
89 XdocUtil.extractUsedPropertiesFromXdocsExamples();
90 final List<String> failures = new ArrayList<>();
91
92 for (Class<?> checkClass : CheckUtil.getCheckstyleChecks()) {
93 final String checkSimpleName = checkClass.getSimpleName();
94
95 final Set<String> definedProperties = Arrays.stream(
96 PropertyUtils.getPropertyDescriptors(checkClass))
97 .filter(descriptor -> descriptor.getWriteMethod() != null)
98 .map(PropertyDescriptor::getName)
99 .filter(property -> !COMMON_PROPERTIES.contains(property))
100 .collect(Collectors.toUnmodifiableSet());
101
102 final Set<String> usedProperties =
103 usedPropertiesByCheck.getOrDefault(checkSimpleName, Collections.emptySet());
104
105 final Set<String> suppressedProps =
106 SUPPRESSED_PROPERTIES_BY_CHECK.getOrDefault(
107 checkSimpleName, Collections.emptySet());
108
109 for (String property : definedProperties) {
110 if (!usedProperties.contains(property)
111 && !suppressedProps.contains(property)) {
112 failures.add("Missing property in xdoc: '"
113 + property + "' of " + checkSimpleName);
114 }
115 }
116 }
117 if (!failures.isEmpty()) {
118 assertWithMessage("Xdocs are missing properties:\n" + String.join("\n", failures))
119 .fail();
120 }
121 }
122 }