View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2025 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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      // This list is temporarily suppressed.
53      // Until: https://github.com/checkstyle/checkstyle/issues/17449
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 }