View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2025 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 org.checkstyle.suppressionxpathfilter.indentation;
21  
22  import java.io.File;
23  import java.util.Arrays;
24  import java.util.Collections;
25  import java.util.List;
26  
27  import org.checkstyle.suppressionxpathfilter.AbstractXpathTestSupport;
28  import org.junit.jupiter.api.Test;
29  
30  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
31  import com.puppycrawl.tools.checkstyle.checks.indentation.IndentationCheck;
32  
33  public class XpathRegressionIndentationTest extends AbstractXpathTestSupport {
34      private final String checkName = IndentationCheck.class.getSimpleName();
35  
36      @Override
37      protected String getCheckName() {
38          return checkName;
39      }
40  
41      @Override
42      protected String getPackageLocation() {
43          return "org/checkstyle/suppressionxpathfilter/indentation/indentation";
44      }
45  
46      @Test
47      public void testDefault() throws Exception {
48          final File fileToProcess =
49                  new File(getPath("InputXpathIndentationDefault.java"));
50  
51          final DefaultConfiguration moduleConfig =
52                  createModuleConfig(IndentationCheck.class);
53  
54          final String[] expectedViolation = {
55              "4:1: " + getCheckMessage(IndentationCheck.class,
56                      IndentationCheck.MSG_ERROR, "method def modifier", 0, 4),
57          };
58  
59          final List<String> expectedXpathQueries = Arrays.asList(
60              "/COMPILATION_UNIT/CLASS_DEF"
61                      + "[./IDENT[@text='InputXpathIndentationDefault']]"
62                      + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='wrongIntend']]",
63  
64               "/COMPILATION_UNIT/CLASS_DEF"
65                       + "[./IDENT[@text='InputXpathIndentationDefault']]"
66                      + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='wrongIntend']]/MODIFIERS",
67  
68              "/COMPILATION_UNIT/CLASS_DEF"
69                      + "[./IDENT[@text='InputXpathIndentationDefault']]"
70                      + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='wrongIntend']]/TYPE",
71  
72              "/COMPILATION_UNIT/CLASS_DEF"
73                      + "[./IDENT[@text='InputXpathIndentationDefault']]"
74                      + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='wrongIntend']]/TYPE/LITERAL_VOID"
75          );
76  
77          runVerifications(moduleConfig, fileToProcess, expectedViolation,
78                  expectedXpathQueries);
79      }
80  
81      @Test
82      public void testBasicOffset() throws Exception {
83          final File fileToProcess =
84                  new File(getPath("InputXpathIndentationBasicOffset.java"));
85  
86          final DefaultConfiguration moduleConfig =
87                  createModuleConfig(IndentationCheck.class);
88          moduleConfig.addProperty("arrayInitIndent", "4");
89          moduleConfig.addProperty("basicOffset", "10");
90          moduleConfig.addProperty("braceAdjustment", "0");
91          moduleConfig.addProperty("caseIndent", "4");
92          moduleConfig.addProperty("forceStrictCondition", "false");
93          moduleConfig.addProperty("lineWrappingIndentation", "4");
94          moduleConfig.addProperty("tabWidth", "4");
95          moduleConfig.addProperty("throwsIndent", "4");
96  
97          final String[] expectedViolation = {
98              "4:5: " + getCheckMessage(IndentationCheck.class,
99                      IndentationCheck.MSG_ERROR, "method def modifier", 4, 10),
100         };
101 
102         final List<String> expectedXpathQueries = Arrays.asList(
103             "/COMPILATION_UNIT/CLASS_DEF"
104                     + "[./IDENT[@text='InputXpathIndentationBasicOffset']]"
105                     + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]",
106 
107             "/COMPILATION_UNIT/CLASS_DEF"
108                     + "[./IDENT[@text='InputXpathIndentationBasicOffset']]"
109                     + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/MODIFIERS",
110 
111             "/COMPILATION_UNIT/CLASS_DEF"
112                     + "[./IDENT[@text='InputXpathIndentationBasicOffset']]"
113                     + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/TYPE",
114 
115             "/COMPILATION_UNIT/CLASS_DEF"
116                     + "[./IDENT[@text='InputXpathIndentationBasicOffset']]"
117                     + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/TYPE/LITERAL_VOID"
118         );
119 
120         runVerifications(moduleConfig, fileToProcess, expectedViolation,
121                 expectedXpathQueries);
122     }
123 
124     @Test
125     public void testCaseIndent() throws Exception {
126         final File fileToProcess =
127                 new File(getPath("InputXpathIndentationSwitchCase.java"));
128 
129         final DefaultConfiguration moduleConfig =
130                 createModuleConfig(IndentationCheck.class);
131         moduleConfig.addProperty("arrayInitIndent", "4");
132         moduleConfig.addProperty("basicOffset", "4");
133         moduleConfig.addProperty("braceAdjustment", "0");
134         moduleConfig.addProperty("caseIndent", "4");
135         moduleConfig.addProperty("forceStrictCondition", "false");
136         moduleConfig.addProperty("lineWrappingIndentation", "4");
137         moduleConfig.addProperty("tabWidth", "4");
138         moduleConfig.addProperty("throwsIndent", "4");
139 
140         final String[] expectedViolation = {
141             "7:9: " + getCheckMessage(IndentationCheck.class,
142                     IndentationCheck.MSG_CHILD_ERROR, "case", 8, 12),
143         };
144 
145         final List<String> expectedXpathQueries = Arrays.asList(
146             "/COMPILATION_UNIT/CLASS_DEF"
147                     + "[./IDENT[@text='InputXpathIndentationSwitchCase']]"
148                     + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_SWITCH/"
149                     + "CASE_GROUP",
150 
151             "/COMPILATION_UNIT/CLASS_DEF"
152                     + "[./IDENT[@text='InputXpathIndentationSwitchCase']]"
153                     + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_SWITCH/"
154                     + "CASE_GROUP/LITERAL_CASE"
155         );
156 
157         runVerifications(moduleConfig, fileToProcess, expectedViolation,
158                 expectedXpathQueries);
159     }
160 
161     @Test
162     public void testLambdaOne() throws Exception {
163         final File fileToProcess =
164                 new File(getPath("InputXpathIndentationLambdaOne.java"));
165 
166         final DefaultConfiguration moduleConfig =
167                 createModuleConfig(IndentationCheck.class);
168         moduleConfig.addProperty("arrayInitIndent", "4");
169         moduleConfig.addProperty("basicOffset", "4");
170         moduleConfig.addProperty("braceAdjustment", "0");
171         moduleConfig.addProperty("caseIndent", "4");
172         moduleConfig.addProperty("forceStrictCondition", "false");
173         moduleConfig.addProperty("lineWrappingIndentation", "4");
174         moduleConfig.addProperty("tabWidth", "4");
175         moduleConfig.addProperty("throwsIndent", "4");
176 
177         final String[] expectedViolation = {
178             "6:9: " + getCheckMessage(IndentationCheck.class,
179                     IndentationCheck.MSG_ERROR, "(", 8, 12),
180         };
181 
182         final List<String> expectedXpathQueries = Collections.singletonList(
183             "/COMPILATION_UNIT/CLASS_DEF"
184                     + "[./IDENT[@text='InputXpathIndentationLambdaOne"
185                     + "']]/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/SLIST/VARIABLE_DEF"
186                     + "[./IDENT[@text='getA']]/ASSIGN/LAMBDA/LPAREN"
187         );
188 
189         runVerifications(moduleConfig, fileToProcess, expectedViolation,
190                 expectedXpathQueries);
191     }
192 
193     @Test
194     public void testLambdaTwo() throws Exception {
195         final File fileToProcess =
196                 new File(getPath("InputXpathIndentationLambdaTwo.java"));
197 
198         final DefaultConfiguration moduleConfig =
199                 createModuleConfig(IndentationCheck.class);
200         moduleConfig.addProperty("arrayInitIndent", "4");
201         moduleConfig.addProperty("basicOffset", "4");
202         moduleConfig.addProperty("braceAdjustment", "0");
203         moduleConfig.addProperty("caseIndent", "4");
204         moduleConfig.addProperty("forceStrictCondition", "false");
205         moduleConfig.addProperty("lineWrappingIndentation", "4");
206         moduleConfig.addProperty("tabWidth", "4");
207         moduleConfig.addProperty("throwsIndent", "4");
208 
209         final String[] expectedViolation = {
210             "14:15: " + getCheckMessage(IndentationCheck.class,
211                     IndentationCheck.MSG_CHILD_ERROR_MULTI, "block", 14, "12, 16"),
212         };
213 
214         final List<String> expectedXpathQueries = Collections.singletonList(
215             "/COMPILATION_UNIT/CLASS_DEF"
216                     + "[./IDENT[@text='InputXpathIndentationLambdaTwo']]"
217                     + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/SLIST/VARIABLE_DEF["
218                     + "./IDENT[@text='div']]/ASSIGN/LAMBDA/SLIST/LITERAL_RETURN"
219         );
220 
221         runVerifications(moduleConfig, fileToProcess, expectedViolation,
222                 expectedXpathQueries);
223     }
224 
225     @Test
226     public void testIfWithNoCurlies() throws Exception {
227         final File fileToProcess =
228             new File(getPath("InputXpathIndentationIfWithoutCurly.java"));
229 
230         final DefaultConfiguration moduleConfig =
231                 createModuleConfig(IndentationCheck.class);
232 
233         moduleConfig.addProperty("arrayInitIndent", "4");
234         moduleConfig.addProperty("basicOffset", "4");
235         moduleConfig.addProperty("braceAdjustment", "0");
236         moduleConfig.addProperty("caseIndent", "4");
237         moduleConfig.addProperty("forceStrictCondition", "false");
238         moduleConfig.addProperty("lineWrappingIndentation", "4");
239         moduleConfig.addProperty("tabWidth", "4");
240         moduleConfig.addProperty("throwsIndent", "4");
241 
242         final String[] expectedViolation = {
243             "8:9: " + getCheckMessage(IndentationCheck.class,
244                 IndentationCheck.MSG_CHILD_ERROR, "if", 8, 12),
245         };
246 
247         final List<String> expectedXpathQueries = Collections.singletonList(
248             "/COMPILATION_UNIT/CLASS_DEF"
249                     + "[./IDENT[@text='InputXpathIndentationIfWithoutCurly']]"
250                     + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_IF/EXPR/"
251                     + "METHOD_CALL/IDENT[@text='e']"
252         );
253 
254         runVerifications(moduleConfig, fileToProcess, expectedViolation,
255             expectedXpathQueries);
256     }
257 
258     @Test
259     public void testElseWithNoCurlies() throws Exception {
260         final File fileToProcess =
261                 new File(getPath("InputXpathIndentationElseWithoutCurly.java"));
262 
263         final DefaultConfiguration moduleConfig =
264                 createModuleConfig(IndentationCheck.class);
265 
266         moduleConfig.addProperty("arrayInitIndent", "4");
267         moduleConfig.addProperty("basicOffset", "4");
268         moduleConfig.addProperty("braceAdjustment", "0");
269         moduleConfig.addProperty("caseIndent", "4");
270         moduleConfig.addProperty("forceStrictCondition", "false");
271         moduleConfig.addProperty("lineWrappingIndentation", "4");
272         moduleConfig.addProperty("tabWidth", "4");
273         moduleConfig.addProperty("throwsIndent", "4");
274 
275         final String[] expectedViolation = {
276             "12:9: " + getCheckMessage(IndentationCheck.class,
277                 IndentationCheck.MSG_CHILD_ERROR, "else", 8, 12),
278         };
279 
280         final List<String> expectedXpathQueries = Collections.singletonList(
281             "/COMPILATION_UNIT/CLASS_DEF"
282                     + "[./IDENT[@text='InputXpathIndentationElseWithoutCurly']]"
283                     + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_IF/LITERAL_ELSE"
284                     + "/EXPR/METHOD_CALL/IDENT[@text='exp']"
285         );
286 
287         runVerifications(moduleConfig, fileToProcess, expectedViolation,
288             expectedXpathQueries);
289     }
290 }