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.utils;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.isUtilsClassHasPrivateConstructor;
24  
25  import java.util.List;
26  
27  import org.junit.jupiter.api.Test;
28  
29  import com.puppycrawl.tools.checkstyle.utils.InlineConfigUtils.MatchedDelimiter;
30  
31  public class InlineConfigUtilsTest {
32  
33      @Test
34      public void testIsProperUtilsClass() throws ReflectiveOperationException {
35          assertWithMessage("Constructor is not private")
36                  .that(isUtilsClassHasPrivateConstructor(InlineConfigUtils.class))
37                  .isTrue();
38      }
39  
40      @Test
41      public void testMatchDelimiterEmptyLines() {
42          final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
43                  List.of(), "Example.java");
44  
45          assertWithMessage("Result should be null for empty lines")
46                  .that(result)
47                  .isNull();
48      }
49  
50      @Test
51      public void testMatchDelimiterJavaXmlStyle() {
52          final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
53                  List.of("/*xml", "content", "*/"), "Example.java");
54  
55          assertWithMessage("Should match java xml-style config")
56                  .that(result)
57                  .isEqualTo(new MatchedDelimiter(InlineConfigUtils.JAVA_CONFIG_END, true));
58      }
59  
60      @Test
61      public void testMatchDelimiterJavaKeyValueStyle() {
62          final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
63                  List.of("/*", "ModuleName", "*/"), "Example.java");
64  
65          assertWithMessage("Should match java key-value style config")
66                  .that(result)
67                  .isEqualTo(new MatchedDelimiter(InlineConfigUtils.JAVA_CONFIG_END, false));
68      }
69  
70      @Test
71      public void testMatchDelimiterXmlTargetStyle() {
72          final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
73                  List.of("<!--xml", "content", "-->"), "Example.xml");
74  
75          assertWithMessage("Should match xml target style config")
76                  .that(result)
77                  .isEqualTo(new MatchedDelimiter(InlineConfigUtils.XML_TARGET_CONFIG_END, true));
78      }
79  
80      @Test
81      public void testMatchDelimiterXmlFileWithoutXmlMarkerFallsThroughToNull() {
82          final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
83                  List.of("<project>", "content"), "Example.xml");
84  
85          assertWithMessage("Should not match when first line is neither convention")
86                  .that(result)
87                  .isNull();
88      }
89  
90      @Test
91      public void testMatchDelimiterPropertiesTargetStyle() {
92          final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
93                  List.of(
94                      "#<module name=\"Checker\">",
95                      "#  <module name=\"UniqueProperties\"/>",
96                      "#</module>"),
97                  "Example.properties");
98  
99          assertWithMessage("Should match properties target style config")
100                 .that(result)
101                 .isEqualTo(new MatchedDelimiter(null, true));
102     }
103 
104     @Test
105     public void testMatchDelimiterPropertiesFileWithoutMarkerFallsThroughToNull() {
106         final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
107                 List.of("key=value"), "Example.properties");
108 
109         assertWithMessage("Should not match when first line is neither convention")
110                 .that(result)
111                 .isNull();
112     }
113 
114     @Test
115     public void testMatchDelimiterPropertiesFileWithCommentPrefix() {
116         final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
117                 List.of("#<module name=\"Checker\">"), "Example.properties");
118 
119         assertWithMessage("Should match when first line starts with #")
120                 .that(result)
121                 .isEqualTo(new MatchedDelimiter(null, true));
122     }
123 
124     @Test
125     public void testMatchDelimiterSqlFileUsesJavaConvention() {
126         final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
127                 List.of("/*xml", "content", "*/"), "Example.sql");
128 
129         assertWithMessage("Sql files should use the java convention")
130                 .that(result)
131                 .isEqualTo(new MatchedDelimiter(InlineConfigUtils.JAVA_CONFIG_END, true));
132     }
133 
134     @Test
135     public void testDescribeExpectedDelimitersJavaFile() {
136         final String result = InlineConfigUtils.describeExpectedDelimiters("Example.java");
137 
138         assertWithMessage("Description should mention java convention only")
139                 .that(result)
140                 .isEqualTo("\"/*xml\" or \"/*\" (Java-comment style)");
141     }
142 
143     @Test
144     public void testDescribeExpectedDelimitersXmlFile() {
145         final String result = InlineConfigUtils.describeExpectedDelimiters("Example.xml");
146 
147         assertWithMessage("Description should mention xml convention")
148                 .that(result)
149                 .isEqualTo("\"/*xml\" or \"/*\" (Java-comment style), or \"<!--xml\""
150                     + " (XML-comment style)");
151     }
152 
153     @Test
154     public void testDescribeExpectedDelimitersPropertiesFile() {
155         final String result = InlineConfigUtils.describeExpectedDelimiters("Example.properties");
156 
157         assertWithMessage("Description should mention properties convention")
158                 .that(result)
159                 .isEqualTo("\"/*xml\" or \"/*\" (Java-comment style), or \"#\""
160                     + " leading comment block, ending at the first blank line");
161     }
162 
163     @Test
164     public void testStripPropertiesCommentPrefixWithHash() {
165         final List<String> result = InlineConfigUtils.stripPropertiesCommentPrefix(
166                 List.of("#<module name=\"Checker\">", "#</module>"));
167 
168         assertWithMessage("Leading hash should be stripped")
169                 .that(result)
170                 .containsExactly("<module name=\"Checker\">", "</module>")
171                 .inOrder();
172     }
173 
174     @Test
175     public void testStripPropertiesCommentPrefixWithoutHash() {
176         final List<String> result = InlineConfigUtils.stripPropertiesCommentPrefix(
177                 List.of("", "not a comment"));
178 
179         assertWithMessage("Lines without a leading hash should pass through unchanged")
180                 .that(result)
181                 .containsExactly("", "not a comment")
182                 .inOrder();
183     }
184 
185     @Test
186     public void testStripPropertiesCommentPrefixMixedLines() {
187         final List<String> result = InlineConfigUtils.stripPropertiesCommentPrefix(
188                 List.of("#line with hash", "line without hash", "#another hash"));
189 
190         assertWithMessage("Mixed lines should be processed correctly")
191                 .that(result)
192                 .containsExactly("line with hash", "line without hash", "another hash")
193                 .inOrder();
194     }
195 
196     @Test
197     public void testMatchDelimiterXmlMarkerIgnoredForNonXmlExtension() {
198         final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
199                 List.of("<!--xml", "content", "-->"), "Example.properties");
200 
201         assertWithMessage("XML marker should not match when file extension is not .xml")
202                 .that(result)
203                 .isNull();
204     }
205 
206     @Test
207     public void testMatchDelimiterPropertiesMarkerIgnoredForNonPropertiesExtension() {
208         final MatchedDelimiter result = InlineConfigUtils.matchDelimiter(
209                 List.of("#<module name=\"Checker\">"), "Example.xml");
210 
211         assertWithMessage("Properties marker should not match when file extension"
212                 + " is not .properties")
213                 .that(result)
214                 .isNull();
215     }
216 
217     @Test
218     public void testGetConfigEndIndexWithNullEndDelimiter() {
219         final int result = InlineConfigUtils.getConfigEndIndex(
220                 List.of(
221                     "#<module name=\"Checker\">",
222                     "#  <module name=\"UniqueProperties\"/>",
223                     "",
224                     "key=value"),
225                 new MatchedDelimiter(null, true));
226 
227         assertWithMessage("Should find end at first blank line")
228                 .that(result)
229                 .isEqualTo(2);
230     }
231 
232     @Test
233     public void testGetConfigEndIndexWithNullEndDelimiterNoBlankLine() {
234         final int result = InlineConfigUtils.getConfigEndIndex(
235                 List.of(
236                     "#<module name=\"Checker\">",
237                     "#  <module name=\"UniqueProperties\"/>",
238                     "#</module>"),
239                 new MatchedDelimiter(null, true));
240 
241         assertWithMessage("Should find end at end of file when no blank line")
242                 .that(result)
243                 .isEqualTo(3);
244     }
245 
246     @Test
247     public void testGetConfigEndIndexWithExplicitEndDelimiter() {
248         final int result = InlineConfigUtils.getConfigEndIndex(
249                 List.of("/*xml", "#<module name=\"Checker\">", "*/", "key=value"),
250                 new MatchedDelimiter(InlineConfigUtils.JAVA_CONFIG_END, true));
251 
252         assertWithMessage("Should find end at explicit delimiter")
253                 .that(result)
254                 .isEqualTo(2);
255     }
256 
257     @Test
258     public void testGetConfigEndIndexWithExplicitEndDelimiterNotFound() {
259         final int result = InlineConfigUtils.getConfigEndIndex(
260                 List.of("/*xml", "#<module name=\"Checker\">", "key=value"),
261                 new MatchedDelimiter(InlineConfigUtils.JAVA_CONFIG_END, true));
262 
263         assertWithMessage("Should return -1 when end delimiter not found")
264                 .that(result)
265                 .isEqualTo(-1);
266     }
267 
268 }