View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 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.annotation;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.MSG_KEY_ANNOTATION_INCORRECT_STYLE;
24  import static com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.MSG_KEY_ANNOTATION_PARENS_MISSING;
25  import static com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.MSG_KEY_ANNOTATION_PARENS_PRESENT;
26  import static com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING;
27  import static com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck.MSG_KEY_ANNOTATION_TRAILING_COMMA_PRESENT;
28  
29  import org.junit.jupiter.api.Test;
30  
31  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
32  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
33  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
34  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
35  import de.thetaphi.forbiddenapis.SuppressForbidden;
36  
37  public class AnnotationUseStyleCheckTest extends AbstractModuleTestSupport {
38  
39      @Override
40      protected String getPackageLocation() {
41          return "com/puppycrawl/tools/checkstyle/checks/annotation/annotationusestyle";
42      }
43  
44      /* Additional test for jacoco, since valueOf()
45       * is generated by javac and jacoco reports that
46       * valueOf() is uncovered.
47       */
48      @Test
49      public void testElementStyleOptionValueOf() {
50          final AnnotationUseStyleCheck.ElementStyleOption option =
51              AnnotationUseStyleCheck.ElementStyleOption.valueOf("COMPACT");
52          assertWithMessage("Invalid valueOf result")
53              .that(option)
54              .isEqualTo(AnnotationUseStyleCheck.ElementStyleOption.COMPACT);
55      }
56  
57      /* Additional test for jacoco, since valueOf()
58       * is generated by javac and jacoco reports that
59       * valueOf() is uncovered.
60       */
61      @Test
62      public void testTrailingArrayCommaOptionValueOf() {
63          final AnnotationUseStyleCheck.TrailingArrayCommaOption option =
64              AnnotationUseStyleCheck.TrailingArrayCommaOption.valueOf("ALWAYS");
65          assertWithMessage("Invalid valueOf result")
66              .that(option)
67              .isEqualTo(AnnotationUseStyleCheck.TrailingArrayCommaOption.ALWAYS);
68      }
69  
70      /* Additional test for jacoco, since valueOf()
71       * is generated by javac and jacoco reports that
72       * valueOf() is uncovered.
73       */
74      @Test
75      public void testClosingParensOptionValueOf() {
76          final AnnotationUseStyleCheck.ClosingParensOption option =
77              AnnotationUseStyleCheck.ClosingParensOption.valueOf("ALWAYS");
78          assertWithMessage("Invalid valueOf result")
79              .that(option)
80              .isEqualTo(AnnotationUseStyleCheck.ClosingParensOption.ALWAYS);
81      }
82  
83      /**
84       * Additional test for checking whether the properties in the configuration are set correctly
85       * when there is whitespace around them. Not possible to check with the inline config parser
86       * as it trims the whitespace around properties while setting them.
87       *
88       * @throws Exception exception
89       */
90      @SuppressForbidden
91      @Test
92      public void testNonTrimmedInput() throws Exception {
93          final DefaultConfiguration configuration =
94              createModuleConfig(AnnotationUseStyleCheck.class);
95          configuration.addProperty("elementStyle", "ignore");
96          configuration.addProperty("closingParens", " ignore  ");
97          configuration.addProperty("trailingArrayComma", " always");
98          final String filePath = getPath("InputAnnotationUseStyleWithTrailingComma.java");
99          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
100 
101         verify(configuration, filePath, expected);
102     }
103 
104     @Test
105     public void testDefault() throws Exception {
106         final String[] expected = {
107             "13:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
108             "14:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
109             "21:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
110             "23:1: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_PRESENT),
111             "29:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
112             "30:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
113             "35:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
114             "42:1: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_PRESENT),
115             "45:5: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_PRESENT),
116             "53:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
117             "55:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
118             "59:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
119             "88:32: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_PRESENT),
120             "91:40: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_PRESENT),
121         };
122 
123         verifyWithInlineConfigParser(
124                 getPath("InputAnnotationUseStyleDifferentStyles.java"), expected);
125     }
126 
127     /**
128      * Test that annotation parens are always present.
129      */
130     @Test
131     public void testParensAlways() throws Exception {
132         final String[] expected = {
133             "12:1: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_MISSING),
134             "27:1: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_MISSING),
135             "32:5: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_MISSING),
136             "80:32: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_MISSING),
137             "83:40: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_MISSING),
138             "91:9: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_MISSING),
139             "91:31: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_MISSING),
140         };
141 
142         verifyWithInlineConfigParser(
143                 getPath("InputAnnotationUseStyleWithParens.java"), expected);
144     }
145 
146     /**
147      * Test that annotation parens are never present.
148      */
149     @Test
150     public void testParensNever() throws Exception {
151         final String[] expected = {
152             "22:1: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_PRESENT),
153             "40:1: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_PRESENT),
154             "43:5: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_PRESENT),
155             "86:32: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_PRESENT),
156             "89:40: " + getCheckMessage(MSG_KEY_ANNOTATION_PARENS_PRESENT),
157         };
158 
159         verifyWithInlineConfigParser(
160                 getPath("InputAnnotationUseStyleNoParens.java"), expected);
161     }
162 
163     @Test
164     public void testStyleExpanded() throws Exception {
165         final String[] expected = {
166             "14:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "EXPANDED"),
167             "21:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "EXPANDED"),
168             "29:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "EXPANDED"),
169             "35:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "EXPANDED"),
170             "48:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "EXPANDED"),
171             "50:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "EXPANDED"),
172             "67:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "EXPANDED"),
173             "72:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "EXPANDED"),
174             "80:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "EXPANDED"),
175             "84:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "EXPANDED"),
176         };
177 
178         verifyWithInlineConfigParser(
179                 getPath("InputAnnotationUseStyleExpanded.java"), expected);
180     }
181 
182     @Test
183     public void testStyleCompact() throws Exception {
184         final String[] expected = {
185             "52:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT"),
186             "56:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT"),
187             "76:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT"),
188             "83:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT"),
189             "88:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT"),
190         };
191 
192         verifyWithInlineConfigParser(
193                 getPath("InputAnnotationUseStyleCompact.java"), expected);
194     }
195 
196     @Test
197     public void testStyleCompactNoArray() throws Exception {
198         final String[] expected = {
199             "13:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
200             "14:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
201             "21:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
202             "29:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
203             "30:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
204             "35:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
205             "52:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
206             "54:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
207             "58:1: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
208         };
209 
210         verifyWithInlineConfigParser(
211                 getPath("InputAnnotationUseStyleCompactNoArray.java"), expected);
212     }
213 
214     @Test
215     public void testCommaAlwaysViolations() throws Exception {
216         final String[] expected = {
217             "12:20: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
218             "15:30: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
219             "20:40: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
220             "24:45: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
221             "28:55: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
222             "36:22: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
223             "36:36: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
224             "38:21: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
225             "38:30: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
226             "41:39: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
227             "41:49: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
228             "44:21: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
229             "44:41: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
230         };
231 
232         verifyWithInlineConfigParser(
233                 getPath("InputAnnotationUseStyleNoTrailingComma.java"), expected);
234     }
235 
236     @Test
237     public void testCommaAlwaysViolationsNonCompilable() throws Exception {
238         final String[] expected = {
239             "15:37: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
240             "15:65: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_MISSING),
241         };
242 
243         verifyWithInlineConfigParser(
244                 getNonCompilablePath("InputAnnotationUseStyleNoTrailingComma.java"), expected);
245     }
246 
247     @Test
248     public void testCommaAlwaysNoViolations() throws Exception {
249         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
250 
251         verifyWithInlineConfigParser(
252                 getPath("InputAnnotationUseStyleWithTrailingComma.java"), expected);
253     }
254 
255     @Test
256     public void testCommaAlwaysNoViolationsNonCompilable() throws Exception {
257         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
258 
259         verifyWithInlineConfigParser(
260                 getNonCompilablePath("InputAnnotationUseStyleWithTrailingComma.java"), expected);
261     }
262 
263     @Test
264     public void testTrailingArrayIgnore() throws Exception {
265         final String[] expected = {
266             "15:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
267             "23:13: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
268             "35:5: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
269             "42:9: " + getCheckMessage(MSG_KEY_ANNOTATION_INCORRECT_STYLE, "COMPACT_NO_ARRAY"),
270         };
271 
272         verifyWithInlineConfigParser(
273                 getPath("InputAnnotationUseStyleWithTrailingCommaIgnore.java"), expected);
274     }
275 
276     @Test
277     public void testCommaNeverViolations() throws Exception {
278         final String[] expected = {
279             "16:32: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_PRESENT),
280             "21:42: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_PRESENT),
281             "25:46: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_PRESENT),
282             "29:56: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_PRESENT),
283             "37:24: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_PRESENT),
284             "37:39: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_PRESENT),
285             "43:41: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_PRESENT),
286             "43:52: " + getCheckMessage(MSG_KEY_ANNOTATION_TRAILING_COMMA_PRESENT),
287         };
288 
289         verifyWithInlineConfigParser(
290                 getPath("InputAnnotationUseStyleWithTrailingCommaNever.java"), expected);
291     }
292 
293     @Test
294     public void testCommaNeverNoViolations() throws Exception {
295         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
296 
297         verifyWithInlineConfigParser(
298                 getPath("InputAnnotationUseStyleNoTrailingCommaNever.java"), expected);
299     }
300 
301     @Test
302     public void testEverythingMixed() throws Exception {
303         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
304 
305         verifyWithInlineConfigParser(
306                 getPath("InputAnnotationUseStyleEverythingMixed.java"), expected);
307     }
308 
309     @Test
310     public void testAnnotationsWithoutDefaultValues() throws Exception {
311         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
312 
313         verifyWithInlineConfigParser(
314                 getPath("InputAnnotationUseStyleParams.java"), expected);
315     }
316 
317     @Test
318     public void testGetAcceptableTokens() {
319         final AnnotationUseStyleCheck constantNameCheckObj = new AnnotationUseStyleCheck();
320         final int[] actual = constantNameCheckObj.getAcceptableTokens();
321         final int[] expected = {TokenTypes.ANNOTATION };
322         assertWithMessage("Invalid acceptable tokens")
323             .that(actual)
324             .isEqualTo(expected);
325     }
326 
327     @Test
328     public void testGetOption() {
329         final AnnotationUseStyleCheck check = new AnnotationUseStyleCheck();
330         try {
331             check.setElementStyle("SHOULD_PRODUCE_ERROR");
332             assertWithMessage("ConversionException is expected").fail();
333         }
334         catch (IllegalArgumentException ex) {
335             final String messageStart = "unable to parse";
336 
337             assertWithMessage("Invalid exception message, should start with: " + messageStart)
338                     .that(ex.getMessage())
339                     .startsWith(messageStart);
340         }
341     }
342 
343     @Test
344     public void testStyleNotInList() throws Exception {
345         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
346 
347         verifyWithInlineConfigParser(
348                 getPath("InputAnnotationUseStyle.java"), expected);
349     }
350 
351 }