View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2026 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.modules;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.modules.ModuleDirectiveOrderCheck.MSG_GROUPING;
24  import static com.puppycrawl.tools.checkstyle.checks.modules.ModuleDirectiveOrderCheck.MSG_ORDER;
25  import static com.puppycrawl.tools.checkstyle.checks.modules.ModuleDirectiveOrderCheck.MSG_SEPARATED_INTERNALLY;
26  import static com.puppycrawl.tools.checkstyle.checks.modules.ModuleDirectiveOrderCheck.MSG_SEPARATION;
27  import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
28  
29  import org.junit.jupiter.api.Test;
30  
31  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
32  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
33  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
34  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
35  
36  public class ModuleDirectiveOrderCheckTest extends AbstractModuleTestSupport {
37  
38      @Override
39      public String getPackageLocation() {
40          return "com/puppycrawl/tools/checkstyle/checks/modules/moduledirectiveorder";
41      }
42  
43      @Test
44      public void testGetRequiredTokens() {
45          final ModuleDirectiveOrderCheck check = new ModuleDirectiveOrderCheck();
46          final int[] expected = {TokenTypes.MODULE_DEF};
47          assertWithMessage("Required tokens are invalid")
48              .that(check.getRequiredTokens())
49              .isEqualTo(expected);
50      }
51  
52      @Test
53      public void testGetAcceptableTokens() {
54          final ModuleDirectiveOrderCheck check = new ModuleDirectiveOrderCheck();
55          final int[] expected = {TokenTypes.MODULE_DEF};
56          assertWithMessage("Acceptable tokens are invalid")
57              .that(check.getAcceptableTokens())
58              .isEqualTo(expected);
59          assertWithMessage("Default tokens are invalid")
60              .that(check.getDefaultTokens())
61              .isEqualTo(expected);
62      }
63  
64      @Test
65      public void testDefault() throws Exception {
66          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
67          verifyWithInlineConfigParser(
68                  getNonCompilablePath("module-info/default/module-info.java"), expected);
69      }
70  
71      @Test
72      public void testWrongOrder() throws Exception {
73          final String[] expected = {
74              "14:5: " + getCheckMessage(MSG_ORDER, "requires", "exports"),
75          };
76          verifyWithInlineConfigParser(
77                  getNonCompilablePath("module-info/unordered/module-info.java"), expected);
78      }
79  
80      @Test
81      public void testWrongOrderReversed() throws Exception {
82          final String[] expected = {
83              "14:5: " + getCheckMessage(MSG_ORDER, "opens", "uses"),
84              "16:5: " + getCheckMessage(MSG_ORDER, "exports", "opens"),
85              "18:5: " + getCheckMessage(MSG_ORDER, "requires", "exports"),
86          };
87          verifyWithInlineConfigParser(
88                  getNonCompilablePath("module-info/reversed/module-info.java"), expected);
89      }
90  
91      @Test
92      public void testGrouping() throws Exception {
93          final String[] expected = {
94              "16:5: " + getCheckMessage(MSG_GROUPING, "requires"),
95              "21:5: " + getCheckMessage(MSG_GROUPING, "exports"),
96          };
97          verifyWithInlineConfigParser(
98                  getNonCompilablePath("module-info/grouping/module-info.java"), expected);
99      }
100 
101     @Test
102     public void testSeparation() throws Exception {
103         final String[] expected = {
104             "13:5: " + getCheckMessage(MSG_SEPARATION, "exports"),
105             "17:5: " + getCheckMessage(MSG_SEPARATION, "opens"),
106         };
107         verifyWithInlineConfigParser(
108                 getNonCompilablePath("module-info/separation/module-info.java"), expected);
109     }
110 
111     @Test
112     public void testSeparatedInternally() throws Exception {
113         final String[] expected = {
114             "14:5: " + getCheckMessage(MSG_SEPARATED_INTERNALLY, "requires"),
115             "20:5: " + getCheckMessage(MSG_SEPARATED_INTERNALLY, "exports"),
116         };
117         verifyWithInlineConfigParser(
118                 getNonCompilablePath("module-info/internal/module-info.java"),
119                 expected);
120     }
121 
122     @Test
123     public void testValidateBlockSeparationFalse() throws Exception {
124         final String[] expected = {
125             "20:5: " + getCheckMessage(MSG_GROUPING, "requires"),
126         };
127         verifyWithInlineConfigParser(
128                 getNonCompilablePath("module-info/unseparated/module-info.java"),
129                 expected);
130     }
131 
132     @Test
133     public void testCustomOrder() throws Exception {
134         final String[] expected = {
135             "17:5: " + getCheckMessage(MSG_ORDER, "uses", "exports"),
136         };
137         verifyWithInlineConfigParser(
138                 getNonCompilablePath("module-info/custom/module-info.java"), expected);
139     }
140 
141     @Test
142     public void testCustomOrderSubset() throws Exception {
143         final String[] expected = {
144             "15:5: " + getCheckMessage(MSG_ORDER, "requires", "exports"),
145         };
146         verifyWithInlineConfigParser(
147                 getNonCompilablePath("module-info/subset/module-info.java"), expected);
148     }
149 
150     @Test
151     public void testEmptyModule() throws Exception {
152         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
153         verifyWithInlineConfigParser(
154                 getNonCompilablePath("module-info/empty/module-info.java"), expected);
155     }
156 
157     @Test
158     public void testSameLine() throws Exception {
159         final String[] expected = {
160             "13:25: " + getCheckMessage(MSG_SEPARATION, "exports"),
161         };
162         verifyWithInlineConfigParser(
163                 getNonCompilablePath("module-info/adjacent/module-info.java"), expected);
164     }
165 
166     @Test
167     public void testCommentBetweenBlocks() throws Exception {
168         final String[] expected = {
169             "14:5: " + getCheckMessage(MSG_SEPARATION, "exports"),
170         };
171         verifyWithInlineConfigParser(
172                 getNonCompilablePath("module-info/comment/module-info.java"), expected);
173     }
174 
175     @Test
176     public void testMultiLineDirective() throws Exception {
177         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
178         verifyWithInlineConfigParser(
179                 getNonCompilablePath("module-info/multiline/module-info.java"), expected);
180     }
181 
182     @Test
183     public void testDefaultQualifiedForms() throws Exception {
184         final String[] expected = {
185             "15:5: " + getCheckMessage(MSG_ORDER, "requires", "exports"),
186             "18:5: " + getCheckMessage(MSG_SEPARATED_INTERNALLY, "requires"),
187         };
188         verifyWithInlineConfigParser(
189                 getNonCompilablePath("module-info/modifiers/module-info.java"),
190                 expected);
191     }
192 
193     @Test
194     public void testCompactSourceFile() throws Exception {
195         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
196         verifyWithInlineConfigParser(
197                 getNonCompilablePath("compact/InputModuleDirectiveOrderCompactSourceFile.java"),
198                 expected);
199     }
200 
201     @Test
202     public void testCompactSourceFileNonDefault() throws Exception {
203         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
204         verifyWithInlineConfigParser(
205                 getNonCompilablePath(
206                         "compact/InputModuleDirectiveOrderCompactSourceFileNonDefault.java"),
207                 expected);
208     }
209 
210     @Test
211     public void testSetOrderInvalidValue() {
212         final ModuleDirectiveOrderCheck check = new ModuleDirectiveOrderCheck();
213         final IllegalArgumentException exc = getExpectedThrowable(IllegalArgumentException.class,
214                 () -> check.setOrder("requires", "foo"));
215         assertWithMessage("Invalid exception message")
216             .that(exc.getMessage())
217             .isEqualTo("unable to parse foo");
218     }
219 
220     @Test
221     public void testInvalidOrderProperty() {
222         final CheckstyleException exc = getExpectedThrowable(CheckstyleException.class,
223                 () -> {
224                     final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
225                     verifyWithInlineConfigParser(
226                             getNonCompilablePath("module-info/invalid/module-info.java"),
227                             expected);
228                 });
229         assertWithMessage("Invalid exception message")
230             .that(exc.getMessage())
231             .isEqualTo("cannot initialize module com.puppycrawl.tools.checkstyle.TreeWalker - "
232                     + "cannot initialize module com.puppycrawl.tools.checkstyle.checks"
233                     + ".modules.ModuleDirectiveOrderCheck");
234     }
235 
236 }