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.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.io.FileNotFoundException;
27  import java.io.IOException;
28  import java.nio.charset.Charset;
29  import java.nio.charset.StandardCharsets;
30  import java.util.ArrayList;
31  import java.util.Arrays;
32  import java.util.Collections;
33  import java.util.List;
34  
35  import org.junit.jupiter.api.Test;
36  
37  import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport;
38  import com.puppycrawl.tools.checkstyle.internal.utils.CheckUtil;
39  import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
40  
41  public class FileTextTest extends AbstractPathTestSupport {
42  
43      @Override
44      public String getPackageLocation() {
45          return "com/puppycrawl/tools/checkstyle/api/filetext";
46      }
47  
48      @Test
49      public void testUnsupportedCharset() {
50          // just to make UT coverage 100%
51          final String charsetName = "STRANGE_CHARSET";
52          final File file = new File("any name");
53          final List<FileText> result = new ArrayList<>();
54          final IllegalStateException exc =
55                  getExpectedThrowable(IllegalStateException.class, () -> {
56                      result.add(new FileText(file, charsetName));
57                  }, "UnsupportedEncodingException is expected");
58          assertWithMessage("Object should not be created")
59                  .that(result)
60                  .isEmpty();
61          assertWithMessage("Invalid exception message")
62                  .that(exc)
63                  .hasMessageThat()
64                  .isEqualTo("Unsupported charset: " + charsetName);
65      }
66  
67      @Test
68      public void testFileNotFound() {
69          final String charsetName = StandardCharsets.ISO_8859_1.name();
70          final File file = new File("any name");
71          final List<FileText> result = new ArrayList<>();
72          final FileNotFoundException exc =
73                  getExpectedThrowable(FileNotFoundException.class, () -> {
74                      result.add(new FileText(file, charsetName));
75                  }, "FileNotFoundException is expected");
76          assertWithMessage("Object should not be created")
77                  .that(result)
78                  .isEmpty();
79          assertWithMessage("Invalid exception message")
80                  .that(exc)
81                  .hasMessageThat()
82                  .isEqualTo("any name (No such file or directory)");
83      }
84  
85      @Test
86      public void testSupportedCharset() throws IOException {
87          final String charsetName = StandardCharsets.ISO_8859_1.name();
88          final FileText fileText = new FileText(new File(getPath("InputFileTextImportControl.xml")),
89                  charsetName);
90          assertWithMessage("Invalid charset name")
91                  .that(fileText.getCharset().name())
92                  .isEqualTo(charsetName);
93      }
94  
95      @Test
96      public void testLineColumnBeforeCopyConstructor() throws IOException {
97          final String charsetName = StandardCharsets.ISO_8859_1.name();
98          final FileText fileText = new FileText(new File(getPath("InputFileTextImportControl.xml")),
99                  charsetName);
100         final LineColumn lineColumn = fileText.lineColumn(100);
101         final FileText copy = new FileText(fileText);
102         assertWithMessage("LineBreaks not copied")
103                 .that(TestUtil.getInternalState(copy, "lineBreaks", int[].class))
104                 .isNotNull();
105         final LineColumn actual = copy.lineColumn(100);
106         assertWithMessage("Invalid linecolumn")
107                 .that(actual)
108                 .isEqualTo(lineColumn);
109     }
110 
111     @Test
112     public void testLineColumnAfterCopyConstructor() throws IOException {
113         final Charset charset = StandardCharsets.ISO_8859_1;
114         final String filepath = getPath("InputFileTextImportControl.xml");
115         final FileText fileText = new FileText(new File(filepath), charset.name());
116         final FileText copy = new FileText(fileText);
117         assertWithMessage("LineBreaks not null")
118                 .that(TestUtil.getInternalState(copy, "lineBreaks", int[].class))
119                 .isNull();
120         final LineColumn lineColumn = copy.lineColumn(100);
121         assertWithMessage("Invalid line")
122                 .that(lineColumn.getLine())
123                 .isEqualTo(3);
124         if (CheckUtil.CRLF.equals(CheckUtil.getLineSeparatorForFile(filepath, charset))) {
125             assertWithMessage("Invalid column")
126                     .that(lineColumn.getColumn())
127                     .isEqualTo(44);
128         }
129         else {
130             assertWithMessage("Invalid column")
131                     .that(lineColumn.getColumn())
132                     .isEqualTo(46);
133         }
134     }
135 
136     @Test
137     public void testLineColumnAtTheStartOfFile() throws IOException {
138         final String charsetName = StandardCharsets.ISO_8859_1.name();
139         final FileText fileText = new FileText(new File(getPath("InputFileTextImportControl.xml")),
140                 charsetName);
141         final FileText copy = new FileText(fileText);
142         final LineColumn lineColumn = copy.lineColumn(0);
143         assertWithMessage("Invalid line")
144                 .that(lineColumn.getLine())
145                 .isEqualTo(1);
146         assertWithMessage("Invalid column")
147                 .that(lineColumn.getColumn())
148                 .isEqualTo(0);
149     }
150 
151     @Test
152     public void testLines() throws IOException {
153         final List<String> lines = Collections.singletonList("abc");
154         final FileText fileText = new FileText(new File(getPath("InputFileTextImportControl.xml")),
155                 lines);
156         assertWithMessage("Invalid line")
157                 .that(fileText.toLinesArray())
158                 .isEqualTo(new String[] {"abc"});
159     }
160 
161     @Test
162     public void testFindLineBreaks() throws Exception {
163         final FileText fileText = new FileText(new File("fileName"), Arrays.asList("1", "2"));
164 
165         assertWithMessage("Invalid line breaks")
166                 .that(TestUtil.invokeMethod(fileText, "findLineBreaks", int[].class))
167                 .isEqualTo(new int[] {0, 2, 4});
168 
169         final FileText fileText2 = new FileText(new File("fileName"), Arrays.asList("1", "2"));
170         TestUtil.setInternalState(fileText2, "fullText", "1\n2");
171 
172         assertWithMessage("Invalid line breaks")
173                 .that(TestUtil.invokeMethod(fileText2, "findLineBreaks", int[].class))
174                 .isEqualTo(new int[] {0, 2, 3});
175     }
176 
177     /**
178      * Reflection is the only way to test that a field is cached since we can't
179      * access the field directly or receive notice when the field is
180      * initialized.
181      *
182      * @throws Exception if there is an error.
183      */
184     @Test
185     public void testFindLineBreaksCache() throws Exception {
186         final FileText fileText = new FileText(new File("fileName"), Collections.emptyList());
187         final int[] lineBreaks = {5};
188         TestUtil.setInternalState(fileText, "lineBreaks", lineBreaks);
189         // produces NPE if used
190         TestUtil.setInternalState(fileText, "fullText", null);
191 
192         assertWithMessage("Invalid line breaks")
193                 .that(TestUtil.invokeMethod(fileText, "findLineBreaks", int[].class))
194                 .isEqualTo(lineBreaks);
195     }
196 
197     @Test
198     public void testCharsetAfterCopyConstructor() throws IOException {
199         final Charset charset = StandardCharsets.ISO_8859_1;
200         final String filepath = getPath("InputFileTextImportControl.xml");
201         final FileText fileText = new FileText(new File(filepath), charset.name());
202         final FileText copy = new FileText(fileText);
203         assertWithMessage("Should not be null")
204                 .that(copy.getCharset()).isNotNull();
205     }
206 }