1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle;
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.IOException;
27 import java.io.InputStream;
28 import java.net.URI;
29 import java.net.URL;
30 import java.net.URLConnection;
31 import java.net.URLStreamHandler;
32 import java.util.Arrays;
33 import java.util.Collections;
34 import java.util.Enumeration;
35 import java.util.HashSet;
36 import java.util.Set;
37
38 import org.junit.jupiter.api.Test;
39 import org.xml.sax.SAXException;
40
41 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
42
43
44
45
46
47
48
49
50
51
52 public class PackageNamesLoaderTest extends AbstractPathTestSupport {
53
54 @Override
55 public String getPackageLocation() {
56 return "com/puppycrawl/tools/checkstyle/packagenamesloader";
57 }
58
59 @Test
60 public void testDefault()
61 throws CheckstyleException {
62 final Set<String> packageNames = PackageNamesLoader
63 .getPackageNames(Thread.currentThread()
64 .getContextClassLoader());
65 assertWithMessage("pkgNames.length.")
66 .that(packageNames)
67 .isEmpty();
68 }
69
70 @Test
71 public void testNoPackages() throws Exception {
72 final Set<String> actualPackageNames = PackageNamesLoader
73 .getPackageNames(new TestUrlsClassLoader(Collections.emptyEnumeration()));
74
75 assertWithMessage("Invalid package names length.")
76 .that(actualPackageNames)
77 .isEmpty();
78 }
79
80 @Test
81 public void testPackagesFile() throws Exception {
82 final Enumeration<URL> enumeration = Collections.enumeration(Collections.singleton(
83 new File(getPath("InputPackageNamesLoaderFile.xml")).toURI().toURL()));
84
85 final Set<String> actualPackageNames = PackageNamesLoader
86 .getPackageNames(new TestUrlsClassLoader(enumeration));
87 final String[] expectedPackageNames = {
88 "com.puppycrawl.tools.checkstyle",
89 "com.puppycrawl.tools.checkstyle.checks",
90 "com.puppycrawl.tools.checkstyle.checks.annotation",
91 "com.puppycrawl.tools.checkstyle.checks.blocks",
92 "com.puppycrawl.tools.checkstyle.checks.coding",
93 "com.puppycrawl.tools.checkstyle.checks.design",
94 "com.puppycrawl.tools.checkstyle.checks.header",
95 "com.puppycrawl.tools.checkstyle.checks.imports",
96 "com.puppycrawl.tools.checkstyle.checks.indentation",
97 "com.puppycrawl.tools.checkstyle.checks.javadoc",
98 "com.puppycrawl.tools.checkstyle.checks.metrics",
99 "com.puppycrawl.tools.checkstyle.checks.modifier",
100 "com.puppycrawl.tools.checkstyle.checks.naming",
101 "com.puppycrawl.tools.checkstyle.checks.regexp",
102 "com.puppycrawl.tools.checkstyle.checks.sizes",
103 "com.puppycrawl.tools.checkstyle.checks.whitespace",
104 "com.puppycrawl.tools.checkstyle.filefilters",
105 "com.puppycrawl.tools.checkstyle.filters",
106 };
107
108 assertWithMessage("Invalid package names length.")
109 .that(actualPackageNames)
110 .hasSize(expectedPackageNames.length);
111 final Set<String> checkstylePackagesSet =
112 new HashSet<>(Arrays.asList(expectedPackageNames));
113 assertWithMessage("Invalid names set.")
114 .that(actualPackageNames)
115 .isEqualTo(checkstylePackagesSet);
116 }
117
118 @Test
119 public void testPackagesWithDots() throws Exception {
120 final Enumeration<URL> enumeration = Collections.enumeration(Collections.singleton(
121 new File(getPath("InputPackageNamesLoaderWithDots.xml")).toURI().toURL()));
122
123 final Set<String> actualPackageNames = PackageNamesLoader
124 .getPackageNames(new TestUrlsClassLoader(enumeration));
125 final String[] expectedPackageNames = {
126 "coding.",
127 };
128
129 assertWithMessage("Invalid package names length.")
130 .that(actualPackageNames)
131 .hasSize(expectedPackageNames.length);
132 final Set<String> checkstylePackagesSet =
133 new HashSet<>(Arrays.asList(expectedPackageNames));
134 assertWithMessage("Invalid names set.")
135 .that(actualPackageNames)
136 .isEqualTo(checkstylePackagesSet);
137 }
138
139 @Test
140 public void testPackagesWithDotsEx() throws Exception {
141 final Enumeration<URL> enumeration = Collections.enumeration(Collections.singleton(
142 new File(getPath("InputPackageNamesLoaderWithDotsEx.xml")).toURI().toURL()));
143
144 final Set<String> actualPackageNames = PackageNamesLoader
145 .getPackageNames(new TestUrlsClassLoader(enumeration));
146 final String[] expectedPackageNames = {
147 "coding.specific",
148 "coding.",
149 };
150
151 assertWithMessage("Invalid package names length.")
152 .that(actualPackageNames)
153 .hasSize(expectedPackageNames.length);
154 final Set<String> checkstylePackagesSet =
155 new HashSet<>(Arrays.asList(expectedPackageNames));
156 assertWithMessage("Invalid names set.")
157 .that(actualPackageNames)
158 .isEqualTo(checkstylePackagesSet);
159 }
160
161 @Test
162 public void testPackagesWithSaxException() throws Exception {
163 final Enumeration<URL> enumeration = Collections.enumeration(Collections.singleton(
164 new File(getPath("InputPackageNamesLoaderNotXml.java")).toURI().toURL()));
165
166 try {
167 PackageNamesLoader.getPackageNames(new TestUrlsClassLoader(enumeration));
168 assertWithMessage("CheckstyleException is expected").fail();
169 }
170 catch (CheckstyleException exc) {
171 assertWithMessage("Invalid exception cause class")
172 .that(exc)
173 .hasCauseThat()
174 .isInstanceOf(SAXException.class);
175 }
176 }
177
178 @Test
179 public void testPackagesWithIoException() throws Exception {
180 final URLStreamHandler handler = new URLStreamHandler() {
181 @Override
182 protected URLConnection openConnection(URL u) {
183 return new NoOperationUrlConnection(u);
184 }
185 };
186
187 final URL url = URL.of(URI.create("test://dummy"), handler);
188
189 final Enumeration<URL> enumeration = Collections.enumeration(Collections.singleton(url));
190
191 try {
192 PackageNamesLoader.getPackageNames(new TestUrlsClassLoader(enumeration));
193 assertWithMessage("CheckstyleException is expected").fail();
194 }
195 catch (CheckstyleException exc) {
196 assertWithMessage("Invalid exception cause class")
197 .that(exc)
198 .hasCauseThat()
199 .isInstanceOf(IOException.class);
200 assertWithMessage("Invalid exception message")
201 .that(exc)
202 .hasMessageThat()
203 .isNotEqualTo("unable to get package file resources");
204 assertWithMessage("Exception message must contain URL")
205 .that(exc.getMessage())
206 .contains(url.toString());
207 }
208 }
209
210 @Test
211 public void testPackagesWithIoExceptionGetResources() {
212 try {
213 PackageNamesLoader.getPackageNames(new TestIoExceptionClassLoader());
214 assertWithMessage("CheckstyleException is expected").fail();
215 }
216 catch (CheckstyleException exc) {
217 assertWithMessage("Invalid exception cause class")
218 .that(exc)
219 .hasCauseThat()
220 .isInstanceOf(IOException.class);
221 assertWithMessage("Invalid exception message")
222 .that(exc.getMessage())
223 .isEqualTo("unable to get package file resources");
224 }
225 }
226
227 @Test
228 public void testUnmodifiableCollection() throws Exception {
229 final Set<String> actualPackageNames = PackageNamesLoader
230 .getPackageNames(new TestUrlsClassLoader(Collections.emptyEnumeration()));
231
232 final Exception ex = getExpectedThrowable(UnsupportedOperationException.class,
233 () -> actualPackageNames.add("com.puppycrawl.tools.checkstyle.checks.modifier"));
234
235 assertWithMessage("Exception class is not expected")
236 .that(ex.getClass())
237 .isEqualTo(UnsupportedOperationException.class);
238 }
239
240 @Test
241 public void testMapping() throws Exception {
242 final Enumeration<URL> enumeration = Collections.enumeration(Collections.singleton(
243 new File(getPath("InputPackageNamesLoader1.xml")).toURI().toURL()));
244
245 final Set<String> actualPackageNames = PackageNamesLoader
246 .getPackageNames(new TestUrlsClassLoader(enumeration));
247
248 assertWithMessage("Invalid package names length.")
249 .that(actualPackageNames)
250 .hasSize(3);
251 }
252
253 @Test
254 public void testMapping2() throws Exception {
255 final Enumeration<URL> enumeration = Collections.enumeration(Collections.singleton(
256 new File(getPath("InputPackageNamesLoader2.xml")).toURI().toURL()));
257
258 final Set<String> actualPackageNames = PackageNamesLoader
259 .getPackageNames(new TestUrlsClassLoader(enumeration));
260
261 assertWithMessage("Invalid package names length.")
262 .that(actualPackageNames)
263 .hasSize(3);
264 }
265
266
267
268
269
270
271
272
273 private static final class TestUrlsClassLoader extends ClassLoader {
274
275 private final Enumeration<URL> urls;
276
277 private TestUrlsClassLoader(Enumeration<URL> urls) {
278 this.urls = urls;
279 }
280
281 @Override
282 public Enumeration<URL> getResources(String name) {
283 return urls;
284 }
285 }
286
287
288
289
290
291
292
293
294 private static final class TestIoExceptionClassLoader extends ClassLoader {
295 @Override
296 public Enumeration<URL> getResources(String name) throws IOException {
297 throw new IOException("test");
298 }
299 }
300
301
302
303
304 private static class NoOperationUrlConnection extends URLConnection {
305
306 NoOperationUrlConnection(URL url) {
307 super(url);
308 }
309
310 @Override
311 public void connect() {
312
313 }
314
315 @Override
316 public InputStream getInputStream() throws IOException {
317 throw new IOException("Simulated IO failure");
318 }
319 }
320 }