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;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.checks.coding.UnusedLocalVariableCheck.MSG_UNUSED_LOCAL_VARIABLE;
24 import static com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck.MSG_KEY;
25
26 import java.io.File;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Optional;
30
31 import org.junit.jupiter.api.AfterEach;
32 import org.junit.jupiter.api.Test;
33
34 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
35 import com.puppycrawl.tools.checkstyle.Checker;
36 import com.puppycrawl.tools.checkstyle.DetailAstImpl;
37 import com.puppycrawl.tools.checkstyle.JavaParser;
38 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
39 import com.puppycrawl.tools.checkstyle.api.DetailAST;
40 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
41 import com.puppycrawl.tools.checkstyle.api.Violation;
42 import com.puppycrawl.tools.checkstyle.checks.coding.UnusedLocalVariableCheck;
43 import com.puppycrawl.tools.checkstyle.checks.naming.AbstractNameCheck;
44 import com.puppycrawl.tools.checkstyle.checks.naming.ConstantNameCheck;
45 import com.puppycrawl.tools.checkstyle.checks.naming.MemberNameCheck;
46 import com.puppycrawl.tools.checkstyle.checks.naming.MethodNameCheck;
47 import com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck;
48 import com.puppycrawl.tools.checkstyle.checks.sizes.ParameterNumberCheck;
49 import com.puppycrawl.tools.checkstyle.checks.whitespace.AbstractParenPadCheck;
50 import com.puppycrawl.tools.checkstyle.checks.whitespace.TypecastParenPadCheck;
51 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
52 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
53
54 public class SuppressWarningsHolderTest extends AbstractModuleTestSupport {
55
56 @Override
57 protected String getPackageLocation() {
58 return "com/puppycrawl/tools/checkstyle/checks/suppresswarningsholder";
59 }
60
61 @AfterEach
62 public void cleanUp() {
63
64
65 new SuppressWarningsHolder().beginTree(null);
66
67 final Map<String, String> map = TestUtil.getInternalStaticStateMap(
68 SuppressWarningsHolder.class, "CHECK_ALIAS_MAP");
69 map.clear();
70 }
71
72 @Test
73 public void testGet() {
74 final SuppressWarningsHolder checkObj = new SuppressWarningsHolder();
75 final int[] expected = {TokenTypes.ANNOTATION};
76 assertWithMessage("Required token array differs from expected")
77 .that(checkObj.getRequiredTokens())
78 .isEqualTo(expected);
79 assertWithMessage("Required token array differs from expected")
80 .that(checkObj.getAcceptableTokens())
81 .isEqualTo(expected);
82 }
83
84 @Test
85 public void testOnComplexAnnotations() throws Exception {
86 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
87
88 verifyWithInlineConfigParser(getPath("InputSuppressWarningsHolder.java"), expected);
89 }
90
91 @Test
92 public void testOnComplexAnnotationsNonConstant() throws Exception {
93 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
94
95 verifyWithInlineConfigParser(
96 getNonCompilablePath("InputSuppressWarningsHolderNonConstant.java"), expected);
97 }
98
99 @Test
100 public void testCustomAnnotation() throws Exception {
101 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
102
103 verifyWithInlineConfigParser(getPath("InputSuppressWarningsHolder5.java"), expected);
104 }
105
106 @Test
107 public void testAll() throws Exception {
108 final String[] expected = {
109 "21:23: "
110 + getCheckMessage(TypecastParenPadCheck.class,
111 AbstractParenPadCheck.MSG_WS_NOT_PRECEDED, ")"),
112 };
113
114 verifyWithInlineConfigParser(getPath("InputSuppressWarningsHolder6.java"), expected);
115 }
116
117 @Test
118 public void testGetDefaultAlias() {
119 assertWithMessage("Default alias differs from expected")
120 .that(SuppressWarningsHolder.getDefaultAlias("SomeName"))
121 .isEqualTo("somename");
122 assertWithMessage("Default alias differs from expected")
123 .that(SuppressWarningsHolder.getDefaultAlias("SomeNameCheck"))
124 .isEqualTo("somename");
125 }
126
127 @Test
128 public void testSetAliasListEmpty() {
129 final SuppressWarningsHolder holder = new SuppressWarningsHolder();
130 holder.setAliasList("");
131 assertWithMessage("Empty alias list should not be set")
132 .that(SuppressWarningsHolder.getAlias(""))
133 .isEqualTo("");
134 }
135
136 @Test
137 public void testSetAliasListCorrect() {
138 final SuppressWarningsHolder holder = new SuppressWarningsHolder();
139 holder.setAliasList("alias=value");
140 assertWithMessage("Alias differs from expected")
141 .that(SuppressWarningsHolder.getAlias("alias"))
142 .isEqualTo("value");
143 }
144
145 @Test
146 public void testSetAliasListWrong() {
147 final SuppressWarningsHolder holder = new SuppressWarningsHolder();
148
149 try {
150 holder.setAliasList("=SomeAlias");
151 assertWithMessage("Exception expected").fail();
152 }
153 catch (IllegalArgumentException exc) {
154 assertWithMessage("Error message is unexpected")
155 .that(exc.getMessage())
156 .isEqualTo("'=' expected in alias list item: =SomeAlias");
157 }
158 }
159
160 @Test
161 public void testAliasCombo() throws Exception {
162 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
163
164 verifyWithInlineXmlConfig(getPath("InputSuppressWarningsHolderAlias3.java"), expected);
165 }
166
167 @Test
168 public void testIsSuppressed() throws Exception {
169 populateHolder("MockEntry", 100, 100, 350, 350);
170 final AuditEvent event = createAuditEvent("check", 100, 10);
171
172 assertWithMessage("Event is not suppressed")
173 .that(SuppressWarningsHolder.isSuppressed(event))
174 .isFalse();
175 }
176
177 @Test
178 public void testIsSuppressedByName() throws Exception {
179 populateHolder("check", 100, 100, 350, 350);
180 final SuppressWarningsHolder holder = new SuppressWarningsHolder();
181 final AuditEvent event = createAuditEvent("id", 110, 10);
182 holder.setAliasList(MemberNameCheck.class.getName() + "=check");
183
184 assertWithMessage("Event is not suppressed")
185 .that(SuppressWarningsHolder.isSuppressed(event))
186 .isTrue();
187 }
188
189 @Test
190 public void testIsSuppressedByModuleId() throws Exception {
191 populateHolder("check", 100, 100, 350, 350);
192 final AuditEvent event = createAuditEvent("check", 350, 350);
193
194 assertWithMessage("Event is not suppressed")
195 .that(SuppressWarningsHolder.isSuppressed(event))
196 .isTrue();
197 }
198
199 @Test
200 public void testIsSuppressedAfterEventEnd() throws Exception {
201 populateHolder("check", 100, 100, 350, 350);
202 final AuditEvent event = createAuditEvent("check", 350, 352);
203
204 assertWithMessage("Event is not suppressed")
205 .that(SuppressWarningsHolder.isSuppressed(event))
206 .isFalse();
207 }
208
209 @Test
210 public void testIsSuppressedAfterEventEnd2() throws Exception {
211 populateHolder("check", 100, 100, 350, 350);
212 final AuditEvent event = createAuditEvent("check", 400, 10);
213
214 assertWithMessage("Event is not suppressed")
215 .that(SuppressWarningsHolder.isSuppressed(event))
216 .isFalse();
217 }
218
219 @Test
220 public void testIsSuppressedAfterEventStart() throws Exception {
221 populateHolder("check", 100, 100, 350, 350);
222 final AuditEvent event = createAuditEvent("check", 100, 100);
223
224 assertWithMessage("Event is not suppressed")
225 .that(SuppressWarningsHolder.isSuppressed(event))
226 .isTrue();
227 }
228
229 @Test
230 public void testIsSuppressedAfterEventStart2() throws Exception {
231 populateHolder("check", 100, 100, 350, 350);
232 final AuditEvent event = createAuditEvent("check", 100, 0);
233
234 assertWithMessage("Event is not suppressed")
235 .that(SuppressWarningsHolder.isSuppressed(event))
236 .isTrue();
237 }
238
239 @Test
240 public void testIsSuppressedWithAllArgument() throws Exception {
241 populateHolder("all", 100, 100, 350, 350);
242
243 final Checker source = new Checker();
244 final Violation firstViolationForTest =
245 new Violation(100, 10, null, null, null, "id", MemberNameCheck.class, "msg");
246 final AuditEvent firstEventForTest =
247 new AuditEvent(source, "fileName", firstViolationForTest);
248 assertWithMessage("Event is suppressed")
249 .that(SuppressWarningsHolder.isSuppressed(firstEventForTest))
250 .isFalse();
251
252 final Violation secondViolationForTest =
253 new Violation(100, 150, null, null, null, "id", MemberNameCheck.class, "msg");
254 final AuditEvent secondEventForTest =
255 new AuditEvent(source, "fileName", secondViolationForTest);
256 assertWithMessage("Event is not suppressed")
257 .that(SuppressWarningsHolder.isSuppressed(secondEventForTest))
258 .isTrue();
259
260 final Violation thirdViolationForTest =
261 new Violation(200, 1, null, null, null, "id", MemberNameCheck.class, "msg");
262 final AuditEvent thirdEventForTest =
263 new AuditEvent(source, "fileName", thirdViolationForTest);
264 assertWithMessage("Event is not suppressed")
265 .that(SuppressWarningsHolder.isSuppressed(thirdEventForTest))
266 .isTrue();
267 }
268
269 @Test
270 public void testAnnotationInTry() throws Exception {
271 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
272
273 verifyWithInlineConfigParser(getPath("InputSuppressWarningsHolder2.java"), expected);
274 }
275
276 @Test
277 public void testEmptyAnnotation() throws Exception {
278 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
279
280 verifyWithInlineConfigParser(getPath("InputSuppressWarningsHolder3.java"), expected);
281 }
282
283 @Test
284 public void testGetAllAnnotationValuesWrongArg() {
285 final SuppressWarningsHolder holder = new SuppressWarningsHolder();
286
287 final DetailAstImpl methodDef = new DetailAstImpl();
288 methodDef.setType(TokenTypes.METHOD_DEF);
289 methodDef.setText("Method Def");
290 methodDef.setLineNo(0);
291 methodDef.setColumnNo(0);
292
293 final DetailAstImpl lparen = new DetailAstImpl();
294 lparen.setType(TokenTypes.LPAREN);
295
296 final DetailAstImpl parent = new DetailAstImpl();
297 parent.addChild(lparen);
298 parent.addChild(methodDef);
299
300 try {
301 TestUtil.invokeMethod(holder, "getAllAnnotationValues", parent);
302 assertWithMessage("Exception expected").fail();
303 }
304 catch (ReflectiveOperationException exc) {
305 assertWithMessage("Error type is unexpected")
306 .that(exc)
307 .hasCauseThat()
308 .isInstanceOf(IllegalArgumentException.class);
309 assertWithMessage("Error message is unexpected")
310 .that(exc)
311 .hasCauseThat()
312 .hasMessageThat()
313 .isEqualTo("Unexpected AST: Method Def[0x0]");
314 }
315 }
316
317 @Test
318 public void testGetAnnotationValuesWrongArg() {
319 final SuppressWarningsHolder holder = new SuppressWarningsHolder();
320
321 final DetailAstImpl methodDef = new DetailAstImpl();
322 methodDef.setType(TokenTypes.METHOD_DEF);
323 methodDef.setText("Method Def");
324 methodDef.setLineNo(0);
325 methodDef.setColumnNo(0);
326
327 try {
328 TestUtil.invokeMethod(holder, "getAnnotationValues", methodDef);
329 assertWithMessage("Exception expected").fail();
330 }
331 catch (ReflectiveOperationException exc) {
332 assertWithMessage("Error type is unexpected")
333 .that(exc)
334 .hasCauseThat()
335 .isInstanceOf(IllegalArgumentException.class);
336 assertWithMessage("Error message is unexpected")
337 .that(exc)
338 .hasCauseThat()
339 .hasMessageThat()
340 .isEqualTo("Expression or annotation array initializer AST expected: "
341 + "Method Def[0x0]");
342 }
343 }
344
345 @Test
346 public void testGetAnnotationTargetWrongArg() {
347 final SuppressWarningsHolder holder = new SuppressWarningsHolder();
348
349 final DetailAstImpl methodDef = new DetailAstImpl();
350 methodDef.setType(TokenTypes.METHOD_DEF);
351 methodDef.setText("Method Def");
352
353 final DetailAstImpl parent = new DetailAstImpl();
354 parent.setType(TokenTypes.ASSIGN);
355 parent.setText("Parent ast");
356 parent.addChild(methodDef);
357 parent.setLineNo(0);
358 parent.setColumnNo(0);
359
360 try {
361 TestUtil.invokeMethod(holder, "getAnnotationTarget", methodDef);
362 assertWithMessage("Exception expected").fail();
363 }
364 catch (ReflectiveOperationException exc) {
365 assertWithMessage("Error type is unexpected")
366 .that(exc)
367 .hasCauseThat()
368 .isInstanceOf(IllegalArgumentException.class);
369 assertWithMessage("Error message is unexpected")
370 .that(exc)
371 .hasCauseThat()
372 .hasMessageThat()
373 .isEqualTo("Unexpected container AST: Parent ast[0x0]");
374 }
375 }
376
377 @Test
378 public void testAstWithoutChildren() {
379 final SuppressWarningsHolder holder = new SuppressWarningsHolder();
380 final DetailAstImpl methodDef = new DetailAstImpl();
381 methodDef.setType(TokenTypes.METHOD_DEF);
382
383 try {
384 holder.visitToken(methodDef);
385 assertWithMessage("Exception expected").fail();
386 }
387 catch (IllegalArgumentException exc) {
388 assertWithMessage("Error message is unexpected")
389 .that(exc.getMessage())
390 .isEqualTo("Identifier AST expected, but get null.");
391 }
392 }
393
394 @Test
395 public void testAnnotationWithFullName() throws Exception {
396 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
397
398 verifyWithInlineConfigParser(getPath("InputSuppressWarningsHolder4.java"), expected);
399 }
400
401 @Test
402 public void testSuppressWarningsAsAnnotationProperty() throws Exception {
403 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
404
405 verifyWithInlineConfigParser(getPath("InputSuppressWarningsHolder7.java"), expected);
406 }
407
408 @SuppressWarnings("unchecked")
409 @Test
410 public void testClearState() throws Exception {
411 final SuppressWarningsHolder check = new SuppressWarningsHolder();
412
413 final Optional<DetailAST> annotationDef = TestUtil.findTokenInAstByPredicate(
414 JavaParser.parseFile(
415 new File(getPath("InputSuppressWarningsHolder.java")),
416 JavaParser.Options.WITHOUT_COMMENTS),
417 ast -> ast.getType() == TokenTypes.ANNOTATION);
418
419 assertWithMessage("Ast should contain ANNOTATION")
420 .that(annotationDef.isPresent())
421 .isTrue();
422 assertWithMessage("State is not cleared on beginTree")
423 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check,
424 annotationDef.orElseThrow(), "ENTRIES",
425 entries -> ((ThreadLocal<List<Object>>) entries).get().isEmpty()))
426 .isTrue();
427 }
428
429 private static void populateHolder(String checkName, int firstLine,
430 int firstColumn, int lastLine,
431 int lastColumn) throws Exception {
432 final Class<?> entry = Class
433 .forName("com.puppycrawl.tools.checkstyle.checks.SuppressWarningsHolder$Entry");
434
435 final Object entryInstance = TestUtil.instantiate(entry, checkName, firstLine,
436 firstColumn, lastLine, lastColumn);
437
438 final ThreadLocal<List<Object>> entries = TestUtil
439 .getInternalStaticStateThreadLocal(SuppressWarningsHolder.class,
440 "ENTRIES");
441 entries.get().add(entryInstance);
442 }
443
444 private static AuditEvent createAuditEvent(String moduleId, int line, int column) {
445 final Checker source = new Checker();
446 final Violation violation = new Violation(line, column, null, null, null,
447 moduleId, MemberNameCheck.class, "violation");
448 return new AuditEvent(source, "filename", violation);
449 }
450
451 @Test
452 public void testSuppressWarningsTextBlocks() throws Exception {
453 final String pattern = "^[a-z][a-zA-Z0-9]*$";
454
455 final String[] expected = {
456 "31:12: " + getCheckMessage(MemberNameCheck.class,
457 AbstractNameCheck.MSG_INVALID_PATTERN, "STRING3", pattern),
458 "33:12: " + getCheckMessage(MemberNameCheck.class,
459 AbstractNameCheck.MSG_INVALID_PATTERN, "STRING4", pattern),
460 "61:12: " + getCheckMessage(MemberNameCheck.class,
461 AbstractNameCheck.MSG_INVALID_PATTERN, "STRING8", pattern),
462 };
463
464 verifyWithInlineConfigParser(
465 getPath("InputSuppressWarningsHolderTextBlocks.java"), expected);
466
467 }
468
469 @Test
470 public void testWithAndWithoutCheckSuffixDifferentCases() throws Exception {
471 final String pattern = "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$";
472 final String[] expected = {
473 "16:30: " + getCheckMessage(ConstantNameCheck.class,
474 AbstractNameCheck.MSG_INVALID_PATTERN, "a", pattern),
475 };
476
477 verifyWithInlineConfigParser(
478 getPath("InputSuppressWarningsHolderWithAndWithoutCheckSuffixDifferentCases.java"),
479 expected);
480 }
481
482 @Test
483 public void testAliasList() throws Exception {
484 final String[] expected = {
485 "16:17: " + getCheckMessage(ParameterNumberCheck.class,
486 ParameterNumberCheck.MSG_KEY, 7, 8),
487 "28:17: " + getCheckMessage(ParameterNumberCheck.class,
488 ParameterNumberCheck.MSG_KEY, 7, 8),
489 };
490 verifyWithInlineConfigParser(
491 getPath("InputSuppressWarningsHolderAlias.java"),
492 expected);
493 }
494
495 @Test
496 public void testAliasList2() throws Exception {
497 final String pattern = "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$";
498 final String[] expected = {
499 "16:29: " + getCheckMessage(ConstantNameCheck.class,
500 AbstractNameCheck.MSG_INVALID_PATTERN, "a", pattern),
501 "19:30: " + getCheckMessage(ConstantNameCheck.class,
502 AbstractNameCheck.MSG_INVALID_PATTERN, "b", pattern),
503 };
504
505 verifyWithInlineConfigParser(
506 getPath("InputSuppressWarningsHolderAlias2.java"),
507 expected);
508 }
509
510 @Test
511 public void testAliasList3() throws Exception {
512 final String[] expected = {
513 "16:17: " + getCheckMessage(ParameterNumberCheck.class,
514 ParameterNumberCheck.MSG_KEY, 7, 8),
515 "28:17: " + getCheckMessage(ParameterNumberCheck.class,
516 ParameterNumberCheck.MSG_KEY, 7, 8),
517 };
518
519 verifyWithInlineConfigParser(
520 getPath("InputSuppressWarningsHolderAlias5.java"),
521 expected);
522 }
523
524 @Test
525 public void testAliasList4() throws Exception {
526 final String pattern = "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$";
527 final String[] expected = {
528 "16:30: " + getCheckMessage(ConstantNameCheck.class,
529 AbstractNameCheck.MSG_INVALID_PATTERN, "a", pattern),
530 "19:30: " + getCheckMessage(ConstantNameCheck.class,
531 AbstractNameCheck.MSG_INVALID_PATTERN, "b", pattern),
532 };
533
534 verifyWithInlineConfigParser(
535 getPath("InputSuppressWarningsHolderAlias4.java"),
536 expected);
537 }
538
539 @Test
540 public void testAliasList5() throws Exception {
541 final String[] expected = {
542 "18: " + getCheckMessage(LineLengthCheck.class, MSG_KEY, 80, 83),
543 "28: " + getCheckMessage(LineLengthCheck.class, MSG_KEY, 75, 96),
544 "28: " + getCheckMessage(LineLengthCheck.class, MSG_KEY, 80, 96),
545 "58: " + getCheckMessage(LineLengthCheck.class, MSG_KEY, 75, 76),
546 "65: " + getCheckMessage(LineLengthCheck.class, MSG_KEY, 75, 87),
547 };
548
549 verifyWithInlineConfigParser(
550 getPath("InputSuppressWarningsHolderAlias6.java"),
551 expected);
552 }
553
554 @Test
555 public void testAliasList6() throws Exception {
556 final String pattern1 = "^[a-z][a-zA-Z0-9]*$";
557 final String pattern2 = "^[A-Z][a-zA-Z0-9]*$";
558
559 final String[] expected = {
560 "25:18: " + getCheckMessage(MethodNameCheck.class,
561 AbstractNameCheck.MSG_INVALID_PATTERN, "Method3", pattern1),
562 "30:20: " + getCheckMessage(MethodNameCheck.class,
563 AbstractNameCheck.MSG_INVALID_PATTERN, "Method5", pattern1),
564 "35:17: " + getCheckMessage(MethodNameCheck.class,
565 AbstractNameCheck.MSG_INVALID_PATTERN, "method7", pattern2),
566 "40:18: " + getCheckMessage(MethodNameCheck.class,
567 AbstractNameCheck.MSG_INVALID_PATTERN, "method9", pattern2),
568 "45:20: " + getCheckMessage(MethodNameCheck.class,
569 AbstractNameCheck.MSG_INVALID_PATTERN, "method11", pattern2),
570 "47:17: " + getCheckMessage(MethodNameCheck.class,
571 AbstractNameCheck.MSG_INVALID_PATTERN, "_methodCheck1", pattern2),
572 "53:18: " + getCheckMessage(MethodNameCheck.class,
573 AbstractNameCheck.MSG_INVALID_PATTERN, "_methodCheck3", pattern2),
574 "53:18: " + getCheckMessage(MethodNameCheck.class,
575 AbstractNameCheck.MSG_INVALID_PATTERN, "_methodCheck3", pattern1),
576 "61:20: " + getCheckMessage(MethodNameCheck.class,
577 AbstractNameCheck.MSG_INVALID_PATTERN, "_methodCheck5", pattern2),
578 "61:20: " + getCheckMessage(MethodNameCheck.class,
579 AbstractNameCheck.MSG_INVALID_PATTERN, "_methodCheck5", pattern1),
580 };
581
582 verifyWithInlineConfigParser(
583 getPath("InputSuppressWarningsHolderAlias7.java"),
584 expected);
585 }
586
587 @Test
588 public void testIdent() throws Exception {
589 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
590 verifyWithInlineConfigParser(
591 getNonCompilablePath("InputSuppressWarningsHolder1.java"),
592 expected);
593 }
594
595 @Test
596 public void testIdent2() throws Exception {
597 final String[] expected = {
598 "37:9: " + getCheckMessage(UnusedLocalVariableCheck.class,
599 MSG_UNUSED_LOCAL_VARIABLE, "a"),
600 "42:9: " + getCheckMessage(UnusedLocalVariableCheck.class,
601 MSG_UNUSED_LOCAL_VARIABLE, "a"),
602 };
603 verifyWithInlineConfigParser(
604 getNonCompilablePath("InputSuppressWarningsHolder2.java"),
605 expected);
606 }
607
608 @Test
609 public void test3() throws Exception {
610 final String pattern = "^[a-z][a-zA-Z0-9]*$";
611
612 final String[] expected = {
613 "18:16: " + getCheckMessage(MemberNameCheck.class,
614 AbstractNameCheck.MSG_INVALID_PATTERN, "K", pattern),
615 };
616 verifyWithInlineConfigParser(
617 getPath("InputSuppressWarningsHolder8.java"),
618 expected);
619 }
620 }