View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2018 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.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck.MSG_HEADER_MISMATCH;
23  import static com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck.MSG_HEADER_MISSING;
24  import static org.junit.Assert.assertEquals;
25  import static org.junit.Assert.assertTrue;
26  import static org.junit.Assert.fail;
27  import static org.mockito.ArgumentMatchers.any;
28  import static org.mockito.Mockito.times;
29  import static org.powermock.api.mockito.PowerMockito.doNothing;
30  import static org.powermock.api.mockito.PowerMockito.mockStatic;
31  import static org.powermock.api.mockito.PowerMockito.verifyStatic;
32  
33  import java.io.Reader;
34  import java.util.List;
35  import java.util.Locale;
36  import java.util.regex.Pattern;
37  
38  import org.junit.Test;
39  import org.junit.runner.RunWith;
40  import org.powermock.core.classloader.annotations.PrepareForTest;
41  import org.powermock.modules.junit4.PowerMockRunner;
42  import org.powermock.reflect.Whitebox;
43  
44  import com.google.common.io.Closeables;
45  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
46  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
47  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
48  import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
49  
50  /**
51   * Unit test for RegexpHeaderCheck.
52   * @author richter
53   */
54  @RunWith(PowerMockRunner.class)
55  @PrepareForTest(Closeables.class)
56  public class RegexpHeaderCheckTest extends AbstractModuleTestSupport {
57  
58      @Override
59      protected String getPackageLocation() {
60          return "com/puppycrawl/tools/checkstyle/checks/header/regexpheader";
61      }
62  
63      /**
64       * Test of setHeader method, of class RegexpHeaderCheck.
65       */
66      @Test
67      public void testSetHeaderNull() {
68          // check null passes
69          final RegexpHeaderCheck instance = new RegexpHeaderCheck();
70          // recreate for each test because multiple invocations fail
71          final String header = null;
72          instance.setHeader(header);
73          final List<Pattern> headerRegexps = Whitebox.getInternalState(instance, "headerRegexps");
74  
75          assertTrue("When header is null regexps should not be set", headerRegexps.isEmpty());
76      }
77  
78      /**
79       * Test of setHeader method, of class RegexpHeaderCheck.
80       */
81      @Test
82      public void testSetHeaderEmpty() {
83          // check null passes
84          final RegexpHeaderCheck instance = new RegexpHeaderCheck();
85          // check empty string passes
86          final String header = "";
87          instance.setHeader(header);
88          final List<Pattern> headerRegexps = Whitebox.getInternalState(instance, "headerRegexps");
89  
90          assertTrue("When header is empty regexps should not be set", headerRegexps.isEmpty());
91      }
92  
93      /**
94       * Test of setHeader method, of class RegexpHeaderCheck.
95       */
96      @Test
97      public void testSetHeaderSimple() {
98          //check if reader finally closed
99          mockStatic(Closeables.class);
100         doNothing().when(Closeables.class);
101         Closeables.closeQuietly(any(Reader.class));
102 
103         final RegexpHeaderCheck instance = new RegexpHeaderCheck();
104         // check valid header passes
105         final String header = "abc.*";
106         instance.setHeader(header);
107 
108         verifyStatic(Closeables.class, times(2));
109         Closeables.closeQuietly(any(Reader.class));
110     }
111 
112     /**
113      * Test of setHeader method, of class RegexpHeaderCheck.
114      */
115     @Test
116     public void testSetHeader() {
117         // check invalid header passes
118         final RegexpHeaderCheck instance = new RegexpHeaderCheck();
119         try {
120             final String header = "^/**\\n * Licensed to the Apache Software Foundation (ASF)";
121             instance.setHeader(header);
122             fail(String.format(Locale.ROOT, "%s should have been thrown",
123                     IllegalArgumentException.class));
124         }
125         catch (IllegalArgumentException ex) {
126             assertEquals("Invalid exception message", "Unable to parse format: ^/**\\n *"
127                 + " Licensed to the Apache Software Foundation (ASF)", ex.getMessage());
128         }
129     }
130 
131     @Test
132     public void testDefaultConfiguration() throws Exception {
133         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
134         createChecker(checkConfig);
135         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
136         verify(checkConfig, getPath("InputRegexpHeaderDefaultConfig.java"), expected);
137     }
138 
139     @Test
140     public void testEmptyFilename() throws Exception {
141         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
142         checkConfig.addAttribute("headerFile", "");
143         try {
144             createChecker(checkConfig);
145             fail("Checker creation should not succeed with invalid headerFile");
146         }
147         catch (CheckstyleException ex) {
148             assertEquals("Invalid exception message", "cannot initialize module"
149                     + " com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck"
150                     + " - Cannot set property 'headerFile' to '' in"
151                     + " module com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck",
152                     ex.getMessage());
153         }
154     }
155 
156     @Test
157     public void testRegexpHeader() throws Exception {
158         final DefaultConfiguration checkConfig =
159                 createModuleConfig(RegexpHeaderCheck.class);
160         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader.header"));
161         final String[] expected = {
162             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "// Created: 2002"),
163         };
164         verify(checkConfig, getPath("InputRegexpHeaderIgnore.java"), expected);
165     }
166 
167     @Test
168     public void testRegexpHeaderUrl() throws Exception {
169         final DefaultConfiguration checkConfig =
170                 createModuleConfig(RegexpHeaderCheck.class);
171         checkConfig.addAttribute("headerFile", getUriString("InputRegexpHeader.header"));
172         final String[] expected = {
173             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "// Created: 2002"),
174         };
175         verify(checkConfig, getPath("InputRegexpHeaderIgnore.java"), expected);
176     }
177 
178     @Test
179     public void testInlineRegexpHeader() throws Exception {
180         final DefaultConfiguration checkConfig =
181                 createModuleConfig(RegexpHeaderCheck.class);
182         checkConfig.addAttribute("header", "^/*$\\n// .*\\n// Created: 2002\\n^//.*\\n^//.*");
183         final String[] expected = {
184             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "// Created: 2002"),
185         };
186         verify(checkConfig, getPath("InputRegexpHeaderIgnore.java"), expected);
187     }
188 
189     @Test
190     public void testFailureForMultilineRegexp() throws Exception {
191         final DefaultConfiguration checkConfig =
192                 createModuleConfig(RegexpHeaderCheck.class);
193         checkConfig.addAttribute("header", "^(.*\\n.*)");
194         try {
195             createChecker(checkConfig);
196             fail("Checker creation should not succeed when regexp spans multiple lines");
197         }
198         catch (CheckstyleException ex) {
199             assertEquals("Invalid exception message", "cannot initialize module"
200                     + " com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck"
201                     + " - Cannot set property 'header' to '^(.*\\n.*)' in module"
202                     + " com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck",
203                     ex.getMessage());
204         }
205     }
206 
207     @Test
208     public void testInlineRegexpHeaderConsecutiveNewlines() throws Exception {
209         final DefaultConfiguration checkConfig =
210                 createModuleConfig(RegexpHeaderCheck.class);
211         checkConfig.addAttribute("header", "^/*$\\n// .*\\n\\n// Created: 2017\\n^//.*");
212         final String[] expected = {
213             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "^$"),
214         };
215         verify(checkConfig, getPath("InputRegexpHeaderConsecutiveNewLines.java"), expected);
216     }
217 
218     @Test
219     public void testInlineRegexpHeaderConsecutiveNewlinesThroughConfigFile() throws Exception {
220         final DefaultConfiguration checkConfig =
221                 createModuleConfig(RegexpHeaderCheck.class);
222         checkConfig.addAttribute("headerFile", getUriString("InputRegexpHeaderNewLines.header"));
223         final String[] expected = {
224             "3: " + getCheckMessage(MSG_HEADER_MISMATCH, "^$"),
225         };
226         verify(checkConfig, getPath("InputRegexpHeaderConsecutiveNewLines.java"), expected);
227     }
228 
229     @Test
230     public void testRegexpHeaderIgnore() throws Exception {
231         final DefaultConfiguration checkConfig =
232                 createModuleConfig(RegexpHeaderCheck.class);
233         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader1.header"));
234         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
235         verify(checkConfig, getPath("InputRegexpHeaderIgnore.java"), expected);
236     }
237 
238     @Test
239     public void testRegexpHeaderMulti1() throws Exception {
240         final DefaultConfiguration checkConfig =
241                 createModuleConfig(RegexpHeaderCheck.class);
242         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader2.header"));
243         checkConfig.addAttribute("multiLines", "3, 6");
244         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
245         verify(checkConfig, getPath("InputRegexpHeaderDefaultConfig.java"), expected);
246     }
247 
248     @Test
249     public void testRegexpHeaderMulti2() throws Exception {
250         final DefaultConfiguration checkConfig =
251                 createModuleConfig(RegexpHeaderCheck.class);
252         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader2.header"));
253         checkConfig.addAttribute("multiLines", "3, 6");
254         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
255         verify(checkConfig, getPath("InputRegexpHeaderMulti2.java"), expected);
256     }
257 
258     @Test
259     public void testRegexpHeaderMulti3() throws Exception {
260         final DefaultConfiguration checkConfig =
261                 createModuleConfig(RegexpHeaderCheck.class);
262         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader2.header"));
263         checkConfig.addAttribute("multiLines", "3, 7");
264         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
265         verify(checkConfig, getPath("InputRegexpHeaderDefaultConfig.java"), expected);
266     }
267 
268     @Test
269     public void testRegexpHeaderMulti4() throws Exception {
270         final DefaultConfiguration checkConfig =
271                 createModuleConfig(RegexpHeaderCheck.class);
272         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader2.header"));
273         checkConfig.addAttribute("multiLines", "3, 5, 6, 7");
274         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
275         verify(checkConfig, getPath("InputRegexpHeaderMulti4.java"), expected);
276     }
277 
278     @Test
279     public void testRegexpHeaderMulti5() throws Exception {
280         final DefaultConfiguration checkConfig =
281                 createModuleConfig(RegexpHeaderCheck.class);
282         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader2.header"));
283         checkConfig.addAttribute("multiLines", "3");
284         final String[] expected = {
285             "1: " + getCheckMessage(MSG_HEADER_MISSING),
286         };
287         verify(checkConfig, getPath("InputRegexpHeaderMulti5.java"), expected);
288     }
289 
290     @Test
291     public void testRegexpHeaderMulti6() throws Exception {
292         final DefaultConfiguration checkConfig =
293                 createModuleConfig(RegexpHeaderCheck.class);
294         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader2_4.header"));
295         checkConfig.addAttribute("multiLines", "8974382");
296         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
297         verify(checkConfig, getPath("InputRegexpHeaderMulti6.java"), expected);
298     }
299 
300     @Test
301     public void testRegexpHeaderSmallHeader() throws Exception {
302         final DefaultConfiguration checkConfig =
303                 createModuleConfig(RegexpHeaderCheck.class);
304         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader2.header"));
305         checkConfig.addAttribute("multiLines", "3, 6");
306         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
307         verify(checkConfig, getPath("InputRegexpHeaderSmallHeader.java"), expected);
308     }
309 
310     @Test
311     public void testEmptyMultiline()
312             throws Exception {
313         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
314         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader2.header"));
315         checkConfig.addAttribute("multiLines", "");
316         final String[] expected = {
317             "1: " + getCheckMessage(MSG_HEADER_MISSING),
318         };
319         verify(checkConfig, getPath("InputRegexpHeaderSmallHeader.java"), expected);
320     }
321 
322     @Test
323     public void testRegexpHeaderMulti52()
324             throws Exception {
325         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
326         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader3.header"));
327         final String[] expected = {
328             "1: " + getCheckMessage(MSG_HEADER_MISSING),
329         };
330         verify(checkConfig, getPath("InputRegexpHeaderMulti52.java"), expected);
331     }
332 
333     @Test
334     public void testIgnoreLinesSorted() throws Exception {
335         final DefaultConfiguration checkConfig =
336                 createModuleConfig(RegexpHeaderCheck.class);
337         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader5.header"));
338         checkConfig.addAttribute("multiLines", "7,5,3");
339         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
340         verify(checkConfig, getPath("InputRegexpHeaderIgnoreLinesSorted.java"), expected);
341     }
342 
343     @Test
344     public void testHeaderWithInvalidRegexp() throws Exception {
345         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
346         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader.invalid.header"));
347         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
348         try {
349             verify(checkConfig, getPath("InputRegexpHeaderMulti52.java"), expected);
350             fail("IllegalArgumentException is expected");
351         }
352         catch (IllegalArgumentException ex) {
353             assertEquals("Invalid exception message",
354                 "line 1 in header specification is not a regular expression", ex.getMessage());
355         }
356     }
357 
358     @Test
359     public void testNoWarningIfSingleLinedLeft() throws Exception {
360         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
361         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader4.header"));
362         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
363         verify(checkConfig, getPath("InputRegexpHeaderMulti5.java"), expected);
364     }
365 
366     @Test
367     public void testNoHeaderMissingErrorInCaseHeaderSizeEqualToFileSize() throws Exception {
368         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
369         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader3.header"));
370         checkConfig.addAttribute("multiLines", "1");
371         final String[] expected = {
372             "5: " + getCheckMessage(MSG_HEADER_MISMATCH, "^$"),
373         };
374         verify(checkConfig, getPath("InputRegexpHeaderMulti52.java"), expected);
375     }
376 
377     @Test
378     public void testReaderClosedAfterHeaderRead() throws Exception {
379         mockStatic(Closeables.class);
380         doNothing().when(Closeables.class);
381         Closeables.closeQuietly(any(Reader.class));
382 
383         final DefaultConfiguration checkConfig = createModuleConfig(RegexpHeaderCheck.class);
384         checkConfig.addAttribute("headerFile", getPath("InputRegexpHeader.header"));
385         createChecker(checkConfig);
386 
387         //check if reader finally closed
388         verifyStatic(Closeables.class, times(2));
389         Closeables.closeQuietly(any(Reader.class));
390     }
391 
392 }