View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 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;
21  
22  import static com.puppycrawl.tools.checkstyle.checks.DescendantTokenCheck.MSG_KEY_MAX;
23  import static com.puppycrawl.tools.checkstyle.checks.DescendantTokenCheck.MSG_KEY_MIN;
24  import static com.puppycrawl.tools.checkstyle.checks.DescendantTokenCheck.MSG_KEY_SUM_MAX;
25  import static com.puppycrawl.tools.checkstyle.checks.DescendantTokenCheck.MSG_KEY_SUM_MIN;
26  
27  import org.junit.Test;
28  
29  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
30  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
31  import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
32  
33  public class DescendantTokenCheckTest extends AbstractModuleTestSupport {
34      @Override
35      protected String getPackageLocation() {
36          return "com/puppycrawl/tools/checkstyle/checks/descendanttoken";
37      }
38  
39      @Test
40      public void testDefault()
41              throws Exception {
42          final DefaultConfiguration checkConfig =
43              createModuleConfig(DescendantTokenCheck.class);
44          final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
45          verify(checkConfig, getPath("InputDescendantTokenIllegalTokens.java"), expected);
46      }
47  
48      @Test
49      public void testMaximumNumber()
50              throws Exception {
51          final DefaultConfiguration checkConfig =
52              createModuleConfig(DescendantTokenCheck.class);
53          checkConfig.addAttribute("tokens", "LITERAL_NATIVE");
54          checkConfig.addAttribute("limitedTokens", "LITERAL_NATIVE");
55          checkConfig.addAttribute("maximumNumber", "0");
56          final String[] expected = {
57              "17:12: " + getCheckMessage(MSG_KEY_MAX, 1, 0, "LITERAL_NATIVE", "LITERAL_NATIVE"),
58          };
59          verify(checkConfig, getPath("InputDescendantTokenIllegalTokens.java"), expected);
60      }
61  
62      @Test
63      public void testMessage()
64              throws Exception {
65          final DefaultConfiguration checkConfig =
66              createModuleConfig(DescendantTokenCheck.class);
67          checkConfig.addAttribute("tokens", "LITERAL_NATIVE");
68          checkConfig.addAttribute("limitedTokens", "LITERAL_NATIVE");
69          checkConfig.addAttribute("maximumNumber", "0");
70          checkConfig.addAttribute("maximumMessage", "Using ''native'' is not allowed.");
71          final String[] expected = {
72              "17:12: Using 'native' is not allowed.",
73          };
74          verify(checkConfig, getPath("InputDescendantTokenIllegalTokens.java"), expected);
75      }
76  
77      @Test
78      public void testMinimumNumber()
79              throws Exception {
80          final DefaultConfiguration checkConfig =
81              createModuleConfig(DescendantTokenCheck.class);
82          checkConfig.addAttribute("tokens", "LITERAL_SWITCH");
83          checkConfig.addAttribute("limitedTokens", "LITERAL_DEFAULT");
84          checkConfig.addAttribute("minimumNumber", "2");
85          final String[] expected = {
86              "8:9: " + getCheckMessage(MSG_KEY_MIN, 1, 2, "LITERAL_SWITCH", "LITERAL_DEFAULT"),
87          };
88          verify(checkConfig, getPath("InputDescendantTokenIllegalTokens.java"), expected);
89      }
90  
91      @Test
92      public void testMinimumDepth()
93              throws Exception {
94          final DefaultConfiguration checkConfig =
95              createModuleConfig(DescendantTokenCheck.class);
96          checkConfig.addAttribute("tokens", "LITERAL_SWITCH");
97          checkConfig.addAttribute("limitedTokens", "LITERAL_DEFAULT");
98          checkConfig.addAttribute("maximumNumber", "0");
99          checkConfig.addAttribute("minimumDepth", "3");
100         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
101         verify(checkConfig, getPath("InputDescendantTokenIllegalTokens.java"), expected);
102     }
103 
104     @Test
105     public void testMaximumDepth()
106             throws Exception {
107         final DefaultConfiguration checkConfig =
108             createModuleConfig(DescendantTokenCheck.class);
109         checkConfig.addAttribute("tokens", "LITERAL_SWITCH");
110         checkConfig.addAttribute("limitedTokens", "LITERAL_DEFAULT");
111         checkConfig.addAttribute("maximumNumber", "0");
112         checkConfig.addAttribute("maximumDepth", "1");
113         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
114         verify(checkConfig, getPath("InputDescendantTokenIllegalTokens.java"), expected);
115     }
116 
117     @Test
118     public void testEmptyStatements()
119             throws Exception {
120         final DefaultConfiguration checkConfig =
121             createModuleConfig(DescendantTokenCheck.class);
122         checkConfig.addAttribute("tokens", "EMPTY_STAT");
123         checkConfig.addAttribute("limitedTokens", "EMPTY_STAT");
124         checkConfig.addAttribute("maximumNumber", "0");
125         checkConfig.addAttribute("maximumDepth", "0");
126         checkConfig.addAttribute("maximumMessage", "Empty statement.");
127 
128         final String[] expected = {
129             "7:7: Empty statement.",
130             "12:7: Empty statement.",
131             "17:19: Empty statement.",
132             "21:10: Empty statement.",
133             "24:16: Empty statement.",
134             "28:10: Empty statement.",
135             "38:10: Empty statement.",
136             "44:13: Empty statement.",
137             "46:13: Empty statement.",
138             "49:19: Empty statement.",
139             "53:10: Empty statement.",
140             "56:9: Empty statement.",
141             "61:10: Empty statement.",
142             "67:10: Empty statement.",
143             "71:10: Empty statement.",
144             "75:10: Empty statement.",
145         };
146 
147         verify(checkConfig, getPath("InputDescendantTokenEmptyStatement.java"), expected);
148     }
149 
150     @Test
151     public void testMissingSwitchDefault() throws Exception {
152         final DefaultConfiguration checkConfig =
153             createModuleConfig(DescendantTokenCheck.class);
154         checkConfig.addAttribute("tokens", "LITERAL_SWITCH");
155         checkConfig.addAttribute("limitedTokens", "LITERAL_DEFAULT");
156         checkConfig.addAttribute("minimumNumber", "1");
157         checkConfig.addAttribute("maximumDepth", "2");
158         checkConfig.addAttribute("minimumMessage", "switch without \"default\" clause.");
159 
160         final String[] expected = {
161             "17:9: switch without \"default\" clause.",
162         };
163 
164         verify(checkConfig, getPath("InputDescendantTokenMissingSwitchDefault.java"), expected);
165     }
166 
167     @Test
168     public void testStringLiteralEquality() throws Exception {
169         final DefaultConfiguration checkConfig =
170             createModuleConfig(DescendantTokenCheck.class);
171         checkConfig.addAttribute("tokens", "EQUAL,NOT_EQUAL");
172         checkConfig.addAttribute("limitedTokens", "STRING_LITERAL");
173         checkConfig.addAttribute("maximumNumber", "0");
174         checkConfig.addAttribute("maximumDepth", "1");
175         checkConfig.addAttribute("maximumMessage",
176             "Literal Strings should be compared using equals(), not ''==''.");
177 
178         final String[] expected = {
179             "7:18: Literal Strings should be compared using equals(), not '=='.",
180             "12:20: Literal Strings should be compared using equals(), not '=='.",
181             "17:22: Literal Strings should be compared using equals(), not '=='.",
182         };
183         verify(checkConfig, getPath("InputDescendantTokenStringLiteralEquality.java"), expected);
184     }
185 
186     @Test
187     public void testIllegalTokenDefault() throws Exception {
188         final DefaultConfiguration checkConfig =
189             createModuleConfig(DescendantTokenCheck.class);
190         checkConfig.addAttribute("tokens", "LITERAL_SWITCH, POST_INC, POST_DEC");
191         checkConfig.addAttribute("limitedTokens", "LITERAL_SWITCH, POST_INC, POST_DEC");
192         checkConfig.addAttribute("maximumNumber", "0");
193         checkConfig.addAttribute("maximumDepth", "0");
194         checkConfig.addAttribute("maximumMessage", "Using ''{2}'' is not allowed.");
195 
196         final String[] expected = {
197             "8:9: Using 'LITERAL_SWITCH' is not allowed.",
198             "11:18: Using 'POST_DEC' is not allowed.",
199             "12:18: Using 'POST_INC' is not allowed.",
200         };
201         verify(checkConfig, getPath("InputDescendantTokenIllegalTokens.java"), expected);
202     }
203 
204     @Test
205     public void testIllegalTokenNative() throws Exception {
206         final DefaultConfiguration checkConfig =
207             createModuleConfig(DescendantTokenCheck.class);
208         checkConfig.addAttribute("tokens", "LITERAL_NATIVE");
209         checkConfig.addAttribute("limitedTokens", "LITERAL_NATIVE");
210         checkConfig.addAttribute("maximumNumber", "0");
211         checkConfig.addAttribute("maximumDepth", "0");
212         checkConfig.addAttribute("maximumMessage", "Using ''{2}'' is not allowed.");
213 
214         final String[] expected = {
215             "17:12: Using 'LITERAL_NATIVE' is not allowed.",
216         };
217         verify(checkConfig, getPath("InputDescendantTokenIllegalTokens.java"), expected);
218     }
219 
220     @Test
221     public void testReturnFromCatch() throws Exception {
222         final DefaultConfiguration checkConfig = createModuleConfig(DescendantTokenCheck.class);
223 
224         checkConfig.addAttribute("tokens", "LITERAL_CATCH");
225         checkConfig.addAttribute("limitedTokens", "LITERAL_RETURN");
226         checkConfig.addAttribute("maximumNumber", "0");
227         checkConfig.addAttribute("maximumMessage", "Return from catch is not allowed.");
228 
229         final String[] expected = {
230             "7:11: Return from catch is not allowed.",
231             "15:11: Return from catch is not allowed.",
232         };
233 
234         verify(checkConfig, getPath("InputDescendantTokenReturnFromCatch.java"), expected);
235     }
236 
237     @Test
238     public void testReturnFromFinally() throws Exception {
239         final DefaultConfiguration checkConfig = createModuleConfig(DescendantTokenCheck.class);
240 
241         checkConfig.addAttribute("tokens", "LITERAL_FINALLY");
242         checkConfig.addAttribute("limitedTokens", "LITERAL_RETURN");
243         checkConfig.addAttribute("maximumNumber", "0");
244         checkConfig.addAttribute("maximumMessage", "Return from finally is not allowed.");
245 
246         final String[] expected = {
247             "7:11: Return from finally is not allowed.",
248             "15:11: Return from finally is not allowed.",
249         };
250 
251         verify(checkConfig, getPath("InputDescendantTokenReturnFromFinally.java"), expected);
252     }
253 
254     @Test
255     public void testNoSum() throws Exception {
256         final DefaultConfiguration checkConfig = createModuleConfig(DescendantTokenCheck.class);
257 
258         checkConfig.addAttribute("tokens", "NOT_EQUAL,EQUAL");
259         checkConfig.addAttribute("limitedTokens", "LITERAL_THIS,LITERAL_NULL");
260         checkConfig.addAttribute("maximumNumber", "1");
261         checkConfig.addAttribute("maximumMessage", "What are you doing?");
262 
263         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
264 
265         verify(checkConfig, getPath("InputDescendantTokenReturnFromFinally.java"), expected);
266     }
267 
268     @Test
269     public void testWithSumCustomMsg() throws Exception {
270         final DefaultConfiguration checkConfig = createModuleConfig(DescendantTokenCheck.class);
271         checkConfig.addAttribute("tokens", "NOT_EQUAL,EQUAL");
272         checkConfig.addAttribute("limitedTokens", "LITERAL_THIS,LITERAL_NULL");
273         checkConfig.addAttribute("maximumNumber", "1");
274         checkConfig.addAttribute("maximumDepth", "1");
275         checkConfig.addAttribute("maximumMessage", "this cannot be null.");
276         checkConfig.addAttribute("sumTokenCounts", "true");
277 
278         final String[] expected = {
279             "22:32: this cannot be null.",
280             "22:50: this cannot be null.",
281             "23:33: this cannot be null.",
282             "23:51: this cannot be null.",
283         };
284 
285         verify(checkConfig, getPath("InputDescendantTokenReturnFromFinally.java"), expected);
286     }
287 
288     @Test
289     public void testWithSumDefaultMsg() throws Exception {
290         final DefaultConfiguration checkConfig = createModuleConfig(DescendantTokenCheck.class);
291         checkConfig.addAttribute("tokens", "NOT_EQUAL,EQUAL");
292         checkConfig.addAttribute("limitedTokens", "LITERAL_THIS,LITERAL_NULL");
293         checkConfig.addAttribute("maximumNumber", "1");
294         checkConfig.addAttribute("maximumDepth", "1");
295         checkConfig.addAttribute("sumTokenCounts", "true");
296 
297         final String[] expected = {
298             "22:32: " + getCheckMessage(MSG_KEY_SUM_MAX, 2, 1, "EQUAL"),
299             "22:50: " + getCheckMessage(MSG_KEY_SUM_MAX, 2, 1, "EQUAL"),
300             "23:33: " + getCheckMessage(MSG_KEY_SUM_MAX, 2, 1, "NOT_EQUAL"),
301             "23:51: " + getCheckMessage(MSG_KEY_SUM_MAX, 2, 1, "NOT_EQUAL"),
302         };
303 
304         verify(checkConfig, getPath("InputDescendantTokenReturnFromFinally.java"), expected);
305     }
306 
307     @Test
308     public void testWithSumLessThenMinDefMsg() throws Exception {
309         final DefaultConfiguration checkConfig = createModuleConfig(DescendantTokenCheck.class);
310         checkConfig.addAttribute("tokens", "NOT_EQUAL,EQUAL");
311         checkConfig.addAttribute("limitedTokens", "LITERAL_THIS,LITERAL_NULL");
312         checkConfig.addAttribute("minimumNumber", "3");
313         checkConfig.addAttribute("sumTokenCounts", "true");
314 
315         final String[] expected = {
316             "16:44: " + getCheckMessage(MSG_KEY_SUM_MIN, 0, 3, "EQUAL"),
317             "22:32: " + getCheckMessage(MSG_KEY_SUM_MIN, 2, 3, "EQUAL"),
318             "22:50: " + getCheckMessage(MSG_KEY_SUM_MIN, 2, 3, "EQUAL"),
319             "23:33: " + getCheckMessage(MSG_KEY_SUM_MIN, 2, 3, "NOT_EQUAL"),
320             "23:51: " + getCheckMessage(MSG_KEY_SUM_MIN, 2, 3, "NOT_EQUAL"),
321             "24:54: " + getCheckMessage(MSG_KEY_SUM_MIN, 2, 3, "EQUAL"),
322             "24:77: " + getCheckMessage(MSG_KEY_SUM_MIN, 1, 3, "EQUAL"),
323         };
324 
325         verify(checkConfig, getPath("InputDescendantTokenReturnFromFinally.java"), expected);
326     }
327 
328     @Test
329     public void testWithSumLessThenMinCustomMsg() throws Exception {
330         final DefaultConfiguration checkConfig = createModuleConfig(DescendantTokenCheck.class);
331         checkConfig.addAttribute("tokens", "NOT_EQUAL,EQUAL");
332         checkConfig.addAttribute("limitedTokens", "LITERAL_THIS,LITERAL_NULL");
333         checkConfig.addAttribute("minimumNumber", "3");
334         checkConfig.addAttribute("sumTokenCounts", "true");
335         checkConfig.addAttribute("minimumMessage", "custom message");
336 
337         final String[] expected = {
338             "16:44: custom message",
339             "22:32: custom message",
340             "22:50: custom message",
341             "23:33: custom message",
342             "23:51: custom message",
343             "24:54: custom message",
344             "24:77: custom message",
345         };
346 
347         verify(checkConfig, getPath("InputDescendantTokenReturnFromFinally.java"), expected);
348     }
349 
350     @Test
351     public void testMaxTokenType() throws Exception {
352         final DefaultConfiguration checkConfig =
353                 createModuleConfig(DescendantTokenCheck.class);
354         checkConfig.addAttribute("tokens", "OBJBLOCK");
355         checkConfig.addAttribute("limitedTokens", "LCURLY,RCURLY");
356         checkConfig.addAttribute("maximumNumber", "0");
357         checkConfig.addAttribute("maximumDepth", "2");
358         final String[] expected = {
359             "6:48: " + getCheckMessage(MSG_KEY_MAX, 1, 0, "OBJBLOCK", "LCURLY"),
360             "6:48: " + getCheckMessage(MSG_KEY_MAX, 1, 0, "OBJBLOCK", "RCURLY"),
361         };
362         verify(checkConfig, getPath("InputDescendantTokenLastTokenType.java"), expected);
363     }
364 
365     @Test
366     public void testMaxTokenTypeReverseOrder() throws Exception {
367         final DefaultConfiguration checkConfig =
368                 createModuleConfig(DescendantTokenCheck.class);
369         checkConfig.addAttribute("tokens", "OBJBLOCK");
370         checkConfig.addAttribute("limitedTokens", "RCURLY,LCURLY");
371         checkConfig.addAttribute("maximumNumber", "0");
372         checkConfig.addAttribute("maximumDepth", "2");
373         final String[] expected = {
374             "6:48: " + getCheckMessage(MSG_KEY_MAX, 1, 0, "OBJBLOCK", "LCURLY"),
375             "6:48: " + getCheckMessage(MSG_KEY_MAX, 1, 0, "OBJBLOCK", "RCURLY"),
376         };
377         verify(checkConfig, getPath("InputDescendantTokenLastTokenType.java"), expected);
378     }
379 }