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.checks.coding;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck.MSG_KEY;
24  
25  import org.junit.jupiter.api.Test;
26  
27  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
28  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
29  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
30  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
31  
32  public class FinalLocalVariableCheckTest
33      extends AbstractModuleTestSupport {
34  
35      @Override
36      protected String getPackageLocation() {
37          return "com/puppycrawl/tools/checkstyle/checks/coding/finallocalvariable";
38      }
39  
40      @Test
41      public void testInputFinalLocalVariableOne() throws Exception {
42  
43          final String[] expected = {
44              "17:13: " + getCheckMessage(MSG_KEY, "i"),
45              "17:16: " + getCheckMessage(MSG_KEY, "j"),
46              "18:18: " + getCheckMessage(MSG_KEY, "runnable"),
47              "28:13: " + getCheckMessage(MSG_KEY, "i"),
48              "32:13: " + getCheckMessage(MSG_KEY, "z"),
49              "34:16: " + getCheckMessage(MSG_KEY, "obj"),
50              "38:16: " + getCheckMessage(MSG_KEY, "x"),
51              "44:18: " + getCheckMessage(MSG_KEY, "runnable"),
52              "48:21: " + getCheckMessage(MSG_KEY, "q"),
53              "64:13: " + getCheckMessage(MSG_KEY, "i"),
54              "68:13: " + getCheckMessage(MSG_KEY, "z"),
55              "70:16: " + getCheckMessage(MSG_KEY, "obj"),
56              "74:16: " + getCheckMessage(MSG_KEY, "x"),
57              "82:21: " + getCheckMessage(MSG_KEY, "w"),
58              "83:26: " + getCheckMessage(MSG_KEY, "runnable"),
59          };
60          verifyWithInlineConfigParser(
61                  getPath("InputFinalLocalVariableOne.java"), expected);
62      }
63  
64      @Test
65      public void testInputFinalLocalVariableTwo() throws Exception {
66          final String[] expected = {
67              "24:17: " + getCheckMessage(MSG_KEY, "weird"),
68              "25:17: " + getCheckMessage(MSG_KEY, "j"),
69              "26:17: " + getCheckMessage(MSG_KEY, "k"),
70          };
71          verifyWithInlineConfigParser(
72                  getPath("InputFinalLocalVariableTwo.java"), expected);
73      }
74  
75      @Test
76      public void testInputFinalLocalVariableThree() throws Exception {
77          final String[] expected = {
78              "14:17: " + getCheckMessage(MSG_KEY, "x"),
79              "20:21: " + getCheckMessage(MSG_KEY, "x"),
80              "41:21: " + getCheckMessage(MSG_KEY, "n"),
81              "47:17: " + getCheckMessage(MSG_KEY, "q"),
82              "48:17: " + getCheckMessage(MSG_KEY, "w"),
83              "57:25: " + getCheckMessage(MSG_KEY, "w"),
84              "58:25: " + getCheckMessage(MSG_KEY, "e"),
85              "79:21: " + getCheckMessage(MSG_KEY, "n"),
86              "92:21: " + getCheckMessage(MSG_KEY, "t"),
87              "102:25: " + getCheckMessage(MSG_KEY, "foo"),
88          };
89          verifyWithInlineConfigParser(
90                  getPath("InputFinalLocalVariableThree.java"), expected);
91      }
92  
93      @Test
94      public void testInputFinalLocalVariableFour() throws Exception {
95          final String[] expected = {
96              "16:17: " + getCheckMessage(MSG_KEY, "shouldBeFinal"),
97              "28:17: " + getCheckMessage(MSG_KEY, "shouldBeFinal"),
98              "72:17: " + getCheckMessage(MSG_KEY, "shouldBeFinal"),
99              "85:17: " + getCheckMessage(MSG_KEY, "shouldBeFinal"),
100             "88:25: " + getCheckMessage(MSG_KEY, "shouldBeFinal"),
101         };
102         verifyWithInlineConfigParser(
103                 getPath("InputFinalLocalVariableFour.java"), expected);
104     }
105 
106     @Test
107     public void testFinalLocalVariableFive() throws Exception {
108         final String[] expected = {
109             "15:17: " + getCheckMessage(MSG_KEY, "shouldBeFinal"),
110             "26:17: " + getCheckMessage(MSG_KEY, "shouldBeFinal"),
111             "58:17: " + getCheckMessage(MSG_KEY, "shouldBeFinal"),
112             "61:25: " + getCheckMessage(MSG_KEY, "shouldBeFinal"),
113             "81:41: " + getCheckMessage(MSG_KEY, "table"),
114         };
115         verifyWithInlineConfigParser(
116                 getPath("InputFinalLocalVariableFive.java"), expected);
117     }
118 
119     @Test
120     public void testRecordsInput() throws Exception {
121         final String[] expected = {
122             "20:17: " + getCheckMessage(MSG_KEY, "b"),
123         };
124         verifyWithInlineConfigParser(
125                 getNonCompilablePath("InputFinalLocalVariableCheckRecords.java"), expected);
126     }
127 
128     @Test
129     public void testInputFinalLocalVariable2One() throws Exception {
130 
131         final String[] expected = {
132             "52:28: " + getCheckMessage(MSG_KEY, "aArg"),
133         };
134         verifyWithInlineConfigParser(
135                 getPath("InputFinalLocalVariable2One.java"), expected);
136     }
137 
138     @Test
139     public void testInputFinalLocalVariable2Two() throws Exception {
140 
141         final String[] excepted = {
142             "78:36: " + getCheckMessage(MSG_KEY, "_o"),
143             "83:37: " + getCheckMessage(MSG_KEY, "_o1"),
144         };
145         verifyWithInlineConfigParser(
146                 getPath("InputFinalLocalVariable2Two.java"), excepted);
147     }
148 
149     @Test
150     public void testInputFinalLocalVariable2Three() throws Exception {
151 
152         final String[] excepted = {
153 
154         };
155         verifyWithInlineConfigParser(
156                 getPath("InputFinalLocalVariable2Three.java"), excepted);
157     }
158 
159     @Test
160     public void testInputFinalLocalVariable2Four() throws Exception {
161 
162         final String[] excepted = {
163 
164         };
165         verifyWithInlineConfigParser(
166                 getPath("InputFinalLocalVariable2Four.java"), excepted);
167     }
168 
169     @Test
170     public void testInputFinalLocalVariable2Five() throws Exception {
171 
172         final String[] excepted = {
173 
174         };
175         verifyWithInlineConfigParser(
176                 getPath("InputFinalLocalVariable2Five.java"), excepted);
177     }
178 
179     @Test
180     public void testNativeMethods() throws Exception {
181 
182         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
183         verifyWithInlineConfigParser(
184                 getPath("InputFinalLocalVariableNativeMethods.java"), expected);
185     }
186 
187     @Test
188     public void testFalsePositive() throws Exception {
189 
190         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
191         verifyWithInlineConfigParser(
192                 getPath("InputFinalLocalVariableFalsePositive.java"), expected);
193     }
194 
195     @Test
196     public void testEnhancedForLoopVariableTrue() throws Exception {
197         final String[] expected = {
198             "16:20: " + getCheckMessage(MSG_KEY, "a"),
199             "23:13: " + getCheckMessage(MSG_KEY, "x"),
200             "29:66: " + getCheckMessage(MSG_KEY, "snippets"),
201             "30:32: " + getCheckMessage(MSG_KEY, "filteredSnippets"),
202             "31:21: " + getCheckMessage(MSG_KEY, "snippet"),
203             "46:20: " + getCheckMessage(MSG_KEY, "a"),
204             "49:16: " + getCheckMessage(MSG_KEY, "a"),
205         };
206         verifyWithInlineConfigParser(
207                 getPath("InputFinalLocalVariableEnhancedForLoopVariable.java"),
208             expected);
209     }
210 
211     @Test
212     public void testEnhancedForLoopVariableFalse() throws Exception {
213         final String[] expected = {
214             "23:13: " + getCheckMessage(MSG_KEY, "x"),
215             "29:66: " + getCheckMessage(MSG_KEY, "snippets"),
216             "30:32: " + getCheckMessage(MSG_KEY, "filteredSnippets"),
217             "49:16: " + getCheckMessage(MSG_KEY, "a"),
218         };
219         verifyWithInlineConfigParser(
220                 getPath("InputFinalLocalVariableEnhancedForLoopVariable2.java"),
221             expected);
222     }
223 
224     @Test
225     public void testLambda()
226             throws Exception {
227         final String[] expected = {
228             "40:16: " + getCheckMessage(MSG_KEY, "result"),
229         };
230         verifyWithInlineConfigParser(
231                 getPath("InputFinalLocalVariableNameLambda.java"),
232             expected);
233     }
234 
235     @Test
236     public void testVariableNameShadowing()
237             throws Exception {
238 
239         final String[] expected = {
240             "12:28: " + getCheckMessage(MSG_KEY, "text"),
241             "25:13: " + getCheckMessage(MSG_KEY, "x"),
242         };
243         verifyWithInlineConfigParser(
244                 getPath("InputFinalLocalVariableNameShadowing.java"), expected);
245     }
246 
247     @Test
248     public void testImproperToken() {
249         final FinalLocalVariableCheck check = new FinalLocalVariableCheck();
250 
251         final DetailAstImpl lambdaAst = new DetailAstImpl();
252         lambdaAst.setType(TokenTypes.LAMBDA);
253 
254         try {
255             check.visitToken(lambdaAst);
256             assertWithMessage("IllegalStateException is expected").fail();
257         }
258         catch (IllegalStateException ex) {
259             // it is OK
260         }
261     }
262 
263     @Test
264     public void testVariableWhichIsAssignedMultipleTimes() throws Exception {
265 
266         final String[] expected = {
267             "57:13: " + getCheckMessage(MSG_KEY, "i"),
268             "130:16: " + getCheckMessage(MSG_KEY, "path"),
269             "134:20: " + getCheckMessage(MSG_KEY, "relativePath"),
270             "210:17: " + getCheckMessage(MSG_KEY, "kind"),
271             "215:24: " + getCheckMessage(MSG_KEY, "m"),
272             "417:17: " + getCheckMessage(MSG_KEY, "increment"),
273         };
274         verifyWithInlineConfigParser(
275                 getPath("InputFinalLocalVariableAssignedMultipleTimes.java"), expected);
276     }
277 
278     @Test
279     public void testVariableIsAssignedInsideAndOutsideSwitchBlock() throws Exception {
280         final String[] expected = {
281             "39:13: " + getCheckMessage(MSG_KEY, "b"),
282         };
283         verifyWithInlineConfigParser(
284                 getPath("InputFinalLocalVariableAssignedInsideAndOutsideSwitch.java"),
285             expected);
286     }
287 
288     @Test
289     public void testFinalLocalVariableFalsePositives() throws Exception {
290         final String[] expected = {
291             "352:16: " + getCheckMessage(MSG_KEY, "c2"),
292             "2195:16: " + getCheckMessage(MSG_KEY, "b"),
293         };
294         verifyWithInlineConfigParser(
295                 getPath("InputFinalLocalVariableFalsePositives.java"), expected);
296     }
297 
298     @Test
299     public void testMultipleAndNestedConditions() throws Exception {
300         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
301         verifyWithInlineConfigParser(
302                 getPath("InputFinalLocalVariableMultipleAndNestedConditions.java"),
303             expected);
304     }
305 
306     @Test
307     public void testMultiTypeCatch() throws Exception {
308         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
309         verifyWithInlineConfigParser(
310                 getPath("InputFinalLocalVariableMultiCatch.java"),
311                 expected);
312     }
313 
314     @Test
315     public void testLeavingSlistToken() throws Exception {
316         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
317         verifyWithInlineConfigParser(
318                 getPath("InputFinalLocalVariableLeavingSlistToken.java"), expected);
319     }
320 
321     @Test
322     public void testBreakOrReturn() throws Exception {
323         final String[] expected = {
324             "15:19: " + getCheckMessage(MSG_KEY, "e"),
325         };
326         verifyWithInlineConfigParser(
327                 getPath("InputFinalLocalVariableBreak.java"), expected);
328     }
329 
330     @Test
331     public void testAnonymousClass() throws Exception {
332         final String[] expected = {
333             "13:16: " + getCheckMessage(MSG_KEY, "testSupport"),
334         };
335         verifyWithInlineConfigParser(
336                 getPath("InputFinalLocalVariableAnonymousClass.java"), expected);
337     }
338 
339     @Test
340     public void testReceiverParameter() throws Exception {
341         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
342         verifyWithInlineConfigParser(
343                 getPath("InputFinalLocalVariableReceiverParameter.java"), expected);
344     }
345 
346     @Test
347     public void testFinalLocalVariableSwitchExpressions() throws Exception {
348         final String[] expected = {
349             "15:19: " + getCheckMessage(MSG_KEY, "e"),
350             "53:19: " + getCheckMessage(MSG_KEY, "e"),
351             "91:19: " + getCheckMessage(MSG_KEY, "e"),
352             "125:19: " + getCheckMessage(MSG_KEY, "e"),
353         };
354         verifyWithInlineConfigParser(
355                 getNonCompilablePath("InputFinalLocalVariableCheckSwitchExpressions.java"),
356             expected);
357     }
358 
359     @Test
360     public void testFinalLocalVariableSwitchAssignment() throws Exception {
361         final String[] expected = {
362             "21:13: " + getCheckMessage(MSG_KEY, "a"),
363             "44:13: " + getCheckMessage(MSG_KEY, "b"),
364             "46:21: " + getCheckMessage(MSG_KEY, "x"),
365             "72:16: " + getCheckMessage(MSG_KEY, "res"),
366             "92:16: " + getCheckMessage(MSG_KEY, "res"),
367         };
368         verifyWithInlineConfigParser(
369                 getNonCompilablePath("InputFinalLocalVariableCheckSwitchAssignment.java"),
370             expected);
371     }
372 
373     @Test
374     public void testFinalLocalVariableSwitchStatement() throws Exception {
375         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
376         verifyWithInlineConfigParser(
377             getPath("InputFinalLocalVariableSwitchStatement.java"),
378             expected);
379     }
380 
381     @Test
382     public void testConstructor() throws Exception {
383         final String[] expected = {
384             "14:44: " + getCheckMessage(MSG_KEY, "a"),
385             "18:44: " + getCheckMessage(MSG_KEY, "a"),
386             "19:43: " + getCheckMessage(MSG_KEY, "b"),
387             "22:47: " + getCheckMessage(MSG_KEY, "str"),
388             "35:21: " + getCheckMessage(MSG_KEY, "str"),
389         };
390         verifyWithInlineConfigParser(
391             getPath("InputFinalLocalVariableConstructor.java"),
392             expected);
393     }
394 
395     @Test
396     public void test() throws Exception {
397         final String[] expected = {
398             "20:17: " + getCheckMessage(MSG_KEY, "start"),
399             "22:17: " + getCheckMessage(MSG_KEY, "end"),
400             "40:38: " + getCheckMessage(MSG_KEY, "list"),
401             "43:38: " + getCheckMessage(MSG_KEY, "forEach"),
402             "45:38: " + getCheckMessage(MSG_KEY, "body"),
403         };
404         verifyWithInlineConfigParser(
405             getPath("InputFinalLocalVariable3.java"),
406             expected);
407     }
408 
409     @Test
410     public void testValidateUnnamedVariablesTrue() throws Exception {
411         final String[] expected = {
412             "21:22: " + getCheckMessage(MSG_KEY, "i"),
413             "22:17: " + getCheckMessage(MSG_KEY, "_"),
414             "23:17: " + getCheckMessage(MSG_KEY, "__"),
415             "26:13: " + getCheckMessage(MSG_KEY, "_"),
416             "27:13: " + getCheckMessage(MSG_KEY, "_result"),
417             "32:18: " + getCheckMessage(MSG_KEY, "_"),
418             "44:18: " + getCheckMessage(MSG_KEY, "_"),
419             "50:18: " + getCheckMessage(MSG_KEY, "__"),
420         };
421         verifyWithInlineConfigParser(
422                 getNonCompilablePath("InputFinalLocalVariableValidateUnnamedVariablesTrue.java"),
423             expected);
424     }
425 
426     @Test
427     public void testValidateUnnamedVariablesFalse() throws Exception {
428         final String[] expected = {
429             "21:22: " + getCheckMessage(MSG_KEY, "i"),
430             "23:17: " + getCheckMessage(MSG_KEY, "__"),
431             "27:13: " + getCheckMessage(MSG_KEY, "_result"),
432             "50:18: " + getCheckMessage(MSG_KEY, "__"),
433         };
434         verifyWithInlineConfigParser(
435                 getNonCompilablePath("InputFinalLocalVariableValidateUnnamedVariablesFalse.java"),
436             expected);
437     }
438 }