View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2025 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ///////////////////////////////////////////////////////////////////////////////////////////////
19  
20  package com.puppycrawl.tools.checkstyle.checks.imports;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.imports.CustomImportOrderCheck.MSG_LEX;
24  import static com.puppycrawl.tools.checkstyle.checks.imports.CustomImportOrderCheck.MSG_LINE_SEPARATOR;
25  import static com.puppycrawl.tools.checkstyle.checks.imports.CustomImportOrderCheck.MSG_NONGROUP_EXPECTED;
26  import static com.puppycrawl.tools.checkstyle.checks.imports.CustomImportOrderCheck.MSG_NONGROUP_IMPORT;
27  import static com.puppycrawl.tools.checkstyle.checks.imports.CustomImportOrderCheck.MSG_ORDER;
28  import static com.puppycrawl.tools.checkstyle.checks.imports.CustomImportOrderCheck.MSG_SEPARATED_IN_GROUP;
29  
30  import java.io.File;
31  
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.DefaultConfiguration;
37  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
38  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
39  import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
40  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
41  
42  public class CustomImportOrderCheckTest extends AbstractModuleTestSupport {
43  
44      /** Shortcuts to make code more compact. */
45      private static final String STATIC = CustomImportOrderCheck.STATIC_RULE_GROUP;
46      private static final String SAME = CustomImportOrderCheck.SAME_PACKAGE_RULE_GROUP;
47      private static final String THIRD = CustomImportOrderCheck.THIRD_PARTY_PACKAGE_RULE_GROUP;
48      private static final String STD = CustomImportOrderCheck.STANDARD_JAVA_PACKAGE_RULE_GROUP;
49      private static final String SPECIAL = CustomImportOrderCheck.SPECIAL_IMPORTS_RULE_GROUP;
50  
51      @Override
52      protected String getPackageLocation() {
53          return "com/puppycrawl/tools/checkstyle/checks/imports/customimportorder";
54      }
55  
56      @Test
57      public void testGetRequiredTokens() {
58          final CustomImportOrderCheck checkObj = new CustomImportOrderCheck();
59          final int[] expected = {
60              TokenTypes.IMPORT,
61              TokenTypes.STATIC_IMPORT,
62              TokenTypes.PACKAGE_DEF,
63          };
64          assertWithMessage("Default required tokens are invalid")
65              .that(checkObj.getRequiredTokens())
66              .isEqualTo(expected);
67      }
68  
69      @Test
70      public void testCustom() throws Exception {
71          final String[] expected = {
72              "16:1: " + getCheckMessage(MSG_LEX, "java.awt.Button.ABORT",
73                      "java.io.File.createTempFile"),
74              "17:1: " + getCheckMessage(MSG_LEX, "java.awt.print.Paper.*",
75                      "java.io.File.createTempFile"),
76              "20:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.awt.Button"),
77              "21:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.awt.Frame"),
78              "22:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.awt.Dialog"),
79              "23:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.awt.color.ColorSpace"),
80              "24:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.awt.event.ActionEvent"),
81              "25:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "javax.swing.JComponent"),
82              "26:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "javax.swing.JTable"),
83              "27:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.io.File"),
84              "28:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.io.IOException"),
85              "29:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.io.InputStream"),
86              "30:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.io.Reader"),
87          };
88  
89          verifyWithInlineConfigParser(
90                  getPath("InputCustomImportOrderDefault.java"), expected);
91      }
92  
93      /**
94       * Checks different group orderings and imports which are out of those
95       * specified in the configuration.
96       */
97      @Test
98      public void testStaticStandardThird() throws Exception {
99          final String[] expected = {
100             "16:1: " + getCheckMessage(MSG_LEX, "java.awt.Button.ABORT",
101                     "java.io.File.createTempFile"),
102             "17:1: " + getCheckMessage(MSG_LEX, "java.awt.print.Paper.*",
103                     "java.io.File.createTempFile"),
104             "22:1: " + getCheckMessage(MSG_LEX, "java.awt.Dialog", "java.awt.Frame"),
105             "27:1: " + getCheckMessage(MSG_LEX, "java.io.File", "javax.swing.JTable"),
106             "28:1: " + getCheckMessage(MSG_LEX, "java.io.IOException", "javax.swing.JTable"),
107             "29:1: " + getCheckMessage(MSG_LEX, "java.io.InputStream", "javax.swing.JTable"),
108             "30:1: " + getCheckMessage(MSG_LEX, "java.io.Reader", "javax.swing.JTable"),
109             "34:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "com.google.common.collect.*"),
110             "34:1: " + getCheckMessage(MSG_LEX, "com.google.common.collect.*",
111                     "com.google.errorprone.annotations.*"),
112         };
113 
114         verifyWithInlineConfigParser(
115                 getPath("InputCustomImportOrderDefault3.java"), expected);
116     }
117 
118     @Test
119     public void testStaticStandardThirdListCustomRules() throws Exception {
120         final String[] expected = {
121             "16:1: " + getCheckMessage(MSG_LEX, "java.awt.Button.ABORT",
122                     "java.io.File.createTempFile"),
123             "17:1: " + getCheckMessage(MSG_LEX, "java.awt.print.Paper.*",
124                     "java.io.File.createTempFile"),
125             "22:1: " + getCheckMessage(MSG_LEX, "java.awt.Dialog", "java.awt.Frame"),
126             "27:1: " + getCheckMessage(MSG_LEX, "java.io.File", "javax.swing.JTable"),
127             "28:1: " + getCheckMessage(MSG_LEX, "java.io.IOException", "javax.swing.JTable"),
128             "29:1: " + getCheckMessage(MSG_LEX, "java.io.InputStream", "javax.swing.JTable"),
129             "30:1: " + getCheckMessage(MSG_LEX, "java.io.Reader", "javax.swing.JTable"),
130             "34:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "com.google.common.collect.*"),
131             "34:1: " + getCheckMessage(MSG_LEX, "com.google.common.collect.*",
132                     "com.google.errorprone.annotations.*"),
133         };
134 
135         verifyWithInlineConfigParser(
136                 getPath("InputCustomImportOrderListRules.java"), expected);
137     }
138 
139     @Test
140     public void testStaticStandardThirdListCustomRulesWhitespace() throws Exception {
141         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
142 
143         verifyWithInlineConfigParser(
144                 getPath("InputCustomImportOrderListRulesWhitespace.java"), expected);
145     }
146 
147     @Test
148     public void testInputCustomImportOrderSingleLineList() throws Exception {
149         final String[] expected = {
150             "14:112: " + getCheckMessage(MSG_LINE_SEPARATOR,
151                 "java.util.Map"),
152             "15:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
153                 "com.google.common.annotations.Beta"),
154             "22:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
155                 "com.puppycrawl.tools.checkstyle.*"),
156             "26:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
157                 "picocli.*"),
158         };
159         verifyWithInlineConfigParser(
160                 getPath("InputCustomImportOrderSingleLineList.java"),
161             expected);
162     }
163 
164     /**
165      * Checks different combinations for same_package group.
166      */
167     @Test
168     public void testNonSpecifiedImports() throws Exception {
169         final String[] expected = {
170             "16:1: " + getCheckMessage(MSG_LEX, "java.awt.Button.ABORT",
171                 "java.io.File.createTempFile"),
172             "17:1: " + getCheckMessage(MSG_LEX, "java.awt.print.Paper.*",
173                 "java.io.File.createTempFile"),
174             "22:1: " + getCheckMessage(MSG_LEX, "java.awt.Dialog", "java.awt.Frame"),
175             "27:1: " + getCheckMessage(MSG_LEX, "java.io.File", "javax.swing.JTable"),
176             "28:1: " + getCheckMessage(MSG_LEX, "java.io.IOException", "javax.swing.JTable"),
177             "29:1: " + getCheckMessage(MSG_LEX, "java.io.InputStream", "javax.swing.JTable"),
178             "30:1: " + getCheckMessage(MSG_LEX, "java.io.Reader", "javax.swing.JTable"),
179             "32:1: " + getCheckMessage(MSG_ORDER, SAME, THIRD, "com.puppycrawl.tools.checkstyle.*"),
180             "34:1: " + getCheckMessage(MSG_NONGROUP_IMPORT, "com.google.common.collect.*"),
181             "35:1: " + getCheckMessage(MSG_LINE_SEPARATOR, "org.junit.*"),
182         };
183 
184         verifyWithInlineConfigParser(
185                 getPath("InputCustomImportOrderDefault4.java"), expected);
186     }
187 
188     @Test
189     public void testOrderRuleEmpty() throws Exception {
190         final String[] expected = {
191             "17:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.List"),
192         };
193 
194         verifyWithInlineConfigParser(
195                 getPath("InputCustomImportOrderEmptyRule.java"), expected);
196     }
197 
198     @Test
199     public void testOrderRuleWithOneGroup() throws Exception {
200         final String[] expected = {
201             "16:1: " + getCheckMessage(MSG_LEX, "java.awt.Button.ABORT",
202                     "java.io.File.createTempFile"),
203             "19:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.List"),
204             "19:1: " + getCheckMessage(MSG_LEX, "java.util.List", "javax.swing.WindowConstants.*"),
205             "20:1: " + getCheckMessage(MSG_LEX, "java.util.StringTokenizer",
206                     "javax.swing.WindowConstants.*"),
207             "21:1: " + getCheckMessage(MSG_LEX, "java.util.*", "javax.swing.WindowConstants.*"),
208             "22:1: " + getCheckMessage(MSG_LEX, "java.util.concurrent.AbstractExecutorService",
209                     "javax.swing.WindowConstants.*"),
210             "23:1: " + getCheckMessage(MSG_LEX, "java.util.concurrent.*",
211                     "javax.swing.WindowConstants.*"),
212             "26:1: " + getCheckMessage(MSG_LEX, "com.google.errorprone.annotations.*",
213                     "com.google.errorprone.annotations.concurrent.*"),
214             "28:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "com.google.common.base.*"),
215             "28:1: " + getCheckMessage(MSG_LEX, "com.google.common.base.*",
216                     "com.google.errorprone.annotations.concurrent.*"),
217         };
218 
219         verifyWithInlineConfigParser(
220                 getPath("InputCustomImportOrderDefault2.java"), expected);
221     }
222 
223     @Test
224     public void testStaticSamePackage() throws Exception {
225         final String[] expected = {
226             "17:1: " + getCheckMessage(MSG_LEX, "java.util.*", "java.util.StringTokenizer"),
227             "18:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME, "java.util.concurrent.*"),
228             "19:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STATIC, "java.awt.Button.ABORT"),
229             "20:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STATIC,
230                     "javax.swing.WindowConstants.*"),
231             "21:1: " + getCheckMessage(MSG_LEX, "com.puppycrawl.tools.*",
232                     "java.util.StringTokenizer"),
233             "22:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME,
234                     "java.util.concurrent.AbstractExecutorService"),
235             "23:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STATIC,
236                     "java.io.File.createTempFile"),
237             "24:1: " + getCheckMessage(MSG_LEX, "com.*", "java.util.StringTokenizer"),
238         };
239 
240         verifyWithInlineConfigParser(
241                 getNonCompilablePath("InputCustomImportOrderSamePackage.java"),
242             expected);
243     }
244 
245     @Test
246     public void testWithoutLineSeparator() throws Exception {
247         final String[] expected = {
248             "17:1: " + getCheckMessage(MSG_LEX, "java.util.*", "java.util.StringTokenizer"),
249             "18:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME, "java.util.concurrent.*"),
250             "19:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STATIC, "java.awt.Button.ABORT"),
251             "20:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STATIC,
252                     "javax.swing.WindowConstants.*"),
253             "21:1: " + getCheckMessage(MSG_LEX, "com.puppycrawl.tools.*",
254                     "java.util.StringTokenizer"),
255             "22:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME,
256                     "java.util.concurrent.AbstractExecutorService"),
257             "23:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STATIC,
258                     "java.io.File.createTempFile"),
259             "24:1: " + getCheckMessage(MSG_LEX, "com.*", "java.util.StringTokenizer"),
260         };
261 
262         verifyWithInlineConfigParser(
263                 getNonCompilablePath("InputCustomImportOrderSamePackage2.java"),
264             expected);
265     }
266 
267     @Test
268     public void testWithoutLineSeparator2() throws Exception {
269         final String[] expected = {
270             "16:1: " + getCheckMessage(MSG_LEX, "java.io.File.createTempFile",
271                 "javax.swing.WindowConstants.*"),
272             "20:1: " + getCheckMessage(MSG_LEX, "java.util.concurrent.locks.*",
273                 "java.util.concurrent.locks.AbstractOwnableSynchronizer.*"),
274         };
275 
276         verifyWithInlineConfigParser(
277                 getPath("InputCustomImportOrder_NoSeparator.java"), expected);
278     }
279 
280     @Test
281     public void testNoValid() throws Exception {
282         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
283 
284         verifyWithInlineConfigParser(
285                 getPath("InputCustomImportOrderNoValid.java"), expected);
286     }
287 
288     @Test
289     public void testPossibleIndexOutOfBoundsException() throws Exception {
290         final String[] expected = {
291             "17:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, THIRD, "org.w3c.dom.Node"),
292         };
293 
294         verifyWithInlineConfigParser(
295                 getPath("InputCustomImportOrderPossibleIndexOutOfBoundsException.java"), expected);
296     }
297 
298     @Test
299     public void testDefaultPackage2() throws Exception {
300 
301         final String[] expected = {
302             "19:1: " + getCheckMessage(MSG_LEX, "java.awt.Button.ABORT",
303                     "java.io.File.createTempFile"),
304             "22:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.awt.Button"),
305             "23:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.awt.Frame"),
306             "24:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.awt.Dialog"),
307             "25:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.awt.event.ActionEvent"),
308             "26:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "javax.swing.JComponent"),
309             "27:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "javax.swing.JTable"),
310             "28:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.io.File"),
311             "29:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.io.IOException"),
312             "30:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.io.InputStream"),
313             "31:1: " + getCheckMessage(MSG_ORDER, STD, THIRD, "java.io.Reader"),
314             "35:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "com.google.common.*"),
315             "35:1: " + getCheckMessage(MSG_LEX, "com.google.common.*", "com.puppycrawl.tools.*"),
316         };
317 
318         verifyWithInlineConfigParser(
319                 getNonCompilablePath("InputCustomImportOrderDefaultPackage.java"),
320             expected);
321     }
322 
323     @Test
324     public void testWithoutThirdPartyPackage() throws Exception {
325         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
326 
327         verifyWithInlineConfigParser(
328                 getNonCompilablePath("InputCustomImportOrderThirdPartyPackage.java"), expected);
329     }
330 
331     @Test
332     public void testThirdPartyAndSpecialImports() throws Exception {
333         final String[] expected = {
334             "23:1: " + getCheckMessage(MSG_ORDER, THIRD, SPECIAL,
335                 "com.google.common.collect.HashMultimap"),
336         };
337 
338         verifyWithInlineConfigParser(
339                 getNonCompilablePath("InputCustomImportOrderThirdPartyAndSpecial.java"), expected);
340     }
341 
342     @Test
343     public void testCompareImports() throws Exception {
344         final String[] expected = {
345             "16:1: " + getCheckMessage(MSG_LEX, "java.util.Map",
346                 "java.util.Map.Entry"),
347         };
348 
349         verifyWithInlineConfigParser(
350                 getPath("InputCustomImportOrderCompareImports.java"), expected);
351     }
352 
353     @Test
354     public void testFindBetterPatternMatch() throws Exception {
355         final String[] expected = {
356             "20:1: " + getCheckMessage(MSG_ORDER, THIRD, SPECIAL,
357                 "com.google.common.annotations.Beta"),
358         };
359 
360         verifyWithInlineConfigParser(
361                 getPath("InputCustomImportOrderFindBetterPatternMatch.java"), expected);
362     }
363 
364     @Test
365     public void testBeginTreeClear() throws Exception {
366         final DefaultConfiguration checkConfig =
367             createModuleConfig(CustomImportOrderCheck.class);
368         checkConfig.addProperty("specialImportsRegExp", "com");
369         checkConfig.addProperty("separateLineBetweenGroups", "false");
370         checkConfig.addProperty("customImportOrderRules",
371             "STANDARD_JAVA_PACKAGE###SPECIAL_IMPORTS");
372         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
373         final Checker checker = createChecker(checkConfig);
374         final String fileName1 = getPath("InputCustomImportOrderImportsContainingJava.java");
375         final String fileName2 = getPath("InputCustomImportOrderNoValid.java");
376         final File[] files = {
377             new File(fileName1),
378             new File(fileName2),
379         };
380         verify(checker, files, fileName1, expected);
381     }
382 
383     @Test
384     public void testImportsContainingJava() throws Exception {
385         final String[] expected = {
386             "17:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
387                     "com.google.errorprone.annotations.*"),
388         };
389 
390         verifyWithInlineConfigParser(
391                 getPath("InputCustomImportOrderImportsContainingJava.java"), expected);
392     }
393 
394     @Test
395     public void testGetAcceptableTokens() {
396         final CustomImportOrderCheck testCheckObject =
397                 new CustomImportOrderCheck();
398         final int[] actual = testCheckObject.getAcceptableTokens();
399         final int[] expected = {
400             TokenTypes.IMPORT,
401             TokenTypes.STATIC_IMPORT,
402             TokenTypes.PACKAGE_DEF,
403         };
404 
405         assertWithMessage("Default acceptable tokens are invalid")
406             .that(actual)
407             .isEqualTo(expected);
408     }
409 
410     @Test
411     // UT uses Reflection to avoid removing null-validation from static method,
412     // which is a candidate for utility method in the future
413     public void testGetFullImportIdent() throws Exception {
414         final Class<?> clazz = CustomImportOrderCheck.class;
415         final Object t = TestUtil.instantiate(clazz);
416         final Object actual = TestUtil.invokeMethod(t, "getFullImportIdent",
417                 Object.class, new Object[] {null});
418 
419         final String expected = "";
420         assertWithMessage("Invalid getFullImportIdent result")
421             .that(actual)
422             .isEqualTo(expected);
423     }
424 
425     @Test
426     public void testSamePackageDepth2() throws Exception {
427         final String[] expected = {
428             "20:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME, "java.util.*"),
429             "21:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME, "java.util.List"),
430             "22:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME, "java.util.StringTokenizer"),
431             "23:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME, "java.util.concurrent.*"),
432             "24:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME,
433                     "java.util.concurrent.AbstractExecutorService"),
434             "25:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME,
435                     "java.util.concurrent.locks.LockSupport"),
436             "26:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME, "java.util.regex.Pattern"),
437             "27:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME, "java.util.regex.Matcher"),
438         };
439 
440         verifyWithInlineConfigParser(
441                 getNonCompilablePath("InputCustomImportOrderSamePackageDepth25.java"),
442             expected);
443     }
444 
445     @Test
446     public void testSamePackageDepth3() throws Exception {
447         final String[] expected = {
448             "23:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME, "java.util.concurrent.*"),
449             "24:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME,
450                 "java.util.concurrent.AbstractExecutorService"),
451             "25:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME,
452                 "java.util.concurrent.locks.LockSupport"),
453             };
454 
455         verifyWithInlineConfigParser(
456                 getNonCompilablePath("InputCustomImportOrderSamePackageDepth252.java"),
457             expected);
458     }
459 
460     @Test
461     public void testSamePackageDepth4() throws Exception {
462         final String[] expected = {
463             "25:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SAME,
464                 "java.util.concurrent.locks.LockSupport"),
465             };
466 
467         verifyWithInlineConfigParser(
468                 getNonCompilablePath("InputCustomImportOrderSamePackageDepth253.java"),
469             expected);
470     }
471 
472     @Test
473     public void testSamePackageDepthLongerThenActualPackage() throws Exception {
474         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
475 
476         verifyWithInlineConfigParser(
477                 getNonCompilablePath("InputCustomImportOrderSamePackageDepth254.java"),
478                 expected);
479     }
480 
481     @Test
482     public void testSamePackageDepthNegative() throws Exception {
483 
484         try {
485             final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
486 
487             verifyWithInlineConfigParser(
488                     getPath("InputCustomImportOrderDefault5.java"), expected);
489             assertWithMessage("exception expected").fail();
490         }
491         catch (CheckstyleException exc) {
492             assertWithMessage("Invalid exception message")
493                 .that(exc)
494                 .hasMessageThat()
495                 .isEqualTo("cannot initialize module com.puppycrawl.tools.checkstyle.TreeWalker - "
496                         + "cannot initialize module com.puppycrawl.tools.checkstyle.checks"
497                         + ".imports.CustomImportOrderCheck - "
498                         + "Cannot set property 'customImportOrderRules' to "
499                         + "'SAME_PACKAGE(-1)'");
500             assertWithMessage("Invalid exception message")
501                 .that(exc.getCause().getCause().getCause().getCause().getMessage())
502                 .isEqualTo("SAME_PACKAGE rule parameter should be positive integer: "
503                         + "SAME_PACKAGE(-1)");
504         }
505     }
506 
507     @Test
508     public void testSamePackageDepthZero() throws Exception {
509         try {
510             final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
511 
512             verifyWithInlineConfigParser(
513                     getPath("InputCustomImportOrderDefault6.java"), expected);
514             assertWithMessage("exception expected").fail();
515         }
516         catch (CheckstyleException exc) {
517             assertWithMessage("Invalid exception message")
518                 .that(exc.getMessage())
519                 .isEqualTo("cannot initialize module com.puppycrawl.tools.checkstyle.TreeWalker - "
520                         + "cannot initialize module com.puppycrawl.tools.checkstyle.checks"
521                         + ".imports.CustomImportOrderCheck - "
522                         + "Cannot set property 'customImportOrderRules' to "
523                         + "'SAME_PACKAGE(0)'");
524             assertWithMessage("Invalid exception message")
525                 .that(exc.getCause().getCause().getCause().getCause().getMessage())
526                 .isEqualTo("SAME_PACKAGE rule parameter should be positive integer: "
527                         + "SAME_PACKAGE(0)");
528         }
529     }
530 
531     @Test
532     public void testUnsupportedRule() throws Exception {
533         try {
534             final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
535 
536             verifyWithInlineConfigParser(
537                     getPath("InputCustomImportOrderDefault7.java"), expected);
538             assertWithMessage("exception expected").fail();
539         }
540         catch (CheckstyleException exc) {
541             assertWithMessage("Invalid exception message")
542                 .that(exc.getMessage())
543                 .isEqualTo("cannot initialize module com.puppycrawl.tools.checkstyle.TreeWalker - "
544                         + "cannot initialize module com.puppycrawl.tools.checkstyle.checks"
545                         + ".imports.CustomImportOrderCheck - "
546                         + "Cannot set property 'customImportOrderRules' to "
547                         + "'SAME_PACKAGE(3)###UNSUPPORTED_RULE'");
548             assertWithMessage("Invalid exception message")
549                 .that(exc.getCause().getCause().getCause().getCause().getMessage())
550                 .isEqualTo("Unexpected rule: UNSUPPORTED_RULE");
551         }
552     }
553 
554     @Test
555     public void testSamePackageDepthNotInt() throws Exception {
556         try {
557             final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
558 
559             verifyWithInlineConfigParser(
560                     getPath("InputCustomImportOrderDefault8.java"), expected);
561             assertWithMessage("exception expected").fail();
562         }
563         catch (CheckstyleException exc) {
564             assertWithMessage("Invalid exception message")
565                 .that(exc.getMessage())
566                 .isEqualTo("cannot initialize module com.puppycrawl.tools.checkstyle.TreeWalker - "
567                         + "cannot initialize module com.puppycrawl.tools.checkstyle.checks"
568                         + ".imports.CustomImportOrderCheck - "
569                         + "Cannot set property 'customImportOrderRules' to "
570                         + "'SAME_PACKAGE(INT_IS_REQUIRED_HERE)'");
571             assertWithMessage("Invalid exception message")
572                 .that(exc.getCause().getCause().getCause().getCause().getMessage())
573                 .isEqualTo("For input string: \"INT_IS_REQUIRED_HERE\"");
574         }
575     }
576 
577     @Test
578     public void testNoImports() throws Exception {
579         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
580 
581         verifyWithInlineConfigParser(
582                 getPath("InputCustomImportOrder_NoImports.java"), expected);
583     }
584 
585     @Test
586     public void testDefaultConfiguration() throws Exception {
587         final String[] expected = {
588             "20:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.awt.Button"),
589             "32:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.io.*"),
590             "34:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "com.google.common.collect.*"),
591         };
592         verifyWithInlineConfigParser(
593                 getPath("InputCustomImportOrderDefault9.java"), expected);
594     }
595 
596     @Test
597     public void testRulesWithOverlappingPatterns() throws Exception {
598         final String[] expected = {
599             "23:1: " + getCheckMessage(MSG_ORDER, THIRD, STD,
600                 "com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocNodeImpl"),
601             "27:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
602                 "com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck"),
603             "33:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
604                 "com.puppycrawl.tools.checkstyle.checks.javadoc.InvalidJavadocTag"),
605             "35:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STD,
606                 "com.puppycrawl.tools.checkstyle.checks.javadoc.WriteTagCheck"),
607             "39:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SPECIAL,
608                 "com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTag"),
609             "40:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STD,
610                 "com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck"),
611             "41:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STD,
612                 "com.puppycrawl.tools.checkstyle.checks.javadoc.NonEmptyAtclauseDescriptionCheck"),
613             };
614 
615         verifyWithInlineConfigParser(
616                 getPath("InputCustomImportOrder_OverlappingPatterns.java"), expected);
617     }
618 
619     @Test
620     public void testMultiplePatternMatchesSecondPatternIsLonger() throws Exception {
621         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
622         verifyWithInlineConfigParser(
623                 getPath("InputCustomImportOrder_MultiplePatternMatches.java"),
624             expected);
625     }
626 
627     @Test
628     public void testMultiplePatternMatchesFirstPatternHasLaterPosition() throws Exception {
629         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
630         verifyWithInlineConfigParser(
631                 getPath("InputCustomImportOrder_MultiplePatternMatches2.java"),
632             expected);
633     }
634 
635     @Test
636     public void testMultiplePatternMatchesFirstPatternHasEarlierPosition() throws Exception {
637         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
638         verifyWithInlineConfigParser(
639                 getPath("InputCustomImportOrder_MultiplePatternMatches3.java"),
640             expected);
641     }
642 
643     @Test
644     public void testMultiplePatternMultipleImportFirstPatternHasLaterPosition() throws Exception {
645         final String[] expected = {
646             "16:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STD, "org.junit.Test"),
647         };
648         verifyWithInlineConfigParser(
649                 getPath("InputCustomImportOrder_MultiplePatternMultipleImport.java"),
650             expected);
651     }
652 
653     @Test
654     public void testNoPackage() throws Exception {
655         final String[] expected = {
656             "17:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.*"),
657             "19:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.HashMap"),
658             "23:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "javax.net.ServerSocketFactory"),
659             "26:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "javax.net.SocketFactory"),
660         };
661         verifyWithInlineConfigParser(
662                 getNonCompilablePath("InputCustomImportOrderNoPackage.java"),
663             expected);
664     }
665 
666     @Test
667     public void testNoPackage2() throws Exception {
668         final String[] expected = {
669             "18:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
670                 "com.sun.accessibility.internal.resources.*"),
671             "22:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Arrays"),
672             "30:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
673                 "org.apache.commons.beanutils.converters.ArrayConverter"),
674         };
675         verifyWithInlineConfigParser(
676                 getNonCompilablePath("InputCustomImportOrderNoPackage2.java"),
677             expected);
678     }
679 
680     @Test
681     public void testNoPackage3() throws Exception {
682         final String[] expected = {
683             "17:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
684                 "java.util.Map"),
685             "25:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
686                 "org.apache.*"),
687             "29:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
688                 "antlr.*"),
689         };
690         verifyWithInlineConfigParser(
691                 getNonCompilablePath("InputCustomImportOrderNoPackage3.java"),
692             expected);
693     }
694 
695     @Test
696     public void testInputCustomImportOrderSingleLine() throws Exception {
697         final String[] expected = {
698             "14:112: " + getCheckMessage(MSG_LINE_SEPARATOR,
699                 "java.util.Map"),
700             "15:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
701                 "com.google.common.annotations.Beta"),
702             "22:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
703                 "com.puppycrawl.tools.checkstyle.*"),
704             "26:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
705                 "picocli.*"),
706         };
707         verifyWithInlineConfigParser(
708                 getPath("InputCustomImportOrderSingleLine.java"),
709             expected);
710     }
711 
712     @Test
713     public void testInputCustomImportOrderSingleLine2() throws Exception {
714         final String[] expected = {
715             "14:118: " + getCheckMessage(MSG_LINE_SEPARATOR,
716                 "java.util.Map"),
717         };
718         verifyWithInlineConfigParser(
719                 getNonCompilablePath("InputCustomImportOrderSingleLine2.java"),
720             expected);
721     }
722 
723     @Test
724     public void testInputCustomImportOrderThirdPartyAndSpecial2() throws Exception {
725         final String[] expected = {
726             "21:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
727                 "javax.swing.WindowConstants.*"),
728             "24:1: " + getCheckMessage(MSG_LINE_SEPARATOR,
729                 "java.awt.Button"),
730             "28:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
731                 "java.awt.Dialog"),
732             "34:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
733                 "com.google.common.*"),
734             "40:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
735                 "org.apache.commons.collections.*"),
736             "45:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
737                 "com.puppycrawl.tools.checkstyle.checks.imports.AbstractImportRule"),
738             "51:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
739                 "antlr.Token"),
740             "53:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
741                 "antlr.collections.AST"),
742         };
743         verifyWithInlineConfigParser(
744                 getNonCompilablePath("InputCustomImportOrderThirdPartyAndSpecial2.java"), expected);
745     }
746 
747     @Test
748     public void testInputCustomImportOrderMultipleViolationsSameLine() throws Exception {
749         final String[] expected = {
750             "17:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STATIC,
751                 "java.util.Collections.*"),
752             "18:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STATIC,
753                 "java.lang.String.CASE_INSENSITIVE_ORDER"),
754             "21:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
755                 "java.net.Socket"),
756             "21:1: " + getCheckMessage(MSG_LEX, "java.net.Socket",
757                 "java.util.*"),
758         };
759         verifyWithInlineConfigParser(
760                 getNonCompilablePath("InputCustomImportOrderViolationsSameLine.java"),
761             expected);
762     }
763 
764     @Test
765     public void testInputCustomImportOrderSpanMultipleLines() throws Exception {
766         final String[] expected = {
767             "30:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.BitSet"),
768             "45:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.HashSet"),
769             "49:1: " + getCheckMessage(MSG_LINE_SEPARATOR, "org.apache.tools.ant.*"),
770             "54:1: " + getCheckMessage(MSG_LINE_SEPARATOR, "com.puppycrawl.tools.checkstyle.*"),
771             "58:1: " + getCheckMessage(MSG_LINE_SEPARATOR, "picocli.*"),
772             "61:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "picocli.CommandLine"),
773         };
774         verifyWithInlineConfigParser(
775                 getPath("InputCustomImportOrderSpanMultipleLines.java"), expected);
776     }
777 
778     @Test
779     public void testInputCustomImportOrderEclipseDefaultPositive() throws Exception {
780         final String[] expected = {
781             "22:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STD, "java.awt.Button"),
782             "23:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STD, "java.awt.Dialog"),
783             "24:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, STD, "java.io.InputStream"),
784             "26:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SPECIAL, "javax.swing.JComponent"),
785             "27:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, SPECIAL, "javax.swing.JTable"),
786             "29:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, THIRD, "org.junit.Test"),
787             "30:1: " + getCheckMessage(MSG_NONGROUP_EXPECTED, THIRD,
788                     "org.mockito.Mock"),
789             "34:1: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "sun.tools.java.ArrayType"),
790         };
791         verifyWithInlineConfigParser(
792                 getNonCompilablePath("InputCustomImportOrderEclipseDefaultPositive.java"),
793                 expected);
794     }
795 
796     @Test
797     public void testInputCustomImportOrderSpecialImportsRegExp() throws Exception {
798         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
799         verifyWithInlineConfigParser(
800                 getPath("InputCustomImportOrderSpecialImportsRegExp.java"),
801                 expected);
802     }
803 }