View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 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.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck.MSG_ORDERING;
23  import static com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck.MSG_SEPARATED_IN_GROUP;
24  import static com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck.MSG_SEPARATION;
25  import static org.junit.Assert.assertEquals;
26  import static org.junit.Assert.assertTrue;
27  import static org.junit.Assert.fail;
28  
29  import org.junit.Test;
30  import org.junit.runner.RunWith;
31  import org.mockito.internal.util.reflection.Whitebox;
32  import org.powermock.api.mockito.PowerMockito;
33  import org.powermock.core.classloader.annotations.PrepareForTest;
34  import org.powermock.modules.junit4.PowerMockRunner;
35  
36  import antlr.CommonHiddenStreamToken;
37  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
38  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
39  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
40  import com.puppycrawl.tools.checkstyle.api.DetailAST;
41  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
42  import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
43  
44  @RunWith(PowerMockRunner.class)
45  @PrepareForTest(ImportOrderOption.class)
46  public class ImportOrderCheckTest extends AbstractModuleTestSupport {
47      @Override
48      protected String getPackageLocation() {
49          return "com/puppycrawl/tools/checkstyle/checks/imports/importorder";
50      }
51  
52      /* Additional test for jacoco, since valueOf()
53       * is generated by javac and jacoco reports that
54       * valueOf() is uncovered.
55       */
56      @Test
57      public void testImportOrderOptionValueOf() {
58          final ImportOrderOption option = ImportOrderOption.valueOf("TOP");
59          assertEquals("Invalid valueOf result", ImportOrderOption.TOP, option);
60      }
61  
62      @Test
63      public void testDefault() throws Exception {
64          final DefaultConfiguration checkConfig =
65              createModuleConfig(ImportOrderCheck.class);
66          final String[] expected = {
67              "5: " + getCheckMessage(MSG_ORDERING, "java.awt.Dialog"),
68              "9: " + getCheckMessage(MSG_ORDERING, "javax.swing.JComponent"),
69              "11: " + getCheckMessage(MSG_ORDERING, "java.io.File"),
70              "13: " + getCheckMessage(MSG_ORDERING, "java.io.IOException"),
71              "18: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
72                      "sun.tools.util.ModifierFilter.ALL_ACCESS"),
73          };
74  
75          verify(checkConfig, getPath("InputImportOrder.java"), expected);
76      }
77  
78      @Test
79      public void testGroups() throws Exception {
80          final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
81          checkConfig.addAttribute("groups", "java.awt");
82          checkConfig.addAttribute("groups", "javax.swing");
83          checkConfig.addAttribute("groups", "java.io");
84          final String[] expected = {
85              "5: " + getCheckMessage(MSG_ORDERING, "java.awt.Dialog"),
86              "13: " + getCheckMessage(MSG_ORDERING, "java.io.IOException"),
87              "16: " + getCheckMessage(MSG_ORDERING, "javax.swing.WindowConstants.*"),
88              "18: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
89                      "sun.tools.util.ModifierFilter.ALL_ACCESS"),
90          };
91  
92          verify(checkConfig, getPath("InputImportOrder.java"), expected);
93      }
94  
95      @Test
96      public void testGroupsRegexp() throws Exception {
97          final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
98          checkConfig.addAttribute("groups", "java, /^javax?\\.(awt|swing)\\./");
99          checkConfig.addAttribute("ordered", "false");
100         final String[] expected = {
101             "11: " + getCheckMessage(MSG_ORDERING, "java.io.File"),
102             "18: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
103                     "sun.tools.util.ModifierFilter.ALL_ACCESS"),
104         };
105 
106         verify(checkConfig, getPath("InputImportOrder.java"), expected);
107     }
108 
109     @Test
110     public void testSeparated() throws Exception {
111         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
112         checkConfig.addAttribute("groups", "java.awt, javax.swing, java.io, java.util");
113         checkConfig.addAttribute("separated", "true");
114         checkConfig.addAttribute("ordered", "false");
115         final String[] expected = {
116             "9: " + getCheckMessage(MSG_SEPARATION, "javax.swing.JComponent"),
117             "11: " + getCheckMessage(MSG_SEPARATION, "java.io.File"),
118             "16: " + getCheckMessage(MSG_ORDERING, "javax.swing.WindowConstants.*"),
119         };
120 
121         verify(checkConfig, getPath("InputImportOrder.java"), expected);
122     }
123 
124     @Test
125     public void testStaticImportSeparated() throws Exception {
126         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
127         checkConfig.addAttribute("groups", "java, org");
128         checkConfig.addAttribute("separated", "true");
129         checkConfig.addAttribute("ordered", "true");
130         checkConfig.addAttribute("option", "top");
131         final String[] expected = {
132             "5: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.lang.Math.cos"),
133             "7: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "org.junit.Assert.assertEquals"),
134         };
135 
136         verify(checkConfig, getPath("InputImportOrderStaticGroupSeparated.java"), expected);
137     }
138 
139     @Test
140     public void testNoGapBetweenStaticImports() throws Exception {
141         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
142         checkConfig.addAttribute("groups", "java, javax, org");
143         checkConfig.addAttribute("separated", "true");
144         checkConfig.addAttribute("ordered", "true");
145         checkConfig.addAttribute("option", "bottom");
146         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
147 
148         verify(checkConfig, getPath("InputImportOrderNoGapBetweenStaticImports.java"), expected);
149     }
150 
151     @Test
152     public void testSortStaticImportsAlphabeticallyFalse() throws Exception {
153         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
154         checkConfig.addAttribute("groups", " java, javax, org");
155         checkConfig.addAttribute("separated", "true");
156         checkConfig.addAttribute("ordered", "true");
157         checkConfig.addAttribute("option", "top");
158         checkConfig.addAttribute("sortStaticImportsAlphabetically", "false");
159         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
160 
161         verify(checkConfig, getPath("InputImportOrderSortStaticImportsAlphabetically.java"),
162             expected);
163     }
164 
165     @Test
166     public void testSortStaticImportsAlphabeticallyTrue() throws Exception {
167         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
168         checkConfig.addAttribute("groups", "java, javax, org");
169         checkConfig.addAttribute("separated", "true");
170         checkConfig.addAttribute("ordered", "true");
171         checkConfig.addAttribute("option", "top");
172         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
173         final String[] expected = {
174             "4: " + getCheckMessage(MSG_ORDERING,
175                 "javax.xml.transform.TransformerFactory.newInstance"),
176             "5: " + getCheckMessage(MSG_ORDERING, "java.lang.Math.cos"),
177             "6: " + getCheckMessage(MSG_ORDERING, "java.lang.Math.abs"),
178         };
179 
180         verify(checkConfig, getPath("InputImportOrderSortStaticImportsAlphabetically.java"),
181             expected);
182     }
183 
184     @Test
185     public void testCaseInsensitive() throws Exception {
186         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
187         checkConfig.addAttribute("caseSensitive", "false");
188         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
189 
190         verify(checkConfig, getPath("InputImportOrderCaseInsensitive.java"), expected);
191     }
192 
193     @Test
194     public void testContainerCaseInsensitive() throws Exception {
195         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
196         checkConfig.addAttribute("option", "top");
197         checkConfig.addAttribute("caseSensitive", "false");
198         checkConfig.addAttribute("useContainerOrderingForStatic", "true");
199         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
200 
201         verify(checkConfig, getNonCompilablePath("InputImportOrderEclipseStaticCaseSensitive.java"),
202             expected);
203     }
204 
205     @Test
206     public void testInvalidOption() throws Exception {
207         final DefaultConfiguration checkConfig =
208             createModuleConfig(ImportOrderCheck.class);
209         checkConfig.addAttribute("option", "invalid_option");
210 
211         try {
212             final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
213 
214             verify(checkConfig, getPath("InputImportOrder_Top.java"), expected);
215             fail("exception expected");
216         }
217         catch (CheckstyleException ex) {
218             final String messageStart = "cannot initialize module "
219                 + "com.puppycrawl.tools.checkstyle.TreeWalker - Cannot set property 'option' to "
220                 + "'invalid_option' in module";
221 
222             assertTrue("Invalid exception message, should start with: " + messageStart,
223                 ex.getMessage().startsWith(messageStart));
224         }
225     }
226 
227     @Test
228     public void testTop() throws Exception {
229         final DefaultConfiguration checkConfig =
230             createModuleConfig(ImportOrderCheck.class);
231         checkConfig.addAttribute("option", "top");
232         final String[] expected = {
233             "7: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.awt.Button"),
234             "12: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.io.IOException"),
235             "15: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "javax.swing.JComponent"),
236             "18: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.io.File.*"),
237             "18: " + getCheckMessage(MSG_ORDERING, "java.io.File.*"),
238         };
239 
240         verify(checkConfig, getPath("InputImportOrder_Top.java"), expected);
241     }
242 
243     @Test
244     public void testAbove() throws Exception {
245         final DefaultConfiguration checkConfig =
246             createModuleConfig(ImportOrderCheck.class);
247         checkConfig.addAttribute("option", "above");
248         final String[] expected = {
249             "5: " + getCheckMessage(MSG_ORDERING, "java.awt.Button.ABORT"),
250             "8: " + getCheckMessage(MSG_ORDERING, "java.awt.Dialog"),
251             "13: " + getCheckMessage(MSG_ORDERING, "java.io.File"),
252             "13: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.io.File"),
253             "14: " + getCheckMessage(MSG_ORDERING, "java.io.File.createTempFile"),
254         };
255 
256         verify(checkConfig, getPath("InputImportOrder_Above.java"), expected);
257     }
258 
259     @Test
260     public void testInFlow() throws Exception {
261         final DefaultConfiguration checkConfig =
262             createModuleConfig(ImportOrderCheck.class);
263         checkConfig.addAttribute("option", "inflow");
264         final String[] expected = {
265             "6: " + getCheckMessage(MSG_ORDERING, "java.awt.Dialog"),
266             "9: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "javax.swing.JComponent"),
267             "11: " + getCheckMessage(MSG_ORDERING,
268                      "javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE"),
269             "12: " + getCheckMessage(MSG_ORDERING, "javax.swing.WindowConstants.*"),
270             "13: " + getCheckMessage(MSG_ORDERING, "javax.swing.JTable"),
271             "15: " + getCheckMessage(MSG_ORDERING, "java.io.File.createTempFile"),
272             "15: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.io.File.createTempFile"),
273             "16: " + getCheckMessage(MSG_ORDERING, "java.io.File"),
274         };
275 
276         verify(checkConfig, getPath("InputImportOrder_InFlow.java"), expected);
277     }
278 
279     @Test
280     public void testUnder() throws Exception {
281         // is default (testDefault)
282         final DefaultConfiguration checkConfig =
283             createModuleConfig(ImportOrderCheck.class);
284         checkConfig.addAttribute("option", "under");
285         final String[] expected = {
286             "5: " + getCheckMessage(MSG_ORDERING, "java.awt.Dialog"),
287             "11: " + getCheckMessage(MSG_ORDERING, "java.awt.Button.ABORT"),
288             "13: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.io.File.createTempFile"),
289             "14: " + getCheckMessage(MSG_ORDERING, "java.io.File"),
290         };
291 
292         verify(checkConfig, getPath("InputImportOrder_Under.java"), expected);
293     }
294 
295     @Test
296     public void testBottom() throws Exception {
297         final DefaultConfiguration checkConfig =
298             createModuleConfig(ImportOrderCheck.class);
299         checkConfig.addAttribute("option", "bottom");
300         final String[] expected = {
301             "8: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.io.IOException"),
302             "11: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "javax.swing.JComponent"),
303             "14: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.io.File.*"),
304             "15: " + getCheckMessage(MSG_ORDERING, "java.io.File"),
305             "17: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.io.File.createTempFile"),
306             "21: " + getCheckMessage(MSG_ORDERING, "java.io.Reader"),
307             "21: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.io.Reader"),
308         };
309 
310         verify(checkConfig, getPath("InputImportOrder_Bottom.java"), expected);
311     }
312 
313     @Test
314     public void testGetGroupNumber() throws Exception {
315         final DefaultConfiguration checkConfig =
316             createModuleConfig(ImportOrderCheck.class);
317         checkConfig.addAttribute("groups", "/javax/, sun, /^java/, org, /java/");
318         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
319 
320         verify(checkConfig,
321             getNonCompilablePath("InputImportOrderGetGroupNumber.java"), expected);
322     }
323 
324     @Test
325     public void testHonorsTokenProperty() throws Exception {
326         final DefaultConfiguration checkConfig =
327             createModuleConfig(ImportOrderCheck.class);
328         checkConfig.addAttribute("tokens", "IMPORT");
329         final String[] expected = {
330             "6: " + getCheckMessage(MSG_ORDERING, "java.awt.Button"),
331         };
332 
333         verify(checkConfig, getPath("InputImportOrder_HonorsTokensProperty.java"), expected);
334     }
335 
336     @Test
337     public void testWildcard() throws Exception {
338         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
339         checkConfig.addAttribute("groups", "com,*,java");
340         final String[] expected = {
341             "9: " + getCheckMessage(MSG_ORDERING, "javax.crypto.Cipher"),
342         };
343 
344         verify(checkConfig, getPath("InputImportOrder_Wildcard.java"), expected);
345     }
346 
347     @Test
348     public void testWildcardUnspecified() throws Exception {
349         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
350 
351         checkConfig.addAttribute("groups", "java,javax,org");
352         final String[] expected = {
353             "11: " + getCheckMessage(MSG_SEPARATED_IN_GROUP,
354                 "com.puppycrawl.tools.checkstyle.checks.imports.importorder.InputImportOrderBug"),
355         };
356 
357         verify(checkConfig, getPath("InputImportOrder_WildcardUnspecified.java"), expected);
358     }
359 
360     @Test
361     public void testNoFailureForRedundantImports() throws Exception {
362         final DefaultConfiguration checkConfig =
363             createModuleConfig(ImportOrderCheck.class);
364         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
365         verify(checkConfig, getPath("InputImportOrder_NoFailureForRedundantImports.java"),
366             expected);
367     }
368 
369     @Test
370     public void testStaticGroupsAlphabeticalOrder() throws Exception {
371         final DefaultConfiguration checkConfig =
372             createModuleConfig(ImportOrderCheck.class);
373         checkConfig.addAttribute("option", "top");
374         checkConfig.addAttribute("groups", "org, java");
375         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
376         final String[] expected = {
377             "6: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "org.*"),
378             "8: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Set"),
379         };
380 
381         verify(checkConfig, getPath("InputImportOrderStaticGroupOrder.java"), expected);
382     }
383 
384     @Test
385     public void testStaticGroupsOrder() throws Exception {
386         final DefaultConfiguration checkConfig =
387             createModuleConfig(ImportOrderCheck.class);
388         checkConfig.addAttribute("option", "top");
389         checkConfig.addAttribute("groups", "org, java");
390         final String[] expected = {
391             "6: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "org.*"),
392             "8: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Set"),
393         };
394         verify(checkConfig, getPath("InputImportOrderStaticGroupOrder.java"), expected);
395     }
396 
397     @Test
398     public void testStaticGroupsAlphabeticalOrderBottom() throws Exception {
399         final DefaultConfiguration checkConfig =
400             createModuleConfig(ImportOrderCheck.class);
401         checkConfig.addAttribute("option", "bottom");
402         checkConfig.addAttribute("groups", "org, java");
403         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
404         final String[] expected = {
405             "5: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Set"),
406             "7: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.lang.Math.PI"),
407         };
408         verify(checkConfig, getPath("InputImportOrderStaticGroupOrderBottom.java"), expected);
409     }
410 
411     @Test
412     public void testStaticGroupsAlphabeticalOrderBottomNegative() throws Exception {
413         final DefaultConfiguration checkConfig =
414             createModuleConfig(ImportOrderCheck.class);
415         checkConfig.addAttribute("option", "bottom");
416         checkConfig.addAttribute("groups", "org, java");
417         checkConfig.addAttribute("separated", "true");
418         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
419         final String[] expected = {
420             "8: " + getCheckMessage(MSG_ORDERING, "java.util.Set"),
421         };
422         verify(checkConfig, getPath("InputImportOrderStaticGroupOrderBottom_Negative.java"),
423             expected);
424     }
425 
426     /** Tests that a non-static import after a static import correctly gives an
427      * error if order=bottom. */
428 
429     @Test
430     public void testStaticGroupsAlphabeticalOrderTopNegative() throws Exception {
431         final DefaultConfiguration checkConfig =
432             createModuleConfig(ImportOrderCheck.class);
433         checkConfig.addAttribute("option", "top");
434         checkConfig.addAttribute("groups", "org, java");
435         checkConfig.addAttribute("separated", "true");
436         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
437         final String[] expected = {
438             "5: " + getCheckMessage(MSG_ORDERING, "java.lang.Math.PI"),
439         };
440         verify(checkConfig, getPath("InputImportOrderStaticGroupOrderBottom_Negative.java"),
441             expected);
442     }
443 
444     /** Tests that a non-static import before a static import correctly gives an
445      * error if order=top. */
446 
447     @Test
448     public void testStaticGroupsAlphabeticalOrderBottomNegative2() throws Exception {
449         final DefaultConfiguration checkConfig =
450             createModuleConfig(ImportOrderCheck.class);
451         checkConfig.addAttribute("option", "bottom");
452         checkConfig.addAttribute("groups", "org, java");
453         checkConfig.addAttribute("separated", "true");
454         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
455         final String[] expected = {
456             "8: " + getCheckMessage(MSG_ORDERING, "java.util.Set"),
457         };
458         verify(checkConfig, getPath("InputImportOrderStaticGroupOrderBottom_Negative2.java"),
459             expected);
460     }
461 
462     @Test
463     public void testStaticGroupsOrderBottom() throws Exception {
464         final DefaultConfiguration checkConfig =
465             createModuleConfig(ImportOrderCheck.class);
466         checkConfig.addAttribute("option", "bottom");
467         checkConfig.addAttribute("groups", "org, java");
468         final String[] expected = {
469             "5: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Set"),
470             "7: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.lang.Math.PI"),
471         };
472         verify(checkConfig, getPath("InputImportOrderStaticGroupOrderBottom.java"), expected);
473     }
474 
475     @Test
476     public void testImportReception() throws Exception {
477         final DefaultConfiguration checkConfig =
478                 createModuleConfig(ImportOrderCheck.class);
479         checkConfig.addAttribute("separated", "true");
480         checkConfig.addAttribute("groups", "java, javax");
481         final String[] expected = {
482             "6: " + getCheckMessage(MSG_ORDERING, "java.awt.event.ActionEvent"),
483         };
484         verify(checkConfig, getPath("InputImportOrderRepetition.java"), expected);
485     }
486 
487     @Test
488     public void testStaticImportReceptionTop() throws Exception {
489         final DefaultConfiguration checkConfig =
490                 createModuleConfig(ImportOrderCheck.class);
491         checkConfig.addAttribute("option", "top");
492         checkConfig.addAttribute("separated", "true");
493         checkConfig.addAttribute("groups", "java, org");
494         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
495         final String[] expected = {
496             "5: " + getCheckMessage(MSG_ORDERING, "org.antlr.v4.runtime.CommonToken.*"),
497         };
498         verify(checkConfig, getPath("InputImportOrderStaticRepetition.java"), expected);
499     }
500 
501     @Test
502     public void testStaticImportReception() throws Exception {
503         final DefaultConfiguration checkConfig =
504                 createModuleConfig(ImportOrderCheck.class);
505         checkConfig.addAttribute("separated", "true");
506         checkConfig.addAttribute("groups", "java, org");
507         final String[] expected = {
508             "4: " + getCheckMessage(MSG_SEPARATION, "org.antlr.v4.runtime.CommonToken.*"),
509             "5: " + getCheckMessage(MSG_ORDERING, "org.antlr.v4.runtime.CommonToken.*"),
510             "7: " + getCheckMessage(MSG_ORDERING, "java.util.Set"),
511         };
512         verify(checkConfig, getPath("InputImportOrderStaticRepetition.java"), expected);
513     }
514 
515     @Test
516     public void testStaticGroupsOrderAbove() throws Exception {
517         final DefaultConfiguration checkConfig =
518             createModuleConfig(ImportOrderCheck.class);
519         checkConfig.addAttribute("option", "above");
520         checkConfig.addAttribute("groups", "org, java, sun");
521         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
522         final String[] expected = {
523             "5: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Set"),
524             "7: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.lang.Math.PI"),
525             "7: " + getCheckMessage(MSG_ORDERING, "java.lang.Math.PI"),
526             "8: " + getCheckMessage(MSG_ORDERING, "org.antlr.v4.runtime.Recognizer.EOF"),
527         };
528         verify(checkConfig, getPath("InputImportOrderStaticGroupOrderBottom.java"), expected);
529     }
530 
531     @Test
532     public void testStaticOnDemandGroupsOrder() throws Exception {
533         final DefaultConfiguration checkConfig =
534             createModuleConfig(ImportOrderCheck.class);
535         checkConfig.addAttribute("option", "top");
536         checkConfig.addAttribute("groups", "org, java");
537         final String[] expected = {
538             "6: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "org.*"),
539             "8: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Set"),
540             "9: " + getCheckMessage(MSG_ORDERING, "org.junit.Test"),
541         };
542         verify(checkConfig, getPath("InputImportOrderStaticOnDemandGroupOrder.java"), expected);
543     }
544 
545     @Test
546     public void testStaticOnDemandGroupsAlphabeticalOrder() throws Exception {
547         final DefaultConfiguration checkConfig =
548             createModuleConfig(ImportOrderCheck.class);
549         checkConfig.addAttribute("option", "top");
550         checkConfig.addAttribute("groups", "org, java");
551         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
552         final String[] expected = {
553             "6: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "org.*"),
554             "8: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Set"),
555             "9: " + getCheckMessage(MSG_ORDERING, "org.junit.Test"),
556         };
557         verify(checkConfig, getPath("InputImportOrderStaticOnDemandGroupOrder.java"), expected);
558     }
559 
560     @Test
561     public void testStaticOnDemandGroupsOrderBottom() throws Exception {
562         final DefaultConfiguration checkConfig =
563             createModuleConfig(ImportOrderCheck.class);
564         checkConfig.addAttribute("option", "bottom");
565         checkConfig.addAttribute("groups", "org, java");
566         final String[] expected = {
567             "5: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Set"),
568             "7: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.lang.Math.*"),
569         };
570         verify(checkConfig, getPath("InputImportOrderStaticOnDemandGroupOrderBottom.java"),
571             expected);
572     }
573 
574     @Test
575     public void testStaticOnDemandGroupsAlphabeticalOrderBottom() throws Exception {
576         final DefaultConfiguration checkConfig =
577             createModuleConfig(ImportOrderCheck.class);
578         checkConfig.addAttribute("option", "bottom");
579         checkConfig.addAttribute("groups", "org, java");
580         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
581         final String[] expected = {
582             "5: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Set"),
583             "7: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.lang.Math.*"),
584         };
585         verify(checkConfig, getPath("InputImportOrderStaticOnDemandGroupOrderBottom.java"),
586             expected);
587     }
588 
589     @Test
590     public void testStaticOnDemandGroupsOrderAbove() throws Exception {
591         final DefaultConfiguration checkConfig =
592             createModuleConfig(ImportOrderCheck.class);
593         checkConfig.addAttribute("option", "above");
594         checkConfig.addAttribute("groups", "org, java");
595         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
596         final String[] expected = {
597             "5: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.util.Set"),
598             "7: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "java.lang.Math.*"),
599             "7: " + getCheckMessage(MSG_ORDERING, "java.lang.Math.*"),
600             "8: " + getCheckMessage(MSG_ORDERING, "org.antlr.v4.runtime.CommonToken.*"),
601         };
602         verify(checkConfig, getPath("InputImportOrderStaticOnDemandGroupOrderBottom.java"),
603             expected);
604     }
605 
606     @Test
607     public void testGroupWithSlashes() throws Exception {
608         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
609         checkConfig.addAttribute("groups", "/^javax");
610 
611         try {
612             final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
613 
614             verify(checkConfig, getPath("InputImportOrder.java"), expected);
615             fail("exception expected");
616         }
617         catch (CheckstyleException ex) {
618             final String messageStart = "cannot initialize module "
619                 + "com.puppycrawl.tools.checkstyle.TreeWalker - Cannot set property"
620                 + " 'groups' to '/^javax' in module";
621 
622             assertTrue("Invalid exception message, should start with: " + messageStart,
623                 ex.getMessage().startsWith(messageStart));
624         }
625     }
626 
627     @Test
628     public void testGroupWithDot() throws Exception {
629         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
630         checkConfig.addAttribute("groups", "java.awt.");
631         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
632 
633         verify(checkConfig, getPath("InputImportOrder_NoFailureForRedundantImports.java"),
634             expected);
635     }
636 
637     @Test
638     public void testMultiplePatternMatches() throws Exception {
639         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
640         checkConfig.addAttribute("groups", "/java/,/rga/,/myO/,/org/,/organ./");
641         final String[] expected = {
642             "5: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "org.*"),
643         };
644 
645         verify(checkConfig, getNonCompilablePath("InputImportOrder_MultiplePatternMatches.java"),
646             expected);
647     }
648 
649     // -@cs[ForbidAnnotationElementValue] Will examine turkish failure
650     @Test(expected = IllegalStateException.class)
651     public void testVisitTokenSwitchReflection() {
652         // Create mock ast
653         final DetailAST astImport = mockAST(TokenTypes.IMPORT, "import", "mockfile", 0, 0);
654         final DetailAST astIdent = mockAST(TokenTypes.IDENT, "myTestImport", "mockfile", 0, 0);
655         astImport.addChild(astIdent);
656         final DetailAST astSemi = mockAST(TokenTypes.SEMI, ";", "mockfile", 0, 0);
657         astIdent.addNextSibling(astSemi);
658 
659         // Set unsupported option
660         final ImportOrderCheck mock = new ImportOrderCheck();
661         final ImportOrderOption importOrderOptionMock = PowerMockito.mock(ImportOrderOption.class);
662         Whitebox.setInternalState(importOrderOptionMock, "name", "NEW_OPTION_FOR_UT");
663         Whitebox.setInternalState(importOrderOptionMock, "ordinal", 5);
664         Whitebox.setInternalState(mock, "option", importOrderOptionMock);
665 
666         // expecting IllegalStateException
667         mock.visitToken(astImport);
668     }
669 
670     /**
671      * Creates MOCK lexical token and returns AST node for this token.
672      * @param tokenType type of token
673      * @param tokenText text of token
674      * @param tokenFileName file name of token
675      * @param tokenRow token position in a file (row)
676      * @param tokenColumn token position in a file (column)
677      * @return AST node for the token
678      */
679     private static DetailAST mockAST(final int tokenType, final String tokenText,
680             final String tokenFileName, final int tokenRow, final int tokenColumn) {
681         final CommonHiddenStreamToken tokenImportSemi = new CommonHiddenStreamToken();
682         tokenImportSemi.setType(tokenType);
683         tokenImportSemi.setText(tokenText);
684         tokenImportSemi.setLine(tokenRow);
685         tokenImportSemi.setColumn(tokenColumn);
686         tokenImportSemi.setFilename(tokenFileName);
687         final DetailAST astSemi = new DetailAST();
688         astSemi.initialize(tokenImportSemi);
689         return astSemi;
690     }
691 
692     @Test
693     public void testEclipseDefaultPositive() throws Exception {
694         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
695         checkConfig.addAttribute("groups", "java,javax,org,com");
696         checkConfig.addAttribute("ordered", "true");
697         checkConfig.addAttribute("separated", "true");
698         checkConfig.addAttribute("option", "top");
699         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
700         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
701 
702         verify(checkConfig, getPath("InputImportOrder_EclipseDefaultPositive.java"), expected);
703     }
704 
705     @Test
706     public void testStaticImportEclipseRepetition() throws Exception {
707         final DefaultConfiguration checkConfig =
708             createModuleConfig(ImportOrderCheck.class);
709         checkConfig.addAttribute("option", "top");
710         checkConfig.addAttribute("separated", "true");
711         checkConfig.addAttribute("groups", "java, org");
712         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
713         checkConfig.addAttribute("useContainerOrderingForStatic", "true");
714         final String[] expected = {
715             "4: " + getCheckMessage(MSG_ORDERING,
716                 "io.netty.handler.codec.http.HttpHeaders.Names.DATE"),
717         };
718         verify(checkConfig,
719             getNonCompilablePath("InputImportOrderEclipseStaticRepetition.java"), expected);
720     }
721 
722     @Test
723     public void testEclipseDefaultNegative() throws Exception {
724         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
725         checkConfig.addAttribute("groups", "java,javax,org,com");
726         checkConfig.addAttribute("ordered", "true");
727         checkConfig.addAttribute("separated", "true");
728         checkConfig.addAttribute("option", "top");
729         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
730         final String[] expected = {
731             "12: " + getCheckMessage(MSG_SEPARATION, "javax.swing.JComponent"),
732             "17: " + getCheckMessage(MSG_ORDERING, "org.junit.Test"),
733             };
734 
735         verify(checkConfig, getPath("InputImportOrder_EclipseDefaultNegative.java"), expected);
736     }
737 
738     @Test
739     public void testUseContainerOrderingForStaticTrue() throws Exception {
740         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
741         checkConfig.addAttribute("groups", "/^javax?\\./,org");
742         checkConfig.addAttribute("ordered", "true");
743         checkConfig.addAttribute("separated", "true");
744         checkConfig.addAttribute("option", "top");
745         checkConfig.addAttribute("caseSensitive", "false");
746         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
747         checkConfig.addAttribute("useContainerOrderingForStatic", "true");
748         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
749         verify(checkConfig, getNonCompilablePath("InputImportOrderEclipseStatic.java"), expected);
750     }
751 
752     @Test
753     public void testUseContainerOrderingForStaticFalse() throws Exception {
754         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
755         checkConfig.addAttribute("groups", "/^javax?\\./,org");
756         checkConfig.addAttribute("ordered", "true");
757         checkConfig.addAttribute("separated", "true");
758         checkConfig.addAttribute("option", "top");
759         checkConfig.addAttribute("caseSensitive", "false");
760         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
761         checkConfig.addAttribute("useContainerOrderingForStatic", "false");
762         final String[] expected = {
763             "6: " + getCheckMessage(MSG_ORDERING,
764                 "io.netty.handler.codec.http.HttpHeaders.Names.addDate"),
765         };
766         verify(checkConfig, getNonCompilablePath("InputImportOrderEclipseStatic.java"), expected);
767     }
768 
769     @Test
770     public void testUseContainerOrderingForStaticTrueCaseSensitive() throws Exception {
771         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
772         checkConfig.addAttribute("groups", "/^javax?\\./,org");
773         checkConfig.addAttribute("ordered", "true");
774         checkConfig.addAttribute("separated", "true");
775         checkConfig.addAttribute("option", "top");
776         checkConfig.addAttribute("sortStaticImportsAlphabetically", "true");
777         checkConfig.addAttribute("useContainerOrderingForStatic", "true");
778         final String[] expected = {
779             "7: " + getCheckMessage(MSG_ORDERING,
780                 "io.netty.handler.codec.http.HttpHeaders.Names.DATE"),
781             };
782         verify(checkConfig, getNonCompilablePath("InputImportOrderEclipseStatic.java"), expected);
783     }
784 
785     @Test
786     public void testImportGroupsRedundantSeparatedInternally() throws Exception {
787         final DefaultConfiguration checkConfig = createModuleConfig(ImportOrderCheck.class);
788         checkConfig.addAttribute("groups", "/^javax\\./,com");
789         checkConfig.addAttribute("ordered", "true");
790         checkConfig.addAttribute("separated", "true");
791         checkConfig.addAttribute("option", "bottom");
792         final String[] expected = {
793             "5: " + getCheckMessage(MSG_SEPARATED_IN_GROUP, "org.*"),
794         };
795         verify(checkConfig, getNonCompilablePath("InputImportOrder_MultiplePatternMatches.java"),
796                 expected);
797     }
798 }