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.javadoc;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.checks.javadoc.WriteTagCheck.MSG_MISSING_TAG;
24 import static com.puppycrawl.tools.checkstyle.checks.javadoc.WriteTagCheck.MSG_TAG_FORMAT;
25 import static com.puppycrawl.tools.checkstyle.checks.javadoc.WriteTagCheck.MSG_WRITE_TAG;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.File;
30 import java.io.InputStreamReader;
31 import java.io.LineNumberReader;
32 import java.nio.charset.StandardCharsets;
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.HashSet;
36 import java.util.List;
37 import java.util.Locale;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
40
41 import org.junit.jupiter.api.Test;
42
43 import com.puppycrawl.tools.checkstyle.AbstractAutomaticBean;
44 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
45 import com.puppycrawl.tools.checkstyle.Checker;
46 import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
47 import com.puppycrawl.tools.checkstyle.DefaultLogger;
48 import com.puppycrawl.tools.checkstyle.PackageObjectFactory;
49 import com.puppycrawl.tools.checkstyle.TreeWalker;
50 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
51 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
52 import de.thetaphi.forbiddenapis.SuppressForbidden;
53
54
55
56
57 public class WriteTagCheckTest extends AbstractModuleTestSupport {
58
59 @Override
60 protected String getPackageLocation() {
61 return "com/puppycrawl/tools/checkstyle/checks/javadoc/writetag";
62 }
63
64 @Test
65 public void testDefaultSettings() throws Exception {
66 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
67 verifyWithInlineConfigParser(getPath("InputWriteTagDefault.java"), expected);
68 }
69
70 @Test
71 public void testTag() throws Exception {
72 final String[] expected = {
73 "15: " + getCheckMessage(MSG_WRITE_TAG, "@author", "Daniel Grenner"),
74 };
75 verifyWithInlineConfigParserTwice(getPath("InputWriteTag.java"), expected);
76 }
77
78 @Test
79 public void testMissingFormat() throws Exception {
80 final String[] expected = {
81 "15: " + getCheckMessage(MSG_WRITE_TAG, "@author", "Daniel Grenner"),
82 };
83 verifyWithInlineConfigParserTwice(
84 getPath("InputWriteTagMissingFormat.java"), expected);
85 }
86
87 @Test
88 public void testTagIncomplete() throws Exception {
89 final String[] expected = {
90 "16: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
91 "This class needs more code..."),
92 };
93 verifyWithInlineConfigParserTwice(
94 getPath("InputWriteTagIncomplete.java"), expected);
95 }
96
97 @Test
98 public void testDoubleTag() throws Exception {
99 final String[] expected = {
100 "18: " + getCheckMessage(MSG_WRITE_TAG, "@doubletag", "first text"),
101 "19: " + getCheckMessage(MSG_WRITE_TAG, "@doubletag", "second text"),
102 };
103 verifyWithInlineConfigParserTwice(
104 getPath("InputWriteTagDoubleTag.java"), expected);
105 }
106
107 @Test
108 public void testEmptyTag() throws Exception {
109 final String[] expected = {
110 "19: " + getCheckMessage(MSG_WRITE_TAG, "@emptytag", ""),
111 };
112 verifyWithInlineConfigParserTwice(
113 getPath("InputWriteTagEmptyTag.java"), expected);
114 }
115
116 @Test
117 public void testMissingTag() throws Exception {
118 final String[] expected = {
119 "20: " + getCheckMessage(MSG_MISSING_TAG, "@missingtag"),
120 };
121 verifyWithInlineConfigParserTwice(
122 getPath("InputWriteTagMissingTag.java"), expected);
123 }
124
125 @Test
126 public void testInterface() throws Exception {
127 final String[] expected = {
128 "15: " + getCheckMessage(MSG_WRITE_TAG, "@author", "Daniel Grenner"),
129 };
130 verifyWithInlineConfigParserTwice(
131 getPath("InputWriteTagInterface.java"), expected
132 );
133 }
134
135 @Test
136 public void testBlockComment() throws Exception {
137 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
138 verifyWithInlineConfigParserTwice(
139 getPath("InputWriteTagBlockComment.java"), expected
140 );
141 }
142
143 @Test
144 public void testMethod() throws Exception {
145 final String[] expected = {
146 "24: " + getCheckMessage(MSG_WRITE_TAG, "@todo",
147 "Add a constructor comment"),
148 "36: " + getCheckMessage(MSG_WRITE_TAG, "@todo", "Add a comment"),
149 };
150 verifyWithInlineConfigParserTwice(
151 getPath("InputWriteTagMethod.java"), expected);
152 }
153
154 @Test
155 public void testSeverity() throws Exception {
156 final String[] expected = {
157 "16: " + getCheckMessage(MSG_WRITE_TAG, "@author", "Daniel Grenner"),
158 };
159 verifyWithInlineConfigParserTwice(
160 getPath("InputWriteTagSeverity.java"), expected);
161 }
162
163
164
165
166
167
168
169
170
171
172
173 @Test
174 @SuppressForbidden
175 public void testResetSeverityLevel() throws Exception {
176
177 final Checker checker = new Checker();
178
179 final TreeWalker treeWalker = new TreeWalker();
180 final PackageObjectFactory factory = new PackageObjectFactory(
181 new HashSet<>(), Thread.currentThread().getContextClassLoader());
182
183 treeWalker.setModuleFactory(factory);
184 treeWalker.finishLocalSetup();
185
186 final DefaultConfiguration writeTagConfig = createModuleConfig(WriteTagCheck.class);
187 writeTagConfig.addProperty("tag", "@author");
188 writeTagConfig.addProperty("tagFormat", "Mohanad");
189 writeTagConfig.addProperty("tagSeverity", "warning");
190
191 treeWalker.setupChild(writeTagConfig);
192
193 checker.addFileSetCheck(treeWalker);
194
195 final ByteArrayOutputStream out = TestUtil.getInternalState(this, "stream");
196 final DefaultLogger logger = new DefaultLogger(out,
197 AbstractAutomaticBean.OutputStreamOptions.CLOSE);
198 checker.addListener(logger);
199
200 execute(checker, getPath("InputWriteTagResetSeverity.java"));
201
202 final String output = out.toString();
203
204
205 final Pattern severityPattern = Pattern.compile("\\[(ERROR|WARN|INFO|IGNORE)]");
206
207 final Matcher matcher = severityPattern.matcher(output);
208
209
210 final boolean firstMatchFound = matcher.find();
211 assertWithMessage("Severity level should be wrapped in a square bracket []")
212 .that(firstMatchFound)
213 .isTrue();
214
215 final String tagExpectedSeverityLevel = "warn";
216 final String firstSeverityLevel = matcher.group(1).toLowerCase(Locale.ENGLISH);
217
218 assertWithMessage("First log should have an error severity level")
219 .that(firstSeverityLevel)
220 .isEqualTo(tagExpectedSeverityLevel);
221
222
223
224 final boolean secondMatchFound = matcher.find();
225 assertWithMessage("Severity level should be wrapped in a square bracket []")
226 .that(secondMatchFound)
227 .isTrue();
228
229 final String expectedSeverityLevelAfterReset = "error";
230
231 final String secondSeverityLevel = matcher.group(1).toLowerCase(Locale.ENGLISH);
232
233 assertWithMessage("Second violation's severity level"
234 + " should have been reset back to default (error)")
235 .that(secondSeverityLevel)
236 .isEqualTo(expectedSeverityLevelAfterReset);
237
238 }
239
240 @Test
241 public void testIgnoreMissing() throws Exception {
242 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
243 verifyWithInlineConfigParserTwice(getPath("InputWriteTagIgnore.java"), expected);
244 }
245
246 @Test
247 public void testRegularEx() throws Exception {
248 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
249 verifyWithInlineConfigParserTwice(
250 getPath("InputWriteTagRegularExpression.java"), expected);
251 }
252
253 @Test
254 public void testRegularExError() throws Exception {
255 final String[] expected = {
256 "15: " + getCheckMessage(MSG_TAG_FORMAT, "@author", "ABC"),
257 };
258 verifyWithInlineConfigParserTwice(
259 getPath("InputWriteTagExpressionError.java"), expected);
260 }
261
262 @Test
263 public void testEnumsAndAnnotations() throws Exception {
264 final String[] expected = {
265 "16: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
266 "This enum needs more code..."),
267 "21: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
268 "This enum constant needs more code..."),
269 "28: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
270 "This annotation needs more code..."),
271 "33: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
272 "This annotation field needs more code..."),
273 };
274 verifyWithInlineConfigParserTwice(
275 getPath("InputWriteTagEnumsAndAnnotations.java"), expected);
276 }
277
278 @Test
279 public void testNoJavadocs() throws Exception {
280 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
281
282 verifyWithInlineConfigParserTwice(getPath("InputWriteTagNoJavadoc.java"), expected);
283 }
284
285 @Test
286 public void testWriteTagRecordsAndCompactCtors() throws Exception {
287 final String[] expected = {
288 "19: " + getCheckMessage(MSG_TAG_FORMAT, "@incomplete", "\\S"),
289 "26: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
290 "Failed to recognize 'record' introduced in Java 14."),
291 "37: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
292 "Failed to recognize 'record' introduced in Java 14."),
293 "48: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
294 "Failed to recognize 'record' introduced in Java 14."),
295 "62: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
296 "Failed to recognize 'record' introduced in Java 14."),
297 };
298 verifyWithInlineConfigParserTwice(
299 getNonCompilablePath("InputWriteTagRecordsAndCompactCtors.java"), expected);
300 }
301
302 @Override
303 protected void verify(Checker checker,
304 File[] processedFiles,
305 String messageFileName,
306 String... expected)
307 throws Exception {
308 getStream().flush();
309 final List<File> theFiles = new ArrayList<>();
310 Collections.addAll(theFiles, processedFiles);
311 final int errs = checker.process(theFiles);
312
313
314 try (ByteArrayInputStream localStream =
315 new ByteArrayInputStream(getStream().toByteArray());
316 LineNumberReader lnr = new LineNumberReader(
317 new InputStreamReader(localStream, StandardCharsets.UTF_8))) {
318 for (int i = 0; i < expected.length; i++) {
319 final String expectedResult = messageFileName + ":" + expected[i];
320 final String actual = lnr.readLine();
321 assertWithMessage("error message " + i)
322 .that(actual)
323 .isEqualTo(expectedResult);
324 }
325
326 assertWithMessage("unexpected output: " + lnr.readLine())
327 .that(errs)
328 .isAtMost(expected.length);
329 }
330 checker.destroy();
331 }
332
333 }