1
2
3
4
5 package com.qulice.checkstyle;
6
7 import com.google.common.base.Splitter;
8 import com.puppycrawl.tools.checkstyle.Checker;
9 import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
10 import com.puppycrawl.tools.checkstyle.PropertiesExpander;
11 import com.puppycrawl.tools.checkstyle.api.AuditListener;
12 import java.io.File;
13 import java.nio.charset.StandardCharsets;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.List;
17 import java.util.Objects;
18 import java.util.Properties;
19 import java.util.stream.Stream;
20 import org.apache.commons.io.IOUtils;
21 import org.hamcrest.MatcherAssert;
22 import org.hamcrest.Matchers;
23 import org.junit.jupiter.params.ParameterizedTest;
24 import org.junit.jupiter.params.provider.Arguments;
25 import org.junit.jupiter.params.provider.MethodSource;
26 import org.xml.sax.InputSource;
27
28
29
30
31
32
33 final class ChecksTest {
34
35
36
37
38
39
40
41
42 @ParameterizedTest
43 @MethodSource("invalids")
44 void testCheckstyleTruePositive(final String dir, final String name)
45 throws Exception {
46 final AuditCollector collector = new AuditCollector();
47 this.run(
48 dir, String.format("/%s", name),
49 new FakeAuditListener(collector)
50 );
51 final String[] violations = IOUtils.toString(
52 Objects.requireNonNull(
53 this.getClass().getResourceAsStream(
54 String.format(
55 "%s/violations%s.txt",
56 dir,
57 name.substring(
58 "Invalid".length(),
59 name.length() - ".java".length()
60 )
61 )
62 )
63 ),
64 StandardCharsets.UTF_8
65 ).split(String.valueOf('\n'));
66 MatcherAssert.assertThat(
67 String.format(
68 "Expected exactly %d violations from %s/%s (%s)",
69 violations.length, dir, name, collector.summary()
70 ),
71 collector.eventCount() == violations.length
72 && Arrays.stream(violations).allMatch(
73 line -> {
74 final List<String> sectors =
75 Splitter.on(':').splitToList(line);
76 return collector.has(
77 Integer.valueOf(sectors.get(0)),
78 sectors.get(1).trim()
79 );
80 }
81 ),
82 Matchers.is(true)
83 );
84 }
85
86
87
88
89
90
91
92
93 @ParameterizedTest
94 @MethodSource("valids")
95 void testCheckstyleTrueNegative(final String dir, final String name)
96 throws Exception {
97 final AuditCollector collector = new AuditCollector();
98 this.run(
99 dir, String.format("/%s", name),
100 new FakeAuditListener(collector)
101 );
102 MatcherAssert.assertThat(
103 String.format("Log should be empty for valid file %s/%s", dir, name),
104 collector.summary(),
105 Matchers.equalTo("")
106 );
107 }
108
109 private void run(
110 final String dir, final String name, final AuditListener listener
111 ) throws Exception {
112 final Checker checker = new Checker();
113 checker.setModuleClassLoader(
114 Thread.currentThread().getContextClassLoader()
115 );
116 checker.configure(
117 ConfigurationLoader.loadConfiguration(
118 new InputSource(
119 this.getClass().getResourceAsStream(
120 String.format("%s/config.xml", dir)
121 )
122 ),
123 new PropertiesExpander(new Properties()),
124 ConfigurationLoader.IgnoredModulesOptions.OMIT
125 )
126 );
127 final List<File> files = new ArrayList<>(0);
128 files.add(
129 new File(
130 this.getClass().getResource(
131 String.format("%s%s", dir, name)
132 ).getFile()
133 )
134 );
135 checker.addListener(listener);
136 checker.process(files);
137 checker.destroy();
138 }
139
140 private static Stream<Arguments> invalids() {
141 return ChecksTest.checks().flatMap(dir -> ChecksTest.files(dir, "Invalid"));
142 }
143
144 private static Stream<Arguments> valids() {
145 return ChecksTest.checks().flatMap(dir -> ChecksTest.files(dir, "Valid"));
146 }
147
148 private static Stream<Arguments> files(
149 final String dir, final String prefix
150 ) {
151 final File directory = new File(
152 Objects.requireNonNull(
153 ChecksTest.class.getResource(dir),
154 String.format("Resource directory not found: %s", dir)
155 ).getFile()
156 );
157 final File[] found = directory.listFiles(
158 (parent, child) -> child.endsWith(".java")
159 && (
160 child.equals(String.format("%s.java", prefix))
161 || child.startsWith(String.format("%s-", prefix))
162 )
163 );
164 final Stream<Arguments> result;
165 if (found == null) {
166 result = Stream.empty();
167 } else {
168 result = Arrays.stream(found)
169 .sorted()
170 .map(file -> Arguments.of(dir, file.getName()));
171 }
172 return result;
173 }
174
175 private static Stream<String> checks() {
176 return Stream.of(
177 "MethodsOrderCheck",
178 "MultilineJavadocTagsCheck",
179 "StringLiteralsConcatenationCheck",
180 "ProhibitLineSeparatorInStringsCheck",
181 "EmptyLinesCheck",
182 "EmptyLineBeforeFirstMemberCheck",
183 "ImportCohesionCheck",
184 "BracketsStructureCheck",
185 "NestedSwitchCheck",
186 "ProhibitTestExpectedCheck",
187 "ProhibitTestMethodNameCheck",
188 "MethodDeclarationLengthCheck",
189 "CurlyBracketsStructureCheck",
190 "JavadocLocationCheck",
191 "JavadocParameterOrderCheck",
192 "MethodBodyCommentsCheck",
193 "RequireThisCheck",
194 "ProtectedMethodInFinalClassCheck",
195 "NoJavadocForOverriddenMethodsCheck",
196 "NonStaticMethodCheck",
197 "ConstantUsageCheck",
198 "SingleUseConstantCheck",
199 "FullyQualifiedTypeCheck",
200 "ImplicitConstructorCheck",
201 "JavadocEmptyLineCheck",
202 "JavadocEmptyLineBeforeTagCheck",
203 "JavadocCompactParagraphCheck",
204 "JavadocStrayAsteriskCheck",
205 "JavadocUnclosedParagraphCheck",
206 "JavadocFirstLineCheck",
207 "JavadocNoIndentCheck",
208 "JavadocTagsCheck",
209 "JavadocTagsDotCheck",
210 "JavadocThrowsCheck",
211 "ProhibitNonFinalClassesCheck",
212 "QualifyInnerClassCheck",
213 "CommentCheck",
214 "ProhibitUnusedPrivateConstructorCheck",
215 "ConstructorsOrderCheck",
216 "ConstructorsCodeFreeCheck",
217 "RedundantSuperConstructorCheck",
218 "StaticAccessViaInstanceCheck",
219 "SingleSpaceSeparatorCheck",
220 "SimpleStringSplitCheck",
221 "ProhibitFieldsInTestClassesCheck",
222 "ProhibitStaticNestedClassesCheck",
223 "NoJavadocForPrivateMethodsCheck",
224 "ParameterNumberCheck"
225 ).map(s -> String.format("ChecksTest/%s", s));
226 }
227 }