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.checks.whitespace;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.checks.whitespace.GenericWhitespaceCheck.MSG_WS_FOLLOWED;
24 import static com.puppycrawl.tools.checkstyle.checks.whitespace.GenericWhitespaceCheck.MSG_WS_ILLEGAL_FOLLOW;
25 import static com.puppycrawl.tools.checkstyle.checks.whitespace.GenericWhitespaceCheck.MSG_WS_NOT_PRECEDED;
26 import static com.puppycrawl.tools.checkstyle.checks.whitespace.GenericWhitespaceCheck.MSG_WS_PRECEDED;
27
28 import java.io.File;
29 import java.nio.charset.StandardCharsets;
30 import java.util.Optional;
31
32 import org.antlr.v4.runtime.CommonToken;
33 import org.junit.jupiter.api.Test;
34
35 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
36 import com.puppycrawl.tools.checkstyle.DetailAstImpl;
37 import com.puppycrawl.tools.checkstyle.JavaParser;
38 import com.puppycrawl.tools.checkstyle.api.DetailAST;
39 import com.puppycrawl.tools.checkstyle.api.FileContents;
40 import com.puppycrawl.tools.checkstyle.api.FileText;
41 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
42 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
43 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
44
45 public class GenericWhitespaceCheckTest
46 extends AbstractModuleTestSupport {
47
48 @Override
49 protected String getPackageLocation() {
50 return "com/puppycrawl/tools/checkstyle/checks/whitespace/genericwhitespace";
51 }
52
53 @Test
54 public void testGetRequiredTokens() {
55 final GenericWhitespaceCheck checkObj = new GenericWhitespaceCheck();
56 final int[] expected = {
57 TokenTypes.GENERIC_START,
58 TokenTypes.GENERIC_END,
59 };
60 assertWithMessage("Default required tokens are invalid")
61 .that(checkObj.getRequiredTokens())
62 .isEqualTo(expected);
63 }
64
65 @Test
66 public void testDefault() throws Exception {
67 final String[] expected = {
68 "22:14: " + getCheckMessage(MSG_WS_PRECEDED, "<"),
69 "22:14: " + getCheckMessage(MSG_WS_FOLLOWED, "<"),
70 "22:24: " + getCheckMessage(MSG_WS_PRECEDED, ">"),
71 "22:44: " + getCheckMessage(MSG_WS_PRECEDED, "<"),
72 "22:44: " + getCheckMessage(MSG_WS_FOLLOWED, "<"),
73 "22:54: " + getCheckMessage(MSG_WS_PRECEDED, ">"),
74 "22:54: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
75 "23:14: " + getCheckMessage(MSG_WS_PRECEDED, "<"),
76 "23:14: " + getCheckMessage(MSG_WS_FOLLOWED, "<"),
77 "23:21: " + getCheckMessage(MSG_WS_PRECEDED, "<"),
78 "23:21: " + getCheckMessage(MSG_WS_FOLLOWED, "<"),
79 "23:31: " + getCheckMessage(MSG_WS_PRECEDED, ">"),
80 "23:31: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
81 "23:33: " + getCheckMessage(MSG_WS_PRECEDED, ">"),
82 "23:53: " + getCheckMessage(MSG_WS_PRECEDED, "<"),
83 "23:53: " + getCheckMessage(MSG_WS_FOLLOWED, "<"),
84 "23:60: " + getCheckMessage(MSG_WS_PRECEDED, "<"),
85 "23:60: " + getCheckMessage(MSG_WS_FOLLOWED, "<"),
86 "23:70: " + getCheckMessage(MSG_WS_PRECEDED, ">"),
87 "23:70: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
88 "23:72: " + getCheckMessage(MSG_WS_PRECEDED, ">"),
89 "23:72: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
90 "36:18: " + getCheckMessage(MSG_WS_NOT_PRECEDED, "<"),
91 "36:20: " + getCheckMessage(MSG_WS_ILLEGAL_FOLLOW, ">"),
92 "48:22: " + getCheckMessage(MSG_WS_PRECEDED, "<"),
93 "48:29: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
94 "66:35: " + getCheckMessage(MSG_WS_NOT_PRECEDED, "&"),
95 "69:35: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
96 "87:28: " + getCheckMessage(MSG_WS_NOT_PRECEDED, "<"),
97 "88:34: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
98 "89:34: " + getCheckMessage(MSG_WS_NOT_PRECEDED, "<"),
99 "89:41: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
100 "92:26: " + getCheckMessage(MSG_WS_NOT_PRECEDED, "<"),
101 "93:35: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
102 "94:35: " + getCheckMessage(MSG_WS_NOT_PRECEDED, "<"),
103 "94:42: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
104 };
105 verifyWithInlineConfigParser(
106 getPath("InputGenericWhitespaceDefault.java"), expected);
107 }
108
109 @Test
110 public void testAtTheStartOfTheLine() throws Exception {
111 final String[] expected = {
112 "16:2: " + getCheckMessage(MSG_WS_PRECEDED, ">"),
113 "18:2: " + getCheckMessage(MSG_WS_PRECEDED, "<"),
114 };
115 verifyWithInlineConfigParser(
116 getPath("InputGenericWhitespaceAtStartOfTheLine.java"), expected);
117 }
118
119 @Test
120 public void testNestedGeneric() throws Exception {
121 final String[] expected = {
122 "17:1: " + getCheckMessage(MSG_WS_NOT_PRECEDED, "&"),
123 };
124 verifyWithInlineConfigParser(
125 getPath("InputGenericWhitespaceNested.java"), expected);
126 }
127
128 @Test
129 public void testList() throws Exception {
130 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
131 verifyWithInlineConfigParser(
132 getPath("InputGenericWhitespaceList.java"), expected);
133 }
134
135 @Test
136 public void testInnerClass() throws Exception {
137 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
138 verifyWithInlineConfigParser(
139 getPath("InputGenericWhitespaceInnerClass.java"), expected);
140 }
141
142 @Test
143 public void testMethodReferences() throws Exception {
144 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
145 verifyWithInlineConfigParser(
146 getPath("InputGenericWhitespaceMethodRef1.java"), expected);
147 }
148
149 @Test
150 public void testMethodReferences2() throws Exception {
151 final String[] expected = {
152 "16:37: " + getCheckMessage(MSG_WS_FOLLOWED, ">"),
153 };
154 verifyWithInlineConfigParser(
155 getPath("InputGenericWhitespaceMethodRef2.java"), expected);
156 }
157
158 @Test
159 public void testGenericEndsTheLine() throws Exception {
160 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
161 verifyWithInlineConfigParser(
162 getPath("InputGenericWhitespaceEndsTheLine.java"), expected);
163 }
164
165 @Test
166 public void testGenericWhitespaceWithEmoji() throws Exception {
167 final String[] expected = {
168 "35:2: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
169 "40:35: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
170 "40:42: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
171 "44:28: " + getCheckMessage(MSG_WS_NOT_PRECEDED, '<'),
172 "45:53: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
173 };
174 verifyWithInlineConfigParser(
175 getPath("InputGenericWhitespaceWithEmoji.java"), expected);
176 }
177
178 @Test
179 public void testBeforeCtorInvocation() throws Exception {
180 final String[] expected = {
181 "17:31: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
182 "19:56: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
183 "19:56: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
184 "24:25: " + getCheckMessage(MSG_WS_FOLLOWED, '<'),
185 "27:36: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
186 "31:35: " + getCheckMessage(MSG_WS_FOLLOWED, '<'),
187 "31:35: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
188 "31:47: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
189 "31:47: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
190 "38:34: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
191 "39:47: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
192 "40:28: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
193 "40:48: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
194 "47:41: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
195 "50:47: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
196 "52:44: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
197 };
198 verifyWithInlineConfigParser(
199 getPath("InputGenericWhitespaceBeforeCtorInvocation.java"), expected);
200 }
201
202 @Test
203 public void testAfterNew() throws Exception {
204 final String[] expected = {
205 "17:30: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
206 "21:12: " + getCheckMessage(MSG_WS_FOLLOWED, '<'),
207 "21:12: " + getCheckMessage(MSG_WS_NOT_PRECEDED, '<'),
208 "21:23: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
209 "21:23: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
210 "28:22: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
211 "33:31: " + getCheckMessage(MSG_WS_FOLLOWED, '<'),
212 "33:31: " + getCheckMessage(MSG_WS_NOT_PRECEDED, '<'),
213 "33:40: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
214 "33:40: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
215 "41:28: " + getCheckMessage(MSG_WS_NOT_PRECEDED, '<'),
216 "41:36: " + getCheckMessage(MSG_WS_FOLLOWED, '<'),
217 "41:56: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
218 "41:61: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
219 "41:63: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
220 "41:65: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
221 "41:66: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
222 "41:85: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
223 "41:92: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
224 };
225 verifyWithInlineConfigParser(
226 getPath("InputGenericWhitespaceAfterNew.java"), expected);
227 }
228
229 @Test
230 public void testBeforeRecordHeader() throws Exception {
231 final String[] expected = {
232 "17:20: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
233 "18:20: " + getCheckMessage(MSG_WS_FOLLOWED, '<'),
234 "18:20: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
235 "18:24: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
236 "18:24: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
237 "30:27: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
238 "30:38: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
239 "30:80: " + getCheckMessage(MSG_WS_ILLEGAL_FOLLOW, '>'),
240 "36:38: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
241 "43:44: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
242 "43:69: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
243 "49:21: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
244 "49:64: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
245 "49:66: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
246 "56:63: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
247 "56:80: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
248 "62:36: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
249 "62:61: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
250 "67:49: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
251 "73:26: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
252 "73:51: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
253 "73:64: " + getCheckMessage(MSG_WS_FOLLOWED, '<'),
254 "80:26: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
255 "80:34: " + getCheckMessage(MSG_WS_FOLLOWED, '<'),
256 "80:55: " + getCheckMessage(MSG_WS_ILLEGAL_FOLLOW, '>'),
257 "91:25: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
258 "91:44: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
259 "91:47: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
260 "91:61: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
261 "91:71: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
262 "91:73: " + getCheckMessage(MSG_WS_PRECEDED, '>'),
263 "101:25: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
264 "101:58: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
265 "108:25: " + getCheckMessage(MSG_WS_PRECEDED, '<'),
266 "108:32: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
267 "108:46: " + getCheckMessage(MSG_WS_FOLLOWED, '<'),
268 "108:63: " + getCheckMessage(MSG_WS_FOLLOWED, '>'),
269 };
270 verifyWithInlineConfigParser(
271 getNonCompilablePath("InputGenericWhitespaceBeforeRecordHeader.java"),
272 expected);
273 }
274
275
276
277
278
279
280
281 @Test
282 public void testClearState() throws Exception {
283 final GenericWhitespaceCheck check = new GenericWhitespaceCheck();
284 final FileText fileText = new FileText(
285 new File(getPath("InputGenericWhitespaceDefault.java")),
286 StandardCharsets.UTF_8.name());
287 check.setFileContents(new FileContents(fileText));
288 final DetailAST root = JavaParser.parseFileText(fileText,
289 JavaParser.Options.WITHOUT_COMMENTS);
290 final Optional<DetailAST> genericStart = TestUtil.findTokenInAstByPredicate(root,
291 ast -> ast.getType() == TokenTypes.GENERIC_START);
292
293 assertWithMessage("Ast should contain GENERIC_START")
294 .that(genericStart.isPresent())
295 .isTrue();
296 assertWithMessage("State is not cleared on beginTree")
297 .that(
298 TestUtil.isStatefulFieldClearedDuringBeginTree(check,
299 genericStart.orElseThrow(), "depth",
300 depth -> ((Number) depth).intValue() == 0))
301 .isTrue();
302 }
303
304 @Test
305 public void testGetAcceptableTokens() {
306 final GenericWhitespaceCheck genericWhitespaceCheckObj = new GenericWhitespaceCheck();
307 final int[] actual = genericWhitespaceCheckObj.getAcceptableTokens();
308 final int[] expected = {
309 TokenTypes.GENERIC_START,
310 TokenTypes.GENERIC_END,
311 };
312 assertWithMessage("Default acceptable tokens are invalid")
313 .that(actual)
314 .isEqualTo(expected);
315 }
316
317 @Test
318 public void testWrongTokenType() {
319 final GenericWhitespaceCheck genericWhitespaceCheckObj = new GenericWhitespaceCheck();
320 final DetailAstImpl ast = new DetailAstImpl();
321 ast.initialize(new CommonToken(TokenTypes.INTERFACE_DEF, "interface"));
322 try {
323 genericWhitespaceCheckObj.visitToken(ast);
324 assertWithMessage("exception expected").fail();
325 }
326 catch (IllegalArgumentException ex) {
327 assertWithMessage("Invalid exception message")
328 .that(ex.getMessage())
329 .isEqualTo("Unknown type interface[0x-1]");
330 }
331 }
332
333 }