1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.api;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
24
25 import java.io.File;
26 import java.nio.charset.Charset;
27 import java.util.Arrays;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.Map;
32 import java.util.Set;
33 import java.util.SortedSet;
34
35 import org.junit.jupiter.api.Test;
36
37 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
38 import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
39 import com.puppycrawl.tools.checkstyle.DetailAstImpl;
40 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
41
42 public class AbstractCheckTest extends AbstractModuleTestSupport {
43
44 @Override
45 protected String getPackageLocation() {
46 return "com/puppycrawl/tools/checkstyle/api/abstractcheck";
47 }
48
49 @Test
50 public void testGetRequiredTokens() {
51 final AbstractCheck check = new AbstractCheck() {
52 @Override
53 public int[] getDefaultTokens() {
54 return CommonUtil.EMPTY_INT_ARRAY;
55 }
56
57 @Override
58 public int[] getAcceptableTokens() {
59 return getDefaultTokens();
60 }
61
62 @Override
63 public int[] getRequiredTokens() {
64 return getDefaultTokens();
65 }
66 };
67
68 assertWithMessage("Invalid number of tokens, should be empty")
69 .that(check.getRequiredTokens())
70 .isEmpty();
71 }
72
73 @Test
74 public void testGetAcceptable() {
75 final AbstractCheck check = new AbstractCheck() {
76 @Override
77 public int[] getDefaultTokens() {
78 return CommonUtil.EMPTY_INT_ARRAY;
79 }
80
81 @Override
82 public int[] getAcceptableTokens() {
83 return getDefaultTokens();
84 }
85
86 @Override
87 public int[] getRequiredTokens() {
88 return getDefaultTokens();
89 }
90 };
91
92 assertWithMessage("Invalid number of tokens, should be empty")
93 .that(check.getAcceptableTokens())
94 .isEmpty();
95 }
96
97 @Test
98 public void testCommentNodes() {
99 final AbstractCheck check = new AbstractCheck() {
100 @Override
101 public int[] getDefaultTokens() {
102 return CommonUtil.EMPTY_INT_ARRAY;
103 }
104
105 @Override
106 public int[] getAcceptableTokens() {
107 return getDefaultTokens();
108 }
109
110 @Override
111 public int[] getRequiredTokens() {
112 return getDefaultTokens();
113 }
114 };
115
116 assertWithMessage("unexpected result")
117 .that(check.isCommentNodesRequired())
118 .isFalse();
119 }
120
121 @Test
122 public void testTokenNames() {
123 final AbstractCheck check = new AbstractCheck() {
124 @Override
125 public int[] getDefaultTokens() {
126 return CommonUtil.EMPTY_INT_ARRAY;
127 }
128
129 @Override
130 public int[] getAcceptableTokens() {
131 return getDefaultTokens();
132 }
133
134 @Override
135 public int[] getRequiredTokens() {
136 return getDefaultTokens();
137 }
138 };
139
140 check.setTokens("IDENT, EXPR, ELIST");
141 assertWithMessage("unexpected result")
142 .that(check.getTokenNames())
143 .containsExactly("IDENT, EXPR, ELIST");
144 }
145
146 @Test
147 public void testVisitToken() {
148 final VisitCounterCheck check = new VisitCounterCheck();
149
150 check.visitToken(null);
151
152 assertWithMessage("expected call count")
153 .that(check.count)
154 .isEqualTo(1);
155 }
156
157 @Test
158 public void testGetLine() throws Exception {
159 final AbstractCheck check = new AbstractCheck() {
160 @Override
161 public int[] getDefaultTokens() {
162 return CommonUtil.EMPTY_INT_ARRAY;
163 }
164
165 @Override
166 public int[] getAcceptableTokens() {
167 return getDefaultTokens();
168 }
169
170 @Override
171 public int[] getRequiredTokens() {
172 return getDefaultTokens();
173 }
174 };
175 check.setFileContents(new FileContents(new FileText(
176 new File(getPath("InputAbstractCheckTestFileContents.java")),
177 Charset.defaultCharset().name())));
178
179 assertWithMessage("Invalid line content")
180 .that(check.getLine(9))
181 .isEqualTo(" * I'm a javadoc");
182 }
183
184 @Test
185 public void testGetLineCodePoints() throws Exception {
186 final AbstractCheck check = new AbstractCheck() {
187 @Override
188 public int[] getDefaultTokens() {
189 return CommonUtil.EMPTY_INT_ARRAY;
190 }
191
192 @Override
193 public int[] getAcceptableTokens() {
194 return getDefaultTokens();
195 }
196
197 @Override
198 public int[] getRequiredTokens() {
199 return getDefaultTokens();
200 }
201 };
202 final FileContents fileContents = new FileContents(new FileText(
203 new File(getPath("InputAbstractCheckTestFileContents.java")),
204 Charset.defaultCharset().name()));
205 check.setFileContents(fileContents);
206
207 final int[] expectedCodePoints = " public int getVariable() {".codePoints().toArray();
208 assertWithMessage("Invalid line content")
209 .that(check.getLineCodePoints(18))
210 .isEqualTo(expectedCodePoints);
211 }
212
213 @Test
214 public void testGetTabWidth() {
215 final AbstractCheck check = new AbstractCheck() {
216 @Override
217 public int[] getDefaultTokens() {
218 return CommonUtil.EMPTY_INT_ARRAY;
219 }
220
221 @Override
222 public int[] getAcceptableTokens() {
223 return getDefaultTokens();
224 }
225
226 @Override
227 public int[] getRequiredTokens() {
228 return getDefaultTokens();
229 }
230 };
231 final int tabWidth = 4;
232 check.setTabWidth(tabWidth);
233
234 assertWithMessage("Invalid tab width")
235 .that(check.getTabWidth())
236 .isEqualTo(tabWidth);
237 }
238
239 @Test
240 public void testFileContents() {
241 final AbstractCheck check = new AbstractCheck() {
242 @Override
243 public int[] getDefaultTokens() {
244 return CommonUtil.EMPTY_INT_ARRAY;
245 }
246
247 @Override
248 public int[] getAcceptableTokens() {
249 return getDefaultTokens();
250 }
251
252 @Override
253 public int[] getRequiredTokens() {
254 return getDefaultTokens();
255 }
256 };
257 final String[] lines = {"test"};
258 final FileContents fileContents = new FileContents(
259 new FileText(new File("filename"), Arrays.asList(lines)));
260 check.setFileContents(fileContents);
261
262 assertWithMessage("Invalid file contents")
263 .that(check.getFileContents())
264 .isEqualTo(fileContents);
265 assertWithMessage("Invalid lines")
266 .that(check.getLines())
267 .isEqualTo(lines);
268 }
269
270 @Test
271 public void testGetAcceptableTokens() {
272 final int[] defaultTokens = {TokenTypes.CLASS_DEF, TokenTypes.INTERFACE_DEF};
273 final int[] acceptableTokens = {TokenTypes.CLASS_DEF, TokenTypes.INTERFACE_DEF};
274 final int[] requiredTokens = {TokenTypes.CLASS_DEF, TokenTypes.INTERFACE_DEF};
275 final AbstractCheck check = new AbstractCheck() {
276 @Override
277 public int[] getDefaultTokens() {
278 return defaultTokens;
279 }
280
281 @Override
282 public int[] getAcceptableTokens() {
283 return acceptableTokens;
284 }
285
286 @Override
287 public int[] getRequiredTokens() {
288 return requiredTokens;
289 }
290 };
291
292 assertWithMessage("Invalid default tokens")
293 .that(check.getDefaultTokens())
294 .isEqualTo(defaultTokens);
295 assertWithMessage("Invalid acceptable tokens")
296 .that(check.getAcceptableTokens())
297 .isEqualTo(acceptableTokens);
298 assertWithMessage("Invalid required tokens")
299 .that(check.getRequiredTokens())
300 .isEqualTo(requiredTokens);
301 }
302
303 @Test
304 public void testClearViolations() {
305 final AbstractCheck check = new DummyAbstractCheck();
306
307 check.log(1, "key", "args");
308 assertWithMessage("Invalid violation size")
309 .that(check.getViolations())
310 .hasSize(1);
311 check.clearViolations();
312 assertWithMessage("Invalid violation size")
313 .that(check.getViolations())
314 .isEmpty();
315 }
316
317 @Test
318 public void testLineColumnLog() throws Exception {
319 final ViolationCheck check = new ViolationCheck();
320 check.configure(new DefaultConfiguration("check"));
321 final File file = new File("fileName");
322 final FileText theText = new FileText(file, Collections.singletonList("test123"));
323
324 check.setFileContents(new FileContents(theText));
325 check.clearViolations();
326 check.visitToken(null);
327
328 final SortedSet<Violation> internalViolations = check.getViolations();
329
330 assertWithMessage("Internal violation should only have 2")
331 .that(internalViolations)
332 .hasSize(2);
333
334 final Iterator<Violation> iterator = internalViolations.iterator();
335
336 final Violation firstViolation = iterator.next();
337 assertWithMessage("expected line")
338 .that(firstViolation.getLineNo())
339 .isEqualTo(1);
340 assertWithMessage("expected column")
341 .that(firstViolation.getColumnNo())
342 .isEqualTo(0);
343
344 final Violation secondViolation = iterator.next();
345 assertWithMessage("expected line")
346 .that(secondViolation.getLineNo())
347 .isEqualTo(1);
348 assertWithMessage("expected column")
349 .that(secondViolation.getColumnNo())
350 .isEqualTo(6);
351 }
352
353 @Test
354 public void testAstLog() throws Exception {
355 final ViolationAstCheck check = new ViolationAstCheck();
356 check.configure(new DefaultConfiguration("check"));
357 final File file = new File("fileName");
358 final FileText theText = new FileText(file, Collections.singletonList("test123"));
359
360 check.setFileContents(new FileContents(theText));
361 check.clearViolations();
362
363 final DetailAstImpl ast = new DetailAstImpl();
364 ast.setLineNo(1);
365 ast.setColumnNo(4);
366 check.visitToken(ast);
367
368 final SortedSet<Violation> internalViolations = check.getViolations();
369
370 assertWithMessage("Internal violation should only have 1")
371 .that(internalViolations)
372 .hasSize(1);
373
374 final Violation firstViolation = internalViolations.iterator().next();
375 assertWithMessage("expected line")
376 .that(firstViolation.getLineNo())
377 .isEqualTo(1);
378 assertWithMessage("expected column")
379 .that(firstViolation.getColumnNo())
380 .isEqualTo(5);
381 }
382
383 @Test
384 public void testCheck() throws Exception {
385 final String[] expected = {
386 "6:1: Violation.",
387 };
388 verifyWithInlineConfigParser(getPath("InputAbstractCheckTestFileContents.java"), expected);
389 }
390
391
392
393
394
395
396 @Test
397 public void testTokensAreUnmodifiable() {
398 final DummyAbstractCheck check = new DummyAbstractCheck();
399 final Set<String> tokenNameSet = check.getTokenNames();
400 final Exception ex = getExpectedThrowable(UnsupportedOperationException.class,
401 () -> tokenNameSet.add(""));
402 assertWithMessage("Exception class is not expected")
403 .that(ex.getClass())
404 .isEqualTo(UnsupportedOperationException.class);
405 }
406
407 public static final class DummyAbstractCheck extends AbstractCheck {
408
409 private static final int[] DUMMY_ARRAY = {6};
410
411 @Override
412 public int[] getDefaultTokens() {
413 return Arrays.copyOf(DUMMY_ARRAY, 1);
414 }
415
416 @Override
417 public int[] getAcceptableTokens() {
418 return Arrays.copyOf(DUMMY_ARRAY, 1);
419 }
420
421 @Override
422 public int[] getRequiredTokens() {
423 return Arrays.copyOf(DUMMY_ARRAY, 1);
424 }
425
426 @Override
427 protected Map<String, String> getCustomMessages() {
428 final Map<String, String> messages = new HashMap<>();
429 messages.put("key", "value");
430 return messages;
431 }
432
433 }
434
435 public static final class VisitCounterCheck extends AbstractCheck {
436
437 private int count;
438
439 @Override
440 public int[] getDefaultTokens() {
441 return CommonUtil.EMPTY_INT_ARRAY;
442 }
443
444 @Override
445 public int[] getAcceptableTokens() {
446 return CommonUtil.EMPTY_INT_ARRAY;
447 }
448
449 @Override
450 public int[] getRequiredTokens() {
451 return CommonUtil.EMPTY_INT_ARRAY;
452 }
453
454 @Override
455 public void visitToken(DetailAST ast) {
456 super.visitToken(ast);
457 count++;
458 }
459 }
460
461 public static class ViolationCheck extends AbstractCheck {
462
463 private static final String MSG_KEY = "Violation.";
464
465 @Override
466 public int[] getDefaultTokens() {
467 return CommonUtil.EMPTY_INT_ARRAY;
468 }
469
470 @Override
471 public int[] getAcceptableTokens() {
472 return CommonUtil.EMPTY_INT_ARRAY;
473 }
474
475 @Override
476 public int[] getRequiredTokens() {
477 return CommonUtil.EMPTY_INT_ARRAY;
478 }
479
480 @Override
481 public void visitToken(DetailAST ast) {
482 log(1, 5, MSG_KEY);
483 log(1, MSG_KEY);
484 }
485
486 }
487
488 public static class ViolationAstCheck extends AbstractCheck {
489
490 private static final String MSG_KEY = "Violation.";
491
492 @Override
493 public int[] getDefaultTokens() {
494 return getRequiredTokens();
495 }
496
497 @Override
498 public int[] getAcceptableTokens() {
499 return getRequiredTokens();
500 }
501
502 @Override
503 public int[] getRequiredTokens() {
504 return new int[] {
505 TokenTypes.PACKAGE_DEF,
506 };
507 }
508
509 @Override
510 public void visitToken(DetailAST ast) {
511 log(ast, MSG_KEY);
512 }
513
514 }
515
516 }