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 "20: " + 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 = {
249 "16: " + getCheckMessage(MSG_WRITE_TAG, "@author", "Daniel Grenner"),
250 };
251
252 verifyWithInlineConfigParserTwice(
253 getPath("InputWriteTagRegularExpression.java"), expected);
254 }
255
256 @Test
257 public void testRegularExError() throws Exception {
258 final String[] expected = {
259 "15: " + getCheckMessage(MSG_TAG_FORMAT, "@author", "ABC"),
260 };
261 verifyWithInlineConfigParserTwice(
262 getPath("InputWriteTagExpressionError.java"), expected);
263 }
264
265 @Test
266 public void testEnumsAndAnnotations() throws Exception {
267 final String[] expected = {
268 "16: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
269 "This enum needs more code..."),
270 "21: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
271 "This enum constant needs more code..."),
272 "28: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
273 "This annotation needs more code..."),
274 "33: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
275 "This annotation field needs more code..."),
276 };
277 verifyWithInlineConfigParserTwice(
278 getPath("InputWriteTagEnumsAndAnnotations.java"), expected);
279 }
280
281 @Test
282 public void testNoJavadocs() throws Exception {
283 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
284
285 verifyWithInlineConfigParserTwice(getPath("InputWriteTagNoJavadoc.java"), expected);
286 }
287
288 @Test
289 public void testWriteTagRecordsAndCompactCtors() throws Exception {
290 final String[] expected = {
291 "19: " + getCheckMessage(MSG_TAG_FORMAT, "@incomplete", "\\S"),
292 "26: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
293 "Failed to recognize 'record' introduced in Java 14."),
294 "37: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
295 "Failed to recognize 'record' introduced in Java 14."),
296 "48: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
297 "Failed to recognize 'record' introduced in Java 14."),
298 "62: " + getCheckMessage(MSG_WRITE_TAG, "@incomplete",
299 "Failed to recognize 'record' introduced in Java 14."),
300 };
301 verifyWithInlineConfigParserTwice(
302 getPath("InputWriteTagRecordsAndCompactCtors.java"), expected);
303 }
304
305 @Override
306 protected void verify(Checker checker,
307 File[] processedFiles,
308 String messageFileName,
309 String... expected)
310 throws Exception {
311 getStream().flush();
312 final List<File> theFiles = new ArrayList<>();
313 Collections.addAll(theFiles, processedFiles);
314 final int errs = checker.process(theFiles);
315
316
317 try (ByteArrayInputStream localStream =
318 new ByteArrayInputStream(getStream().toByteArray());
319 LineNumberReader lnr = new LineNumberReader(
320 new InputStreamReader(localStream, StandardCharsets.UTF_8))) {
321 for (int i = 0; i < expected.length; i++) {
322 final String expectedResult = messageFileName + ":" + expected[i];
323 final String actual = lnr.readLine();
324 assertWithMessage("error message " + i)
325 .that(actual)
326 .isEqualTo(expectedResult);
327 }
328
329 assertWithMessage("unexpected output: " + lnr.readLine())
330 .that(errs)
331 .isAtMost(expected.length);
332 }
333 checker.destroy();
334 }
335
336 }