View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2026 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.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck.MSG_KEY;
23  import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
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      public 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              "19:18: " + getCheckMessage(MSG_KEY, "runnable"),
47              "29:13: " + getCheckMessage(MSG_KEY, "i"),
48              "33:13: " + getCheckMessage(MSG_KEY, "z"),
49              "35:16: " + getCheckMessage(MSG_KEY, "obj"),
50              "39:16: " + getCheckMessage(MSG_KEY, "x"),
51              "45:18: " + getCheckMessage(MSG_KEY, "runnable"),
52              "49:21: " + getCheckMessage(MSG_KEY, "q"),
53              "65:13: " + getCheckMessage(MSG_KEY, "i"),
54              "69:13: " + getCheckMessage(MSG_KEY, "z"),
55              "71:16: " + getCheckMessage(MSG_KEY, "obj"),
56              "75:16: " + getCheckMessage(MSG_KEY, "x"),
57              "83:21: " + getCheckMessage(MSG_KEY, "w"),
58              "85: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             "89: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             "62:25: " + getCheckMessage(MSG_KEY, "shouldBeFinal"),
113             "83: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                 getPath("InputFinalLocalVariableCheckRecords.java"), expected);
126     }
127 
128     @Test
129     public void testInputFinalLocalVariable2One() throws Exception {
130 
131         final String[] expected = {
132             "53: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 = CommonUtil.EMPTY_STRING_ARRAY;
153         verifyWithInlineConfigParser(
154                 getPath("InputFinalLocalVariable2Three.java"), excepted);
155     }
156 
157     @Test
158     public void testInputFinalLocalVariable2Four() throws Exception {
159 
160         final String[] excepted = CommonUtil.EMPTY_STRING_ARRAY;
161         verifyWithInlineConfigParser(
162                 getPath("InputFinalLocalVariable2Four.java"), excepted);
163     }
164 
165     @Test
166     public void testInputFinalLocalVariable2Five() throws Exception {
167 
168         final String[] excepted = CommonUtil.EMPTY_STRING_ARRAY;
169         verifyWithInlineConfigParser(
170                 getPath("InputFinalLocalVariable2Five.java"), excepted);
171     }
172 
173     @Test
174     public void testNativeMethods() throws Exception {
175 
176         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
177         verifyWithInlineConfigParser(
178                 getPath("InputFinalLocalVariableNativeMethods.java"), expected);
179     }
180 
181     @Test
182     public void testFalsePositive() throws Exception {
183 
184         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
185         verifyWithInlineConfigParser(
186                 getPath("InputFinalLocalVariableFalsePositive.java"), expected);
187     }
188 
189     @Test
190     public void testEnhancedForLoopVariableTrue() throws Exception {
191         final String[] expected = {
192             "16:20: " + getCheckMessage(MSG_KEY, "a"),
193             "23:13: " + getCheckMessage(MSG_KEY, "x"),
194             "29:66: " + getCheckMessage(MSG_KEY, "snippets"),
195             "31:32: " + getCheckMessage(MSG_KEY, "filteredSnippets"),
196             "33:21: " + getCheckMessage(MSG_KEY, "snippet"),
197             "48:20: " + getCheckMessage(MSG_KEY, "a"),
198             "51:16: " + getCheckMessage(MSG_KEY, "a"),
199         };
200         verifyWithInlineConfigParser(
201                 getPath("InputFinalLocalVariableEnhancedForLoopVariable.java"),
202             expected);
203     }
204 
205     @Test
206     public void testEnhancedForLoopVariableFalse() throws Exception {
207         final String[] expected = {
208             "23:13: " + getCheckMessage(MSG_KEY, "x"),
209             "29:66: " + getCheckMessage(MSG_KEY, "snippets"),
210             "31:32: " + getCheckMessage(MSG_KEY, "filteredSnippets"),
211             "50:16: " + getCheckMessage(MSG_KEY, "a"),
212         };
213         verifyWithInlineConfigParser(
214                 getPath("InputFinalLocalVariableEnhancedForLoopVariable2.java"),
215             expected);
216     }
217 
218     @Test
219     public void testLambda() throws Exception {
220         final String[] expected = {
221             "43:16: " + getCheckMessage(MSG_KEY, "result"),
222         };
223         verifyWithInlineConfigParser(
224                 getPath("InputFinalLocalVariableNameLambda.java"),
225             expected);
226     }
227 
228     @Test
229     public void testVariableNameShadowing() throws Exception {
230 
231         final String[] expected = {
232             "12:28: " + getCheckMessage(MSG_KEY, "text"),
233             "25:13: " + getCheckMessage(MSG_KEY, "x"),
234         };
235         verifyWithInlineConfigParser(
236                 getPath("InputFinalLocalVariableNameShadowing.java"), expected);
237     }
238 
239     @Test
240     public void testImproperToken() {
241         final FinalLocalVariableCheck check = new FinalLocalVariableCheck();
242 
243         final DetailAstImpl lambdaAst = new DetailAstImpl();
244         lambdaAst.setType(TokenTypes.LAMBDA);
245 
246         getExpectedThrowable(IllegalStateException.class,
247                 () -> check.visitToken(lambdaAst));
248     }
249 
250     @Test
251     public void testVariableWhichIsAssignedMultipleTimes() throws Exception {
252 
253         final String[] expected = {
254             "57:13: " + getCheckMessage(MSG_KEY, "i"),
255             "130:16: " + getCheckMessage(MSG_KEY, "path"),
256             "135:20: " + getCheckMessage(MSG_KEY, "relativePath"),
257             "211:17: " + getCheckMessage(MSG_KEY, "kind"),
258             "216:24: " + getCheckMessage(MSG_KEY, "m"),
259             "418:17: " + getCheckMessage(MSG_KEY, "increment"),
260         };
261         verifyWithInlineConfigParser(
262                 getPath("InputFinalLocalVariableAssignedMultipleTimes.java"), expected);
263     }
264 
265     @Test
266     public void testVariableIsAssignedInsideAndOutsideSwitchBlock() throws Exception {
267         final String[] expected = {
268             "39:13: " + getCheckMessage(MSG_KEY, "b"),
269         };
270         verifyWithInlineConfigParser(
271                 getPath("InputFinalLocalVariableAssignedInsideAndOutsideSwitch.java"),
272             expected);
273     }
274 
275     @Test
276     public void testFinalLocalVariableFalsePositives() throws Exception {
277         final String[] expected = {
278             "352:16: " + getCheckMessage(MSG_KEY, "c2"),
279             "2195:16: " + getCheckMessage(MSG_KEY, "b"),
280         };
281         verifyWithInlineConfigParser(
282                 getPath("InputFinalLocalVariableFalsePositives.java"), expected);
283     }
284 
285     @Test
286     public void testMultipleAndNestedConditions() throws Exception {
287         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
288         verifyWithInlineConfigParser(
289                 getPath("InputFinalLocalVariableMultipleAndNestedConditions.java"),
290             expected);
291     }
292 
293     @Test
294     public void testMultiTypeCatchAdjacentCatches() throws Exception {
295         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
296         verifyWithInlineConfigParser(
297                 getPath("InputFinalLocalVariableMultiCatchAdjacentCatches.java"),
298                 expected);
299     }
300 
301     @Test
302     public void testMultiTypeCatchNested() throws Exception {
303         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
304         verifyWithInlineConfigParser(
305                 getPath("InputFinalLocalVariableMultiCatchNested.java"),
306                 expected);
307     }
308 
309     @Test
310     public void testLeavingSlistToken() throws Exception {
311         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
312         verifyWithInlineConfigParser(
313                 getPath("InputFinalLocalVariableLeavingSlistToken.java"), expected);
314     }
315 
316     @Test
317     public void testBreakOrReturn() throws Exception {
318         final String[] expected = {
319             "15:19: " + getCheckMessage(MSG_KEY, "e"),
320         };
321         verifyWithInlineConfigParser(
322                 getPath("InputFinalLocalVariableBreak.java"), expected);
323     }
324 
325     @Test
326     public void testAnonymousClass() throws Exception {
327         final String[] expected = {
328             "14:16: " + getCheckMessage(MSG_KEY, "testSupport"),
329         };
330         verifyWithInlineConfigParser(
331                 getPath("InputFinalLocalVariableAnonymousClass.java"), expected);
332     }
333 
334     @Test
335     public void testReceiverParameter() throws Exception {
336         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
337         verifyWithInlineConfigParser(
338                 getPath("InputFinalLocalVariableReceiverParameter.java"), expected);
339     }
340 
341     @Test
342     public void testFinalLocalVariableSwitchExpressionsA() throws Exception {
343         final String[] expected = {
344             "15:19: " + getCheckMessage(MSG_KEY, "e"),
345             "53:19: " + getCheckMessage(MSG_KEY, "e"),
346         };
347         verifyWithInlineConfigParser(
348                 getNonCompilablePath("InputFinalLocalVariableCheckSwitchExpressionsA.java"),
349             expected);
350     }
351 
352     @Test
353     public void testFinalLocalVariableSwitchExpressionsB() throws Exception {
354         final String[] expected = {
355             "16:19: " + getCheckMessage(MSG_KEY, "e"),
356             "50:19: " + getCheckMessage(MSG_KEY, "e"),
357         };
358         verifyWithInlineConfigParser(
359                 getNonCompilablePath("InputFinalLocalVariableCheckSwitchExpressionsB.java"),
360             expected);
361     }
362 
363     @Test
364     public void testFinalLocalVariableSwitchExpressionsC() throws Exception {
365         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
366 
367         verifyWithInlineConfigParser(
368                 getNonCompilablePath("InputFinalLocalVariableCheckSwitchExpressionsC.java"),
369             expected);
370     }
371 
372     @Test
373     public void testFinalLocalVariableSwitchAssignment() throws Exception {
374         final String[] expected = {
375             "21:13: " + getCheckMessage(MSG_KEY, "a"),
376             "44:13: " + getCheckMessage(MSG_KEY, "b"),
377             "46:21: " + getCheckMessage(MSG_KEY, "x"),
378             "72:16: " + getCheckMessage(MSG_KEY, "res"),
379             "92:16: " + getCheckMessage(MSG_KEY, "res"),
380         };
381         verifyWithInlineConfigParser(
382                 getPath("InputFinalLocalVariableCheckSwitchAssignment.java"),
383             expected);
384     }
385 
386     @Test
387     public void testFinalLocalVariableSwitchStatement() throws Exception {
388         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
389         verifyWithInlineConfigParser(
390             getPath("InputFinalLocalVariableSwitchStatement.java"),
391             expected);
392     }
393 
394     @Test
395     public void testConstructor() throws Exception {
396         final String[] expected = {
397             "14:44: " + getCheckMessage(MSG_KEY, "a"),
398             "18:44: " + getCheckMessage(MSG_KEY, "a"),
399             "19:43: " + getCheckMessage(MSG_KEY, "b"),
400             "22:47: " + getCheckMessage(MSG_KEY, "str"),
401             "35:21: " + getCheckMessage(MSG_KEY, "str"),
402         };
403         verifyWithInlineConfigParser(
404             getPath("InputFinalLocalVariableConstructor.java"),
405             expected);
406     }
407 
408     @Test
409     public void test() throws Exception {
410         final String[] expected = {
411             "22:17: " + getCheckMessage(MSG_KEY, "start"),
412             "24:17: " + getCheckMessage(MSG_KEY, "end"),
413             "42:38: " + getCheckMessage(MSG_KEY, "list"),
414             "45:38: " + getCheckMessage(MSG_KEY, "forEach"),
415             "47:38: " + getCheckMessage(MSG_KEY, "body"),
416         };
417         verifyWithInlineConfigParser(
418             getPath("InputFinalLocalVariable3.java"),
419             expected);
420     }
421 
422     @Test
423     public void testValidateUnnamedVariablesTrue() throws Exception {
424         final String[] expected = {
425             "21:22: " + getCheckMessage(MSG_KEY, "i"),
426             "22:17: " + getCheckMessage(MSG_KEY, "_"),
427             "23:17: " + getCheckMessage(MSG_KEY, "__"),
428             "26:13: " + getCheckMessage(MSG_KEY, "_"),
429             "27:13: " + getCheckMessage(MSG_KEY, "_result"),
430             "32:18: " + getCheckMessage(MSG_KEY, "_"),
431             "44:18: " + getCheckMessage(MSG_KEY, "_"),
432             "50:18: " + getCheckMessage(MSG_KEY, "__"),
433         };
434         verifyWithInlineConfigParser(
435                 getNonCompilablePath("InputFinalLocalVariableValidateUnnamedVariablesTrue.java"),
436             expected);
437     }
438 
439     @Test
440     public void testValidateUnnamedVariablesFalse() throws Exception {
441         final String[] expected = {
442             "21:22: " + getCheckMessage(MSG_KEY, "i"),
443             "23:17: " + getCheckMessage(MSG_KEY, "__"),
444             "27:13: " + getCheckMessage(MSG_KEY, "_result"),
445             "50:18: " + getCheckMessage(MSG_KEY, "__"),
446         };
447         verifyWithInlineConfigParser(
448                 getNonCompilablePath("InputFinalLocalVariableValidateUnnamedVariablesFalse.java"),
449             expected);
450     }
451 
452     @Test
453     public void test1() throws Exception {
454         final String[] expected = {
455             "13:34: " + getCheckMessage(MSG_KEY, "param"),
456             "14:20: " + getCheckMessage(MSG_KEY, "local"),
457             "20:32: " + getCheckMessage(MSG_KEY, "aParam"),
458             "23:40: " + getCheckMessage(MSG_KEY, "num"),
459             "28:42: " + getCheckMessage(MSG_KEY, "e"),
460         };
461         verifyWithInlineConfigParser(
462             getPath("InputFinalLocalVariableInterface.java"),
463             expected);
464     }
465 
466     @Test
467     public void testCompactSourceFile() throws Exception {
468         final String[] expected = {
469             "18:9: " + getCheckMessage(MSG_KEY, "lambdaLocal"),
470             "24:13: " + getCheckMessage(MSG_KEY, "branchLocal"),
471             "31:9: " + getCheckMessage(MSG_KEY, "local"),
472         };
473         verifyWithInlineConfigParser(
474                 getNonCompilablePath("InputFinalLocalVariableCompactSourceFile.java"),
475             expected);
476     }
477 }