1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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.HeaderCheck.MSG_MISMATCH;
24 import static com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck.MSG_MISSING;
25 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
26 import static org.mockito.Mockito.mockConstruction;
27 import static org.mockito.Mockito.when;
28
29 import java.io.File;
30 import java.io.IOException;
31 import java.io.LineNumberReader;
32 import java.net.URI;
33 import java.nio.file.Files;
34 import java.util.Set;
35
36 import org.junit.jupiter.api.Test;
37 import org.junit.jupiter.api.io.TempDir;
38 import org.mockito.MockedConstruction;
39
40 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
41 import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
42 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
43 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
44 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
45
46 public class HeaderCheckTest extends AbstractModuleTestSupport {
47
48 @TempDir
49 public File temporaryFolder;
50
51 @Override
52 protected String getPackageLocation() {
53 return "com/puppycrawl/tools/checkstyle/checks/header/header";
54 }
55
56 @Test
57 public void testStaticHeader() throws Exception {
58 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
59 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.header"));
60 checkConfig.addProperty("ignoreLines", "");
61 final String[] expected = {
62 "1: " + getCheckMessage(MSG_MISSING),
63 };
64
65 verify(checkConfig, getPath("InputHeader.java"), expected);
66 }
67
68 @Test
69 public void testNoHeader() throws Exception {
70 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
71
72 createChecker(checkConfig);
73 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
74
75 verify(checkConfig, getPath("InputHeaderRegexp.java"), expected);
76 }
77
78 @Test
79 public void testWhitespaceHeader() throws Exception {
80 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
81 checkConfig.addProperty("header", "\n \n");
82
83 createChecker(checkConfig);
84 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
85
86 verify(checkConfig, getPath("InputHeaderRegexp.java"), expected);
87 }
88
89 @Test
90 public void testNonExistentHeaderFile() throws Exception {
91 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
92 checkConfig.addProperty("headerFile", getPath("nonExistent.file"));
93 final CheckstyleException ex = getExpectedThrowable(CheckstyleException.class,
94 () -> createChecker(checkConfig));
95 assertWithMessage("Invalid exception message")
96 .that(ex)
97 .hasMessageThat()
98 .startsWith("cannot initialize module"
99 + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
100 + " - illegal value ");
101 assertWithMessage("Invalid cause exception message")
102 .that(ex)
103 .hasCauseThat()
104 .hasCauseThat()
105 .hasCauseThat()
106 .hasMessageThat()
107 .startsWith("Unable to find: ");
108 }
109
110 @Test
111 public void testInvalidCharset() throws Exception {
112 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
113 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.header"));
114 checkConfig.addProperty("charset", "XSO-8859-1");
115 final CheckstyleException ex = getExpectedThrowable(CheckstyleException.class,
116 () -> createChecker(checkConfig));
117 assertWithMessage("Invalid exception message")
118 .that(ex)
119 .hasMessageThat()
120 .isEqualTo("cannot initialize module"
121 + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
122 + " - Cannot set property 'charset' to 'XSO-8859-1'");
123 assertWithMessage("Invalid cause exception message")
124 .that(ex)
125 .hasCauseThat()
126 .hasCauseThat()
127 .hasCauseThat()
128 .hasMessageThat()
129 .startsWith("unsupported charset: 'XSO-8859-1'");
130 }
131
132 @Test
133 public void testEmptyFilename() {
134 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
135 checkConfig.addProperty("headerFile", "");
136 final CheckstyleException ex = getExpectedThrowable(CheckstyleException.class,
137 () -> createChecker(checkConfig));
138 assertWithMessage("Invalid exception message")
139 .that(ex)
140 .hasMessageThat()
141 .isEqualTo("cannot initialize module"
142 + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
143 + " - Cannot set property 'headerFile' to ''");
144 assertWithMessage("Invalid cause exception message")
145 .that(ex)
146 .hasCauseThat()
147 .hasCauseThat()
148 .hasCauseThat()
149 .hasMessageThat()
150 .isEqualTo("property 'headerFile' is missing or invalid in module"
151 + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck");
152 }
153
154 @Test
155 public void testNullFilename() {
156 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
157 checkConfig.addProperty("headerFile", null);
158 final CheckstyleException ex = getExpectedThrowable(CheckstyleException.class,
159 () -> createChecker(checkConfig));
160 assertWithMessage("Invalid exception message")
161 .that(ex)
162 .hasMessageThat()
163 .isEqualTo("cannot initialize module"
164 + " com.puppycrawl.tools.checkstyle.checks.header.HeaderCheck"
165 + " - Cannot set property 'headerFile' to 'null'");
166 }
167
168 @Test
169 public void testNotMatch() throws Exception {
170 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
171 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.header"));
172 checkConfig.addProperty("ignoreLines", "");
173 final String[] expected = {
174 "2: " + getCheckMessage(MSG_MISMATCH,
175 "// checkstyle: Checks Java source code and other text files for adherence to a"
176 + " set of rules."),
177 };
178
179 verify(checkConfig, getPath("InputHeaderjava2.header"), expected);
180 }
181
182 @Test
183 public void testIgnore() throws Exception {
184 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
185 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.header"));
186 checkConfig.addProperty("ignoreLines", "2");
187 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
188
189 verify(checkConfig, getPath("InputHeaderjava2.header"), expected);
190 }
191
192 @Test
193 public void testSetHeaderTwice() {
194 final HeaderCheck check = new HeaderCheck();
195 check.setHeader("Header");
196 final IllegalArgumentException ex =
197 getExpectedThrowable(IllegalArgumentException.class,
198 () -> check.setHeader("Header2"));
199 assertWithMessage("Invalid exception message")
200 .that(ex)
201 .hasMessageThat()
202 .isEqualTo("header has already been set - "
203 + "set either header or headerFile, not both");
204 }
205
206 @Test
207 public void testIoExceptionWhenLoadingHeaderFile() throws Exception {
208 final HeaderCheck check = new HeaderCheck();
209 final String uri = "test://bad";
210 check.setHeaderFile(new URI(uri));
211
212 final ReflectiveOperationException ex =
213 getExpectedThrowable(ReflectiveOperationException.class,
214 () -> TestUtil.invokeVoidMethod(check, "loadHeaderFile"));
215 assertWithMessage("Invalid exception cause message")
216 .that(ex)
217 .hasCauseThat()
218 .hasMessageThat()
219 .isEqualTo("unable to load header file " + uri);
220 }
221
222 @Test
223 public void testCacheHeaderFile() throws Exception {
224 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
225 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.header"));
226
227 final DefaultConfiguration checkerConfig = createRootConfig(checkConfig);
228 final File cacheFile = Files.createTempFile(temporaryFolder.toPath(), "junit", null)
229 .toFile();
230 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
231
232 final String[] expected = {
233 "1: " + getCheckMessage(MSG_MISSING),
234 };
235
236
237 verify(checkerConfig, getPath("InputHeader.java"), expected);
238
239
240 verify(checkerConfig, getPath("InputHeader.java"), expected);
241 }
242
243 @Test
244 public void testCacheHeaderWithoutFile() throws Exception {
245 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
246 checkConfig.addProperty("header", "Test");
247
248 final DefaultConfiguration checkerConfig = createRootConfig(checkConfig);
249 final File cacheFile = Files.createTempFile(temporaryFolder.toPath(), "junit", null)
250 .toFile();
251 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
252
253 final String[] expected = {
254 "1: " + getCheckMessage(MSG_MISMATCH, "Test"),
255 };
256
257
258 verify(checkerConfig, getPath("InputHeader.java"), expected);
259 }
260
261 @Test
262 public void testIgnoreLinesSorted() throws Exception {
263 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
264 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.header"));
265 checkConfig.addProperty("ignoreLines", "4,2,3");
266 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
267 verify(checkConfig, getPath("InputHeaderjava3.header"), expected);
268 }
269
270 @Test
271 public void testLoadHeaderFileTwice() {
272 final HeaderCheck check = new HeaderCheck();
273 check.setHeader("Header");
274 final ReflectiveOperationException ex =
275 getExpectedThrowable(ReflectiveOperationException.class,
276 () -> TestUtil.invokeVoidMethod(check, "loadHeaderFile"));
277 assertWithMessage("Invalid exception cause message")
278 .that(ex)
279 .hasCauseThat()
280 .hasMessageThat()
281 .isEqualTo("header has already been set - "
282 + "set either header or headerFile, not both");
283 }
284
285 @Test
286 public void testHeaderIsValidWithBlankLines() throws Exception {
287 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
288 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.blank-lines.header"));
289
290 verify(checkConfig, getPath("InputHeaderBlankLines.java"));
291 }
292
293 @Test
294 public void testHeaderIsValidWithBlankLinesBlockStyle() throws Exception {
295 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
296 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.blank-lines2.header"));
297
298 verify(checkConfig, getPath("InputHeaderBlankLines2.java"));
299 }
300
301 @Test
302 public void testExternalResource() throws Exception {
303 final HeaderCheck check = new HeaderCheck();
304 final URI uri = CommonUtil.getUriByFilename(getPath("InputHeaderjava.header"));
305 check.setHeaderFile(uri);
306 final Set<String> results = check.getExternalResourceLocations();
307 assertWithMessage("Invalid result size")
308 .that(results.size())
309 .isEqualTo(1);
310 assertWithMessage("Invalid resource location")
311 .that(results.iterator().next())
312 .isEqualTo(uri.toASCIIString());
313 }
314
315 @Test
316 public void testIoExceptionWhenLoadingHeader() {
317 final HeaderCheck check = new HeaderCheck();
318 try (MockedConstruction<LineNumberReader> mocked = mockConstruction(
319 LineNumberReader.class, (mock, context) -> {
320 when(mock.readLine()).thenThrow(IOException.class);
321 })) {
322 final IllegalArgumentException ex =
323 getExpectedThrowable(IllegalArgumentException.class,
324 () -> check.setHeader("header"));
325 assertWithMessage("Invalid exception cause")
326 .that(ex)
327 .hasCauseThat()
328 .isInstanceOf(IOException.class);
329 assertWithMessage("Invalid exception message")
330 .that(ex)
331 .hasMessageThat()
332 .isEqualTo("unable to load header");
333 }
334 }
335
336 }