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