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.header;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck.MSG_HEADER_MISMATCH;
24  import static com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck.MSG_HEADER_MISSING;
25  import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
26  
27  import java.util.List;
28  import java.util.regex.Pattern;
29  
30  import org.junit.jupiter.api.Test;
31  
32  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
33  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
34  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
35  import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
36  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
37  
38  /**
39   * Unit test for RegexpHeaderCheck.
40   */
41  public class RegexpHeaderCheckTest extends AbstractModuleTestSupport {
42  
43      @Override
44      public String getPackageLocation() {
45          return "com/puppycrawl/tools/checkstyle/checks/header/regexpheader";
46      }
47  
48      /**
49       * Test of setHeader method, of class RegexpHeaderCheck.
50       */
51      @Test
52      public void testSetHeaderNull() {
53          // check null passes
54          final RegexpHeaderCheck instance = new RegexpHeaderCheck();
55          // recreate for each test because multiple invocations fail
56          final String header = null;
57          instance.setHeader(header);
58          final List<Pattern> headerRegexps = TestUtil.getInternalStateListPattern(
59                  instance, "headerRegexps");
60  
61          assertWithMessage("When header is null regexps should not be set")
62                  .that(headerRegexps)
63                  .isEmpty();
64      }
65  
66      /**
67       * Test of setHeader method, of class RegexpHeaderCheck.
68       */
69      @Test
70      public void testSetHeaderEmpty() {
71          // check null passes
72          final RegexpHeaderCheck instance = new RegexpHeaderCheck();
73          // check empty string passes
74          final String header = "";
75          instance.setHeader(header);
76          final List<Pattern> headerRegexps = TestUtil.getInternalStateListPattern(
77                  instance, "headerRegexps");
78  
79          assertWithMessage("When header is empty regexps should not be set")
80                  .that(headerRegexps)
81                  .isEmpty();
82      }
83  
84      /**
85       * Test of setHeader method, of class RegexpHeaderCheck.
86       */
87  
88      @Test
89      public void testSetHeaderSimple() {
90          final RegexpHeaderCheck instance = new RegexpHeaderCheck();
91          // check valid header passes
92          final String header = "abc.*";
93          instance.setHeader(header);
94          final List<Pattern> headerRegexps = TestUtil.getInternalStateListPattern(
95                  instance, "headerRegexps");
96          assertWithMessage("Expected one pattern")
97              .that(headerRegexps.size())
98              .isEqualTo(1);
99          assertWithMessage("Invalid header regexp")
100             .that(headerRegexps.getFirst().pattern())
101             .isEqualTo(header);
102     }
103 
104     /**
105      * Test of setHeader method, of class RegexpHeaderCheck.
106      */
107     @Test
108     public void testSetHeader() {
109         // check invalid header passes
110         final RegexpHeaderCheck instance = new RegexpHeaderCheck();
111         final String header = "^/**\\n * Licensed to the Apache Software Foundation (ASF)";
112         final IllegalArgumentException exc =
113                 getExpectedThrowable(IllegalArgumentException.class,
114                         () -> instance.setHeader(header));
115         assertWithMessage("Invalid exception message")
116                 .that(exc.getMessage())
117                 .isEqualTo("Unable to parse format: ^/**\\n *"
118                     + " Licensed to the Apache Software Foundation (ASF)");
119     }
120 
121     @Test
122     public void testDefaultConfiguration() throws Exception {
123         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
124         createChecker(checkConfig);
125         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
126         // Content header is conflicting with Input inline header
127         verify(checkConfig, getPath("InputRegexpHeaderDefaultConfig.java"), expected);
128     }
129 
130     @Test
131     public void testEmptyFilename() {
132         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
133         checkConfig.addProperty("headerFile", "");
134         final CheckstyleException exc =
135                 getExpectedThrowable(CheckstyleException.class, () -> createChecker(checkConfig));
136         assertWithMessage("Invalid exception message")
137                 .that(exc.getMessage())
138                 .isEqualTo("cannot initialize module"
139                     + " com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck"
140                     + " - Cannot set property 'headerFile' to ''");
141     }
142 
143     @Test
144     public void testRegexpHeader() throws Exception {
145         final DefaultConfiguration checkConfig =
146                 createModuleConfig(RegexpHeaderCheck.class);
147         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader.header"));
148         final String[] expected = {
149             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "// Created: 2002"),
150         };
151         // Content header is conflicting with Input inline header
152         verify(checkConfig, getPath("InputRegexpHeaderIgnore.java"), expected);
153     }
154 
155     @Test
156     public void testNonMatchingRegexpHeader() throws Exception {
157         final DefaultConfiguration checkConfig =
158             createModuleConfig(RegexpHeaderCheck.class);
159         checkConfig.addProperty("header",
160                                 "\\/\\/ Nth Line of Header\\n\\/\\/ Nth Line of Header\\n");
161         checkConfig.addProperty("multiLines", "1");
162         final String[] expected = {
163             "1: " + getCheckMessage(MSG_HEADER_MISMATCH, "\\/\\/ Nth Line of Header"),
164         };
165         // Content header is conflicting with Input inline header
166         verify(checkConfig, getPath("InputRegexpHeaderNonMatching.java"), expected);
167     }
168 
169     @Test
170     public void testRegexpHeaderUrl() throws Exception {
171         final DefaultConfiguration checkConfig =
172                 createModuleConfig(RegexpHeaderCheck.class);
173         checkConfig.addProperty("headerFile", getUriString("InputRegexpHeader.header"));
174         final String[] expected = {
175             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "// Created: 2002"),
176         };
177         // Content header is conflicting with Input inline header
178         verify(checkConfig, getPath("InputRegexpHeaderIgnore.java"), expected);
179     }
180 
181     @Test
182     public void testInlineRegexpHeader() throws Exception {
183         final DefaultConfiguration checkConfig =
184                 createModuleConfig(RegexpHeaderCheck.class);
185         checkConfig.addProperty("header", "^/*$\\n// .*\\n// Created: 2002\\n^//.*\\n^//.*");
186         final String[] expected = {
187             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "// Created: 2002"),
188         };
189         // Content header is conflicting with Input inline header
190         verify(checkConfig, getPath("InputRegexpHeaderIgnore.java"), expected);
191     }
192 
193     @Test
194     public void testFailureForMultilineRegexp() {
195         final DefaultConfiguration checkConfig =
196                 createModuleConfig(RegexpHeaderCheck.class);
197         checkConfig.addProperty("header", "^(.*\\n.*)");
198         final CheckstyleException exc =
199                 getExpectedThrowable(CheckstyleException.class, () -> createChecker(checkConfig));
200         assertWithMessage("Invalid exception message")
201                 .that(exc.getMessage())
202                 .isEqualTo("cannot initialize module"
203                     + " com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck"
204                     + " - Cannot set property 'header' to '^(.*\\n.*)'");
205     }
206 
207     @Test
208     public void testInlineRegexpHeaderConsecutiveNewlines() throws Exception {
209         final DefaultConfiguration checkConfig =
210                 createModuleConfig(RegexpHeaderCheck.class);
211         checkConfig.addProperty("header", "^/*$\\n// .*\\n\\n// Created: 2017\\n^//.*");
212         final String[] expected = {
213             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "^$"),
214         };
215         // Content header is conflicting with Input inline header
216         verify(checkConfig, getPath("InputRegexpHeaderConsecutiveNewLines.java"), expected);
217     }
218 
219     @Test
220     public void testInlineRegexpHeaderConsecutiveNewlinesThroughConfigFile() throws Exception {
221         final DefaultConfiguration checkConfig =
222                 createModuleConfig(RegexpHeaderCheck.class);
223         checkConfig.addProperty("headerFile", getUriString("InputRegexpHeaderNewLines.header"));
224         final String[] expected = {
225             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "^$"),
226         };
227         // Content header is conflicting with Input inline header
228         verify(checkConfig, getPath("InputRegexpHeaderConsecutiveNewLines.java"), expected);
229     }
230 
231     @Test
232     public void testRegexpHeaderIgnore() throws Exception {
233         final DefaultConfiguration checkConfig =
234                 createModuleConfig(RegexpHeaderCheck.class);
235         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader1.header"));
236         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
237         // Content header is conflicting with Input inline header
238         verify(checkConfig, getPath("InputRegexpHeaderIgnore.java"), expected);
239     }
240 
241     @Test
242     public void testRegexpHeaderMulti1() throws Exception {
243         final DefaultConfiguration checkConfig =
244                 createModuleConfig(RegexpHeaderCheck.class);
245         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader2.header"));
246         checkConfig.addProperty("multiLines", "3, 6");
247         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
248         // Content header is conflicting with Input inline header
249         verify(checkConfig, getPath("InputRegexpHeaderDefaultConfig.java"), expected);
250     }
251 
252     @Test
253     public void testRegexpHeaderMulti2() throws Exception {
254         final DefaultConfiguration checkConfig =
255                 createModuleConfig(RegexpHeaderCheck.class);
256         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader2.header"));
257         checkConfig.addProperty("multiLines", "3, 6");
258         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
259         // Content header is conflicting with Input inline header
260         verify(checkConfig, getPath("InputRegexpHeaderMulti2.java"), expected);
261     }
262 
263     @Test
264     public void testRegexpHeaderMulti3() throws Exception {
265         final DefaultConfiguration checkConfig =
266                 createModuleConfig(RegexpHeaderCheck.class);
267         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader2.header"));
268         checkConfig.addProperty("multiLines", "3, 7");
269         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
270         // Content header is conflicting with Input inline header
271         verify(checkConfig, getPath("InputRegexpHeaderDefaultConfig.java"), expected);
272     }
273 
274     @Test
275     public void testRegexpHeaderMulti4() throws Exception {
276         final DefaultConfiguration checkConfig =
277                 createModuleConfig(RegexpHeaderCheck.class);
278         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader2.header"));
279         checkConfig.addProperty("multiLines", "3, 5, 6, 7");
280         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
281         // Content header is conflicting with Input inline header
282         verify(checkConfig, getPath("InputRegexpHeaderMulti4.java"), expected);
283     }
284 
285     @Test
286     public void testRegexpHeaderMulti5() throws Exception {
287         final DefaultConfiguration checkConfig =
288                 createModuleConfig(RegexpHeaderCheck.class);
289         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader2.header"));
290         checkConfig.addProperty("multiLines", "3");
291         final String[] expected = {
292             "1: " + getCheckMessage(MSG_HEADER_MISSING),
293         };
294         // Content header is conflicting with Input inline header
295         verify(checkConfig, getPath("InputRegexpHeaderMulti5.java"), expected);
296     }
297 
298     @Test
299     public void testRegexpHeaderMulti6() throws Exception {
300         final DefaultConfiguration checkConfig =
301                 createModuleConfig(RegexpHeaderCheck.class);
302         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader2_4.header"));
303         checkConfig.addProperty("multiLines", "8974382");
304         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
305         // Content header is conflicting with Input inline header
306         verify(checkConfig, getPath("InputRegexpHeaderMulti6.java"), expected);
307     }
308 
309     @Test
310     public void testRegexpHeaderSmallHeader() throws Exception {
311         final DefaultConfiguration checkConfig =
312                 createModuleConfig(RegexpHeaderCheck.class);
313         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader2.header"));
314         checkConfig.addProperty("multiLines", "3, 6");
315         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
316         // Content header is conflicting with Input inline header
317         verify(checkConfig, getPath("InputRegexpHeaderSmallHeader.java"), expected);
318     }
319 
320     @Test
321     public void testEmptyMultiline()
322             throws Exception {
323         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
324         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader2.header"));
325         checkConfig.addProperty("multiLines", "");
326         final String[] expected = {
327             "1: " + getCheckMessage(MSG_HEADER_MISSING),
328         };
329         // Content header is conflicting with Input inline header
330         verify(checkConfig, getPath("InputRegexpHeaderSmallHeader.java"), expected);
331     }
332 
333     @Test
334     public void testRegexpHeaderMulti52()
335             throws Exception {
336         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
337         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader3.header"));
338         final String[] expected = {
339             "1: " + getCheckMessage(MSG_HEADER_MISSING),
340         };
341         // Content header is conflicting with Input inline header
342         verify(checkConfig, getPath("InputRegexpHeaderMulti52.java"), expected);
343     }
344 
345     @Test
346     public void testIgnoreLinesSorted() throws Exception {
347         final DefaultConfiguration checkConfig =
348                 createModuleConfig(RegexpHeaderCheck.class);
349         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader5.header"));
350         checkConfig.addProperty("multiLines", "7,5,3");
351         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
352         // Content header is conflicting with Input inline header
353         verify(checkConfig, getPath("InputRegexpHeaderIgnoreLinesSorted.java"), expected);
354     }
355 
356     @Test
357     public void testHeaderWithInvalidRegexp() throws Exception {
358         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
359         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader.invalid.header"));
360         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
361         final String path = getPath("InputRegexpHeaderMulti52.java");
362         final IllegalArgumentException exc =
363                 getExpectedThrowable(IllegalArgumentException.class,
364                         () -> verify(checkConfig, path, expected));
365         assertWithMessage("Invalid exception message")
366                 .that(exc.getMessage())
367                 .isEqualTo("line 3 in header specification is not a regular expression");
368     }
369 
370     @Test
371     public void testNoWarningIfSingleLinedLeft() throws Exception {
372         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
373         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader4.header"));
374         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
375         // Content header is conflicting with Input inline header
376         verify(checkConfig, getPath("InputRegexpHeaderMulti5.java"), expected);
377     }
378 
379     @Test
380     public void testNoHeaderMissingErrorInCaseHeaderSizeEqualToFileSize() throws Exception {
381         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
382         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader3.header"));
383         checkConfig.addProperty("multiLines", "1");
384         final String[] expected = {
385             "5: " + getCheckMessage(MSG_HEADER_MISMATCH, "^$"),
386         };
387         // Content header is conflicting with Input inline header
388         verify(checkConfig, getPath("InputRegexpHeaderMulti52.java"), expected);
389     }
390 
391     @Test
392     public void testCharsetProperty1() throws Exception {
393         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
394         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader7.header"));
395         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
396         final String path = getPath("InputRegexpHeader4.java");
397         // Content header is conflicting with Input inline header
398         verify(checkConfig, path, expected);
399     }
400 
401     @Test
402     public void testCharsetProperty2() throws Exception {
403         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
404         checkConfig.addProperty("charset", "US-ASCII");
405         checkConfig.addProperty("headerFile", getPath("InputRegexpHeader7.header"));
406         final String[] expected = {
407             // -@cs[RegexpSinglelineJava] need for testing
408             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "// some.class.��������.passed"),
409         };
410         final String path = getPath("InputRegexpHeader4.java");
411         // Content header is conflicting with Input inline header
412         verify(checkConfig, path, expected);
413 
414     }
415 
416     @Test
417     public void testCharsetProperty3() throws Exception {
418         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
419         checkConfig.addProperty("headerFile",
420                 getPath("InputRegexpHeader7.header"));
421         checkConfig.addProperty("charset", "US-ASCII");
422         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
423         final String path = getPath("InputRegexpHeader3.java");
424         // Content header is conflicting with Input inline header
425         verify(checkConfig, path, expected);
426     }
427 }