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 check.setHeaderFile(new URI("test://bad"));
210
211 final ReflectiveOperationException ex =
212 getExpectedThrowable(ReflectiveOperationException.class,
213 () -> TestUtil.invokeMethod(check, "loadHeaderFile"));
214 assertWithMessage("Invalid exception cause message")
215 .that(ex)
216 .hasCauseThat()
217 .hasMessageThat()
218 .startsWith("unable to load header file ");
219 }
220
221 @Test
222 public void testCacheHeaderFile() throws Exception {
223 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
224 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.header"));
225
226 final DefaultConfiguration checkerConfig = createRootConfig(checkConfig);
227 final File cacheFile = Files.createTempFile(temporaryFolder.toPath(), "junit", null)
228 .toFile();
229 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
230
231 final String[] expected = {
232 "1: " + getCheckMessage(MSG_MISSING),
233 };
234
235
236 verify(checkerConfig, getPath("InputHeader.java"), expected);
237
238
239 verify(checkerConfig, getPath("InputHeader.java"), expected);
240 }
241
242 @Test
243 public void testCacheHeaderWithoutFile() throws Exception {
244 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
245 checkConfig.addProperty("header", "Test");
246
247 final DefaultConfiguration checkerConfig = createRootConfig(checkConfig);
248 final File cacheFile = Files.createTempFile(temporaryFolder.toPath(), "junit", null)
249 .toFile();
250 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
251
252 final String[] expected = {
253 "1: " + getCheckMessage(MSG_MISMATCH, "Test"),
254 };
255
256
257 verify(checkerConfig, getPath("InputHeader.java"), expected);
258 }
259
260 @Test
261 public void testIgnoreLinesSorted() throws Exception {
262 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
263 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.header"));
264 checkConfig.addProperty("ignoreLines", "4,2,3");
265 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
266 verify(checkConfig, getPath("InputHeaderjava3.header"), expected);
267 }
268
269 @Test
270 public void testLoadHeaderFileTwice() {
271 final HeaderCheck check = new HeaderCheck();
272 check.setHeader("Header");
273 final ReflectiveOperationException ex =
274 getExpectedThrowable(ReflectiveOperationException.class,
275 () -> TestUtil.invokeMethod(check, "loadHeaderFile"));
276 assertWithMessage("Invalid exception cause message")
277 .that(ex)
278 .hasCauseThat()
279 .hasMessageThat()
280 .isEqualTo("header has already been set - "
281 + "set either header or headerFile, not both");
282 }
283
284 @Test
285 public void testHeaderIsValidWithBlankLines() throws Exception {
286 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
287 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.blank-lines.header"));
288
289 verify(checkConfig, getPath("InputHeaderBlankLines.java"));
290 }
291
292 @Test
293 public void testHeaderIsValidWithBlankLinesBlockStyle() throws Exception {
294 final DefaultConfiguration checkConfig = createModuleConfig(HeaderCheck.class);
295 checkConfig.addProperty("headerFile", getPath("InputHeaderjava.blank-lines2.header"));
296
297 verify(checkConfig, getPath("InputHeaderBlankLines2.java"));
298 }
299
300 @Test
301 public void testExternalResource() throws Exception {
302 final HeaderCheck check = new HeaderCheck();
303 final URI uri = CommonUtil.getUriByFilename(getPath("InputHeaderjava.header"));
304 check.setHeaderFile(uri);
305 final Set<String> results = check.getExternalResourceLocations();
306 assertWithMessage("Invalid result size")
307 .that(results.size())
308 .isEqualTo(1);
309 assertWithMessage("Invalid resource location")
310 .that(results.iterator().next())
311 .isEqualTo(uri.toASCIIString());
312 }
313
314 @Test
315 public void testIoExceptionWhenLoadingHeader() {
316 final HeaderCheck check = new HeaderCheck();
317 try (MockedConstruction<LineNumberReader> mocked = mockConstruction(
318 LineNumberReader.class, (mock, context) -> {
319 when(mock.readLine()).thenThrow(IOException.class);
320 })) {
321 final IllegalArgumentException ex =
322 getExpectedThrowable(IllegalArgumentException.class,
323 () -> check.setHeader("header"));
324 assertWithMessage("Invalid exception cause")
325 .that(ex)
326 .hasCauseThat()
327 .isInstanceOf(IOException.class);
328 assertWithMessage("Invalid exception message")
329 .that(ex)
330 .hasMessageThat()
331 .isEqualTo("unable to load header");
332 }
333 }
334
335 }