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.meta;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.meta.JavadocMetadataScraper.MSG_DESC_MISSING;
24  
25  import java.nio.file.Files;
26  import java.nio.file.Path;
27  import java.util.Arrays;
28  import java.util.LinkedHashSet;
29  import java.util.Set;
30  import java.util.regex.Matcher;
31  import java.util.regex.Pattern;
32  import java.util.stream.Collectors;
33  import java.util.stream.Stream;
34  
35  import org.itsallcode.io.Capturable;
36  import org.itsallcode.junit.sysextensions.SystemOutGuard;
37  import org.junit.jupiter.api.Test;
38  import org.junit.jupiter.api.extension.ExtendWith;
39  
40  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
41  import com.puppycrawl.tools.checkstyle.internal.utils.CheckUtil;
42  
43  @ExtendWith(SystemOutGuard.class)
44  public final class MetadataGeneratorUtilTest extends AbstractModuleTestSupport {
45  
46      private final Set<String> modulesContainingNoMetadataFile = Set.of(
47              "Checker",
48              "TreeWalker",
49              "JavadocMetadataScraper",
50              "ClassAndPropertiesSettersJavadocScraper"
51      );
52  
53      @Override
54      protected String getPackageLocation() {
55          return null;
56      }
57  
58      /**
59       * Generates metadata for checkstyle modules and verifies number of
60       * generated metadata modules match the number of checkstyle modules.
61       * Also verifies whether every checkstyle module contains description.
62       *
63       * @param systemOut wrapper for {@code System.out}
64       * @throws Exception if exception occurs during generating metadata or
65       *                   if an I/O error is thrown when accessing the starting file.
66       * @noinspection UseOfSystemOutOrSystemErr
67       * @noinspectionreason UseOfSystemOutOrSystemErr - generation of metadata
68       *      requires {@code System.out} for error messages
69       */
70      @Test
71      public void testMetadataFilesGenerationAllFiles(@SystemOutGuard.SysOut Capturable systemOut)
72              throws Exception {
73          systemOut.captureMuted();
74  
75          MetadataGeneratorUtil.generate(System.getProperty("user.dir")
76                          + "/src/main/java/com/puppycrawl/tools/checkstyle",
77                  System.out, "checks", "filters", "filefilters");
78  
79          final String[] expectedErrorMessages = {
80              "31: " + getCheckMessage(MSG_DESC_MISSING, "AbstractSuperCheck"),
81              "43: " + getCheckMessage(MSG_DESC_MISSING, "AbstractHeaderCheck"),
82              "42: " + getCheckMessage(MSG_DESC_MISSING, "AbstractJavadocCheck"),
83              "45: " + getCheckMessage(MSG_DESC_MISSING, "AbstractClassCouplingCheck"),
84              "26: " + getCheckMessage(MSG_DESC_MISSING, "AbstractAccessControlNameCheck"),
85              "30: " + getCheckMessage(MSG_DESC_MISSING, "AbstractNameCheck"),
86              "30: " + getCheckMessage(MSG_DESC_MISSING, "AbstractParenPadCheck"),
87          };
88  
89          final String[] actualViolations = systemOut.getCapturedData().split("\\n");
90          final Pattern violationExtractingPattern = Pattern.compile("((?<=:)\\d.*:.*(?=\\s\\[))");
91  
92          Arrays.setAll(actualViolations, id -> {
93              final Matcher matcher = violationExtractingPattern.matcher(actualViolations[id]);
94              matcher.find();
95              return matcher.group(1);
96          });
97  
98          assertWithMessage("Expected and actual errors do not match")
99                  .that(expectedErrorMessages)
100                 .asList()
101                 .containsExactlyElementsIn(actualViolations);
102 
103         final Set<String> metaFiles;
104         try (Stream<Path> fileStream = Files.walk(
105                 Path.of(System.getProperty("user.dir") + "/src/main/resources/com/puppycrawl"
106                         + "/tools/checkstyle/meta"))) {
107             metaFiles = fileStream
108                     .filter(Files::isRegularFile)
109                     .filter(path -> !path.toString().endsWith(".properties"))
110                     .map(MetadataGeneratorUtilTest::getMetaFileName)
111                     .sorted()
112                     .collect(Collectors.toCollection(LinkedHashSet::new));
113         }
114         final Set<String> checkstyleModules =
115                 CheckUtil.getSimpleNames(CheckUtil.getCheckstyleModules())
116                 .stream()
117                 .sorted()
118                 .collect(Collectors.toCollection(LinkedHashSet::new));
119         checkstyleModules.removeAll(modulesContainingNoMetadataFile);
120         assertWithMessage("Number of generated metadata files dont match with "
121                 + "number of checkstyle module")
122                 .that(metaFiles)
123                 .isEqualTo(checkstyleModules);
124     }
125 
126     /**
127      * Get meta file name from full file name.
128      *
129      * @param file file to process
130      * @return meta file name
131      */
132     private static String getMetaFileName(Path file) {
133         final String fileName = file.getFileName().toString();
134         final int lengthToOmit;
135         if (fileName.contains("Check")) {
136             lengthToOmit = "Check.xml".length();
137         }
138         else {
139             lengthToOmit = ".xml".length();
140         }
141         return fileName.substring(0, fileName.length() - lengthToOmit);
142     }
143 }