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