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