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.blocks;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.blocks.EmptyBlockCheck.MSG_KEY_BLOCK_EMPTY;
24  import static com.puppycrawl.tools.checkstyle.checks.blocks.EmptyBlockCheck.MSG_KEY_BLOCK_NO_STATEMENT;
25  import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
26  
27  import org.junit.jupiter.api.Test;
28  
29  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
30  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
31  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
32  
33  public class EmptyBlockCheckTest
34      extends AbstractModuleTestSupport {
35  
36      @Override
37      public String getPackageLocation() {
38          return "com/puppycrawl/tools/checkstyle/checks/blocks/emptyblock";
39      }
40  
41      /* Additional test for jacoco, since valueOf()
42       * is generated by javac and jacoco reports that
43       * valueOf() is uncovered.
44       */
45      @Test
46      public void testBlockOptionValueOf() {
47          final BlockOption option = BlockOption.valueOf("TEXT");
48          assertWithMessage("Invalid valueOf result")
49              .that(option)
50              .isEqualTo(BlockOption.TEXT);
51      }
52  
53      @Test
54      public void testDefault()
55              throws Exception {
56          final String[] expected = {
57              "38:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
58              "40:17: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
59              "42:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
60              "45:17: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
61              "68:5: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
62              "76:29: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
63              "78:41: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
64              "89:12: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
65          };
66          verifyWithInlineConfigParser(
67                  getPath("InputEmptyBlockSemantic.java"), expected);
68      }
69  
70      @Test
71      public void testText()
72              throws Exception {
73          final String[] expected = {
74              "38:13: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "try"),
75              "40:17: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "finally"),
76              "68:5: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "INSTANCE_INIT"),
77              "76:29: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "synchronized"),
78              "88:12: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "STATIC_INIT"),
79          };
80          verifyWithInlineConfigParser(
81                  getPath("InputEmptyBlockSemanticText.java"), expected);
82      }
83  
84      @Test
85      public void testStatement()
86              throws Exception {
87          final String[] expected = {
88              "38:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
89              "40:17: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
90              "42:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
91              "45:17: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
92              "68:5: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
93              "76:29: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
94              "78:41: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
95              "89:12: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
96          };
97          verifyWithInlineConfigParser(
98                  getPath("InputEmptyBlockSemanticStatement.java"), expected);
99      }
100 
101     @Test
102     public void allowEmptyLoops() throws Exception {
103         final String[] expected = {
104             "21:21: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
105             "24:34: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
106             "27:21: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
107             "28:20: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT),
108         };
109         verifyWithInlineConfigParser(
110                 getPath("InputEmptyBlockSemantic2Statement.java"), expected);
111     }
112 
113     @Test
114     public void allowEmptyLoopsText() throws Exception {
115         final String[] expected = {
116             "26:21: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "if"),
117             "29:34: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "if"),
118             "32:21: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "if"),
119             "33:20: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "switch"),
120         };
121         verifyWithInlineConfigParser(
122                 getPath("InputEmptyBlockSemantic2Text.java"), expected);
123     }
124 
125     @Test
126     public void testInvalidOption() {
127 
128         final CheckstyleException exc = getExpectedThrowable(CheckstyleException.class,
129                 () -> {
130                     final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
131                     verifyWithInlineConfigParser(
132                             getPath("InputEmptyBlockSemanticInvalid.java"), expected);
133                 });
134         assertWithMessage("Invalid exception message")
135             .that(exc.getMessage())
136             .isEqualTo("cannot initialize module com.puppycrawl.tools.checkstyle.TreeWalker - "
137                     + "cannot initialize module com.puppycrawl.tools.checkstyle.checks."
138                     + "blocks.EmptyBlockCheck");
139     }
140 
141     @Test
142     public void testAllowEmptyCaseWithText() throws Exception {
143         final String[] expected = {
144             "16:28: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
145             "22:13: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
146             "33:29: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
147             "35:37: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
148             "36:29: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
149         };
150         verifyWithInlineConfigParser(
151                 getPath("InputEmptyBlockCase.java"), expected);
152     }
153 
154     @Test
155     public void testForbidCaseWithoutStmt() throws Exception {
156         final String[] expected = {
157             "16:28: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "case"),
158             "22:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "case"),
159             "26:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "case"),
160             "33:29: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "case"),
161             "35:37: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "case"),
162             "36:29: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "case"),
163             "36:40: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "case"),
164         };
165         verifyWithInlineConfigParser(
166                 getPath("InputEmptyBlockCase2.java"), expected);
167     }
168 
169     @Test
170     public void testAllowEmptyDefaultWithText() throws Exception {
171         final String[] expected = {
172             "15:30: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
173             "21:13: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
174             "46:22: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
175             "54:47: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
176             "60:22: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
177             "88:13: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
178         };
179         verifyWithInlineConfigParser(
180                 getPath("InputEmptyBlockDefault.java"), expected);
181     }
182 
183     @Test
184     public void testForbidDefaultWithoutStatement() throws Exception {
185         final String[] expected = {
186             "15:30: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "default"),
187             "21:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "default"),
188             "25:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "default"),
189             "36:30: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "default"),
190             "46:22: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "default"),
191             "54:47: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "default"),
192             "60:22: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "default"),
193             "75:22: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "default"),
194             "88:13: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "default"),
195         };
196         verifyWithInlineConfigParser(
197                 getPath("InputEmptyBlockDefault2.java"), expected);
198     }
199 
200     @Test
201     public void testEmptyBlockWithEmoji() throws Exception {
202         final String[] expected = {
203             "15:12: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "STATIC_INIT"),
204             "25:27: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "if"),
205             "28:34: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "if"),
206             "30:62: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "for"),
207             "31:25: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "if"),
208             "33:25: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "switch"),
209             "40:22: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
210             "45:46: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
211         };
212         verifyWithInlineConfigParser(
213                 getPath("InputEmptyBlockWithEmoji.java"), expected);
214 
215     }
216 
217     @Test
218     public void testAnnotationDefaultKeyword() throws Exception {
219         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
220         final String path = getPath("InputEmptyBlockAnnotationDefaultKeyword.java");
221         verifyWithInlineConfigParser(
222                 path, expected);
223     }
224 
225     @Test
226     public void testEmptyBlockSwitchExpressionsOne() throws Exception {
227         final String[] expected = {
228             "17:30: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "default"),
229         };
230         verifyWithInlineConfigParser(
231                 getPath("InputEmptyBlockSwitchExpressionsOne.java"), expected);
232     }
233 
234     @Test
235     public void testEmptyBlockSwitchExpressionsTwo() throws Exception {
236         final String[] expected = {
237             "25:32: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "case"),
238             "27:26: " + getCheckMessage(MSG_KEY_BLOCK_NO_STATEMENT, "case"),
239         };
240         verifyWithInlineConfigParser(
241                 getPath("InputEmptyBlockSwitchExpressionsTwo.java"), expected);
242     }
243 
244     @Test
245     public void testUppercaseProperty() throws Exception {
246         final String[] expected = {
247             "16:30: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
248             "22:13: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
249         };
250         verifyWithInlineConfigParser(
251                 getPath("InputEmptyBlockTestUppercaseOptionProperty.java"), expected);
252     }
253 
254     @Test
255     public void testEmptyBlockCaseAndDefaultWithTextOption() throws Exception {
256         final String[] expected = {
257             "20:28: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
258             "24:22: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
259             "33:30: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "case"),
260             "37:24: " + getCheckMessage(MSG_KEY_BLOCK_EMPTY, "default"),
261         };
262         verifyWithInlineConfigParser(
263                 getNonCompilablePath("InputEmptyBlockCaseAndDefaultWithTextOption.java"),
264                 expected);
265     }
266 }