View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 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.api;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
24  
25  import java.io.File;
26  import java.util.Arrays;
27  import java.util.Collections;
28  import java.util.HashMap;
29  import java.util.List;
30  import java.util.Map;
31  
32  import org.junit.jupiter.api.Test;
33  
34  import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
35  
36  public class FileContentsTest {
37  
38      @Test
39      public void testTextFileName() {
40          final FileContents fileContents = new FileContents(
41                  new FileText(new File("filename"), Arrays.asList("123", "456")));
42  
43          assertWithMessage("Invalid file name")
44                  .that(fileContents.getText().getFile().getName())
45                  .isEqualTo("filename");
46          assertWithMessage("Invalid array")
47                  .that(fileContents.getLines())
48                  .isEqualTo(new String[] {"123", "456"});
49          assertWithMessage("Invalid file name")
50                  .that(fileContents.getFileName())
51                  .isEqualTo("filename");
52      }
53  
54      @Test
55      public void testIsLineBlank() {
56          assertWithMessage("Invalid result")
57                  .that(new FileContents(
58                          new FileText(new File("filename"), Collections.singletonList("123")))
59                                  .lineIsBlank(0))
60                  .isFalse();
61          assertWithMessage("Invalid result")
62                  .that(new FileContents(new FileText(new File("filename"),
63                          Collections.singletonList("")))
64                          .lineIsBlank(0))
65                  .isTrue();
66      }
67  
68      @Test
69      public void testLineIsComment() {
70          assertWithMessage("Invalid result")
71                  .that(new FileContents(
72                          new FileText(new File("filename"), Collections.singletonList("123")))
73                                  .lineIsComment(0))
74                  .isFalse();
75          assertWithMessage("Invalid result")
76                  .that(new FileContents(
77                          new FileText(new File("filename"), Collections.singletonList(" // abc")))
78                                  .lineIsComment(0))
79                  .isTrue();
80      }
81  
82      @Test
83      public void testDeprecatedAbbreviatedMethod() {
84          // just to make UT coverage 100%
85          final FileContents fileContents = new FileContents(
86                  new FileText(new File("filename"), Arrays.asList("123", "456")));
87          fileContents.reportSingleLineComment(1, 1);
88          fileContents.reportBlockComment(1, 1, 1, 1);
89  
90          final Comment cppComment = new Comment(new String[] {"23"}, 1, 1, 2);
91          final Comment cComment = new Comment(new String[] {"2"}, 1, 1, 1);
92          final String lineComment = fileContents.getSingleLineComments().get(1).toString();
93          assertWithMessage("Invalid cpp comment")
94                  .that(lineComment)
95                  .isEqualTo(cppComment.toString());
96          final String blockComment = fileContents.getBlockComments().get(1).get(0).toString();
97          assertWithMessage("Invalid c comment")
98                  .that(blockComment)
99                  .isEqualTo(cComment.toString());
100     }
101 
102     @Test
103     public void testSinglelineCommentNotIntersect() {
104         // just to make UT coverage 100%
105         final FileContents fileContents = new FileContents(
106                 new FileText(new File("filename"), Collections.singletonList("  //  ")));
107         fileContents.reportSingleLineComment(1, 2);
108         assertWithMessage("Should return false when there is no intersection")
109                 .that(fileContents.hasIntersectionWithComment(1, 0, 1, 1))
110                 .isFalse();
111     }
112 
113     @Test
114     public void testSinglelineCommentIntersect() {
115         // just to make UT coverage 100%
116         final FileContents fileContents = new FileContents(
117                 new FileText(new File("filename"), Collections.singletonList("  //   ")));
118         fileContents.reportSingleLineComment("type", 1, 2);
119         assertWithMessage("Should return true when comments intersect")
120                 .that(fileContents.hasIntersectionWithComment(1, 5, 1, 6))
121                 .isTrue();
122     }
123 
124     @Test
125     public void testReportCppComment() {
126         final FileContents fileContents = new FileContents(
127                 new FileText(new File("filename"), Collections.singletonList("   //  ")));
128         fileContents.reportSingleLineComment(1, 2);
129         final Map<Integer, TextBlock> cppComments = fileContents.getSingleLineComments();
130 
131         assertWithMessage("Invalid comment")
132                 .that(cppComments.get(1).toString())
133                 .isEqualTo(new Comment(new String[] {" //  "}, 2, 1, 6).toString());
134     }
135 
136     @Test
137     public void testHasIntersectionWithSingleLineComment() {
138         final FileContents fileContents = new FileContents(
139                 new FileText(new File("filename"), Arrays.asList("     ", "  //test   ",
140                         "  //test   ", "  //test   ")));
141         fileContents.reportSingleLineComment(4, 4);
142 
143         assertWithMessage("Should return true when comments intersect")
144                 .that(fileContents.hasIntersectionWithComment(1, 3, 4, 6))
145                 .isTrue();
146     }
147 
148     @Test
149     public void testReportComment() {
150         final FileContents fileContents = new FileContents(
151                 new FileText(new File("filename"), Collections.singletonList("  //   ")));
152         fileContents.reportBlockComment("type", 1, 2, 1, 2);
153         final Map<Integer, List<TextBlock>> comments = fileContents.getBlockComments();
154 
155         assertWithMessage("Invalid comment")
156                 .that(comments.get(1).get(0).toString())
157                 .isEqualTo(new Comment(new String[] {"/"}, 2, 1, 2).toString());
158     }
159 
160     @Test
161     public void testReportBlockCommentSameLine() {
162         final FileContents fileContents = new FileContents(
163                 new FileText(new File("filename"), Collections.singletonList("/* a */ /* b */ ")));
164         fileContents.reportBlockComment("type", 1, 0, 1, 6);
165         fileContents.reportBlockComment("type", 1, 8, 1, 14);
166         final Map<Integer, List<TextBlock>> comments = fileContents.getBlockComments();
167 
168         assertWithMessage("Invalid comment")
169                 .that(comments.get(1).toString())
170                 .isEqualTo(Arrays.asList(
171                     new Comment(new String[] {"/* a */"}, 0, 1, 6),
172                     new Comment(new String[] {"/* b */"}, 8, 1, 14)
173                 ).toString());
174     }
175 
176     @Test
177     public void testReportBlockCommentMultiLine() {
178         final FileContents fileContents = new FileContents(
179                 new FileText(new File("filename"), Arrays.asList("/*", "c", "*/")));
180         fileContents.reportBlockComment("type", 1, 0, 3, 1);
181         final Map<Integer, List<TextBlock>> comments = fileContents.getBlockComments();
182 
183         assertWithMessage("Invalid comment")
184                 .that(comments.get(1).toString())
185                 .isEqualTo(Collections.singletonList(
186                     new Comment(new String[] {"/*", "c", "*/"}, 0, 3, 1)).toString()
187             );
188     }
189 
190     @Test
191     public void testReportBlockCommentJavadoc() {
192         final FileContents fileContents = new FileContents(new FileText(new File("filename"),
193                 Arrays.asList("/** A */", "", "//", "/**/", "/* B */")));
194         fileContents.reportBlockComment("type", 1, 0, 1, 7);
195         fileContents.reportBlockComment("type", 4, 0, 4, 3);
196         fileContents.reportBlockComment("type", 5, 0, 5, 6);
197 
198         assertWithMessage("Invalid comment")
199                 .that(fileContents.getJavadocBefore(1))
200                 .isNull();
201         assertWithMessage("Invalid comment")
202                 .that(fileContents.getJavadocBefore(4).toString())
203                 .isEqualTo(new Comment(new String[] {"/** A */"}, 0, 1, 7).toString());
204         assertWithMessage("Invalid comment")
205                 .that(fileContents.getJavadocBefore(5))
206                 .isNull();
207         assertWithMessage("Invalid comment")
208                 .that(fileContents.getJavadocBefore(6))
209                 .isNull();
210     }
211 
212     @Test
213     public void testHasIntersectionWithBlockComment() {
214         final FileContents fileContents = new FileContents(new FileText(new File("filename"),
215                         Arrays.asList("  /* */    ", "    ", "  /* test   ", "  */  ", "   ")));
216         fileContents.reportBlockComment(1, 2, 1, 5);
217         fileContents.reportBlockComment(3, 2, 4, 2);
218 
219         assertWithMessage("Should return true when comments intersect")
220                 .that(fileContents.hasIntersectionWithComment(2, 2, 3, 6))
221                 .isTrue();
222     }
223 
224     @Test
225     public void testHasIntersectionWithBlockComment2() {
226         final FileContents fileContents = new FileContents(
227                 new FileText(new File("filename"), Arrays.asList("  /* */    ", "    ", " ")));
228         fileContents.reportBlockComment(1, 2, 1, 5);
229 
230         assertWithMessage("Should return false when there is no intersection")
231                 .that(fileContents.hasIntersectionWithComment(2, 2, 3, 6))
232                 .isFalse();
233     }
234 
235     @Test
236     public void testReportJavadocComment() {
237         final FileContents fileContents = new FileContents(
238                 new FileText(new File("filename"), Collections.singletonList("  /** */   ")));
239         fileContents.reportBlockComment(1, 2, 1, 6);
240         final TextBlock comment = fileContents.getJavadocBefore(2);
241 
242         assertWithMessage("Invalid comment")
243                 .that(comment.toString())
244                 .isEqualTo(new Comment(new String[] {"/** *"}, 2, 1, 6).toString());
245     }
246 
247     @Test
248     public void testReportJavadocComment2() {
249         final FileContents fileContents = new FileContents(
250                 new FileText(new File("filename"), Collections.singletonList("  /** */   ")));
251         fileContents.reportBlockComment(1, 2, 1, 6);
252         final TextBlock comment = fileContents.getJavadocBefore(2);
253 
254         assertWithMessage("Invalid comment")
255                 .that(comment.toString())
256                 .isEqualTo(new Comment(new String[] {"/** *"}, 2, 1, 6).toString());
257     }
258 
259     /*
260      * This method is deprecated due to usage of deprecated FileContents#inPackageInfo
261      * we keep this method until https://github.com/checkstyle/checkstyle/issues/11723
262      */
263     @Deprecated(since = "10.2")
264     @Test
265     public void testInPackageInfo() {
266         final FileContents fileContents = new FileContents(new FileText(
267                 new File("package-info.java"),
268                 Collections.singletonList("  //   ")));
269 
270         assertWithMessage("Should return true when in package info")
271                 .that(fileContents.inPackageInfo())
272                 .isTrue();
273     }
274 
275     /*
276      * This method is deprecated due to usage of deprecated FileContents#inPackageInfo
277      * we keep this method until https://github.com/checkstyle/checkstyle/issues/11723
278      */
279     @Deprecated(since = "10.2")
280     @Test
281     public void testNotInPackageInfo() {
282         final FileContents fileContents = new FileContents(new FileText(
283                 new File("some-package-info.java"),
284                 Collections.singletonList("  //   ")));
285 
286         assertWithMessage("Should return false when not in package info")
287                 .that(fileContents.inPackageInfo())
288                 .isFalse();
289     }
290 
291     @Test
292     public void testGetJavadocBefore() {
293         final FileContents fileContents = new FileContents(
294                 new FileText(new File("filename"), Collections.singletonList("    ")));
295         final Map<Integer, TextBlock> javadoc = new HashMap<>();
296         javadoc.put(0, new Comment(new String[] {"// "}, 2, 1, 2));
297         TestUtil.setInternalState(fileContents, "javadocComments", javadoc);
298         final TextBlock javadocBefore = fileContents.getJavadocBefore(2);
299 
300         assertWithMessage("Invalid before javadoc")
301                 .that(javadocBefore.toString())
302                 .isEqualTo(new Comment(new String[] {"// "}, 2, 1, 2).toString());
303     }
304 
305     @Test
306     public void testExtractBlockComment() {
307         final FileContents fileContents = new FileContents(
308                 new FileText(new File("filename"), Arrays.asList("   ", "    ", "  /* test   ",
309                         "  */  ", "   ")));
310         fileContents.reportBlockComment(3, 2, 4, 2);
311         final Map<Integer, List<TextBlock>> blockComments =
312             fileContents.getBlockComments();
313         final String[] text = blockComments.get(3).get(0).getText();
314 
315         assertWithMessage("Invalid comment text")
316                 .that(text)
317                 .isEqualTo(new String[] {"/* test   ", "  *"});
318     }
319 
320     @Test
321     public void testHasIntersectionEarlyOut() throws Exception {
322         final FileContents fileContents = new FileContents(
323                 new FileText(new File("filename"), Collections.emptyList()));
324         final Map<Integer, List<TextBlock>> clangComments = TestUtil.getInternalState(fileContents,
325                 "clangComments");
326         final TextBlock textBlock = new Comment(new String[] {""}, 1, 1, 1);
327         clangComments.put(1, Collections.singletonList(textBlock));
328         clangComments.put(2, Collections.emptyList());
329 
330         assertWithMessage("Invalid results")
331                 .that(TestUtil.<Boolean>invokeMethod(fileContents,
332                         "hasIntersectionWithBlockComment", 1, 1, 1, 1))
333                 .isTrue();
334     }
335 
336     @Test
337     public void testUnmodifiableGetSingleLineComment() {
338         final FileContents cppComments = new FileContents(new FileText(new File("filename"),
339                 Arrays.asList("// comment ", " A + B ", " ")));
340         cppComments.reportSingleLineComment(1, 0);
341         final Map<Integer, TextBlock> comments = cppComments.getSingleLineComments();
342         final Exception ex = getExpectedThrowable(UnsupportedOperationException.class,
343                 () -> comments.remove(0));
344         assertWithMessage("Exception message not expected")
345                 .that(ex.getClass())
346                 .isEqualTo(UnsupportedOperationException.class);
347     }
348 
349     @Test
350     public void testUnmodifiableGetBlockComments() {
351         final FileContents clangComments = new FileContents(new FileText(new File("filename"),
352                 Arrays.asList("/* comment ", " ", " comment */")));
353         clangComments.reportBlockComment(1, 0, 3, 9);
354         final Map<Integer, List<TextBlock>> comments = clangComments.getBlockComments();
355         final Exception ex = getExpectedThrowable(UnsupportedOperationException.class,
356                 () -> comments.remove(0));
357         assertWithMessage("Exception message not expected")
358                 .that(ex.getClass())
359                 .isEqualTo(UnsupportedOperationException.class);
360     }
361 }