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