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("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 }