1
2
3
4
5 package com.qulice.checkstyle;
6
7 import com.puppycrawl.tools.checkstyle.Checker;
8 import com.puppycrawl.tools.checkstyle.ConfigurationLoader;
9 import com.puppycrawl.tools.checkstyle.PropertiesExpander;
10 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
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.LinkedList;
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.cactoos.text.Joined;
22 import org.hamcrest.MatcherAssert;
23 import org.hamcrest.Matchers;
24 import org.junit.jupiter.params.ParameterizedTest;
25 import org.junit.jupiter.params.provider.MethodSource;
26 import org.xml.sax.InputSource;
27
28
29
30
31
32 final class ChecksTest {
33
34
35
36
37
38
39 @ParameterizedTest
40 @MethodSource("checks")
41 @SuppressWarnings("PMD.JUnitAssertionsShouldIncludeMessage")
42 void testCheckstyleTruePositive(final String dir) throws Exception {
43 final Collector collector = new ChecksTest.Collector();
44 final AuditListener listener = new FakeAuditListener(collector);
45 this.check(dir, "/Invalid.java", listener);
46 final String[] violations = IOUtils.toString(
47 Objects.requireNonNull(
48 this.getClass().getResourceAsStream(
49 String.format("%s/violations.txt", dir)
50 )
51 ),
52 StandardCharsets.UTF_8
53 ).split("\n");
54 for (final String line : violations) {
55 final String[] sectors = line.split(":");
56 final Integer pos = Integer.valueOf(sectors[0]);
57 final String needle = sectors[1].trim();
58 MatcherAssert.assertThat(
59 collector.has(pos, needle),
60 Matchers.describedAs(
61 String.format(
62 "Line no.%d ('%s') not reported by %s: '%s'",
63 pos,
64 needle,
65 dir,
66 collector.summary()
67 ),
68 Matchers.is(true)
69 )
70 );
71 }
72 MatcherAssert.assertThat(
73 collector.eventCount(),
74 Matchers.describedAs(
75 String.format(
76 "Got more violations that expected for directory %s (%s)",
77 dir, collector.summary()
78 ),
79 Matchers.equalTo(violations.length)
80 )
81 );
82 }
83
84
85
86
87
88
89 @ParameterizedTest
90 @MethodSource("checks")
91 void testCheckstyleTrueNegative(final String dir) throws Exception {
92 final Collector collector = new ChecksTest.Collector();
93 final AuditListener listener = new FakeAuditListener(collector);
94 this.check(dir, "/Valid.java", listener);
95 MatcherAssert.assertThat(
96 "Log should be empty for valid files",
97 collector.summary(),
98 Matchers.equalTo("")
99 );
100 }
101
102
103
104
105
106
107
108
109 private void check(
110 final String dir, final String name, final AuditListener listener
111 ) throws Exception {
112 final Checker checker = new Checker();
113 final InputSource src = new InputSource(
114 this.getClass().getResourceAsStream(
115 String.format("%s/config.xml", dir)
116 )
117 );
118 checker.setModuleClassLoader(
119 Thread.currentThread().getContextClassLoader()
120 );
121 checker.configure(
122 ConfigurationLoader.loadConfiguration(
123 src,
124 new PropertiesExpander(new Properties()),
125 ConfigurationLoader.IgnoredModulesOptions.OMIT
126 )
127 );
128 final List<File> files = new ArrayList<>(0);
129 files.add(
130 new File(
131 this.getClass().getResource(
132 String.format("%s%s", dir, name)
133 ).getFile()
134 )
135 );
136 checker.addListener(listener);
137 checker.process(files);
138 checker.destroy();
139 }
140
141
142
143
144
145 @SuppressWarnings("PMD.UnusedPrivateMethod")
146 private static Stream<String> checks() {
147 return Stream.of(
148 "MethodsOrderCheck",
149 "MultilineJavadocTagsCheck",
150 "StringLiteralsConcatenationCheck",
151 "EmptyLinesCheck",
152 "ImportCohesionCheck",
153 "BracketsStructureCheck",
154 "CurlyBracketsStructureCheck",
155 "JavadocLocationCheck",
156 "JavadocParameterOrderCheck",
157 "MethodBodyCommentsCheck",
158 "RequireThisCheck",
159 "ProtectedMethodInFinalClassCheck",
160 "NoJavadocForOverriddenMethodsCheck",
161 "NonStaticMethodCheck",
162 "ConstantUsageCheck",
163 "JavadocEmptyLineCheck",
164 "JavadocTagsCheck",
165 "ProhibitNonFinalClassesCheck",
166 "QualifyInnerClassCheck",
167 "CommentCheck",
168 "ProhibitUnusedPrivateConstructorCheck"
169 ).map(s -> String.format("ChecksTest/%s", s));
170 }
171
172
173
174
175
176
177 private static final class Collector {
178
179
180
181 private final List<AuditEvent> events = new LinkedList<>();
182
183 public void add(final AuditEvent event) {
184 this.events.add(event);
185 }
186
187
188
189
190
191 public int eventCount() {
192 return this.events.size();
193 }
194
195
196
197
198
199
200
201 public boolean has(final Integer line, final String msg) {
202 boolean has = false;
203 for (final AuditEvent event : this.events) {
204 if (event.getLine() == line && event.getMessage().equals(msg)) {
205 has = true;
206 break;
207 }
208 }
209 return has;
210 }
211
212
213
214
215
216 public String summary() {
217 final List<String> msgs = new LinkedList<>();
218 for (final AuditEvent event : this.events) {
219 msgs.add(
220 String.format(
221 "%s:%s",
222 event.getLine(),
223 event.getMessage()
224 )
225 );
226 }
227 return new Joined("; ", msgs).toString();
228 }
229 }
230
231
232
233
234
235
236
237
238 private static final class FakeAuditListener implements AuditListener {
239
240
241
242 private final ChecksTest.Collector collector;
243
244 FakeAuditListener(final ChecksTest.Collector collect) {
245 this.collector = collect;
246 }
247
248 @Override
249 public void auditStarted(final AuditEvent event) {
250
251 }
252
253 @Override
254 public void auditFinished(final AuditEvent event) {
255
256 }
257
258 @Override
259 public void fileStarted(final AuditEvent event) {
260
261 }
262
263 @Override
264 public void fileFinished(final AuditEvent event) {
265
266 }
267
268 @Override
269 public void addError(final AuditEvent event) {
270 this.collector.add(event);
271 }
272
273 @Override
274 public void addException(
275 final AuditEvent event,
276 final Throwable throwable
277 ) {
278
279 }
280 }
281 }