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 final CheckstyleException exc =
167 getExpectedThrowable(CheckstyleException.class, () -> {
168 PackageNamesLoader.getPackageNames(new TestUrlsClassLoader(enumeration));
169 }, "CheckstyleException is expected");
170 assertWithMessage("Invalid exception cause class")
171 .that(exc)
172 .hasCauseThat()
173 .isInstanceOf(SAXException.class);
174 }
175
176 @Test
177 public void testPackagesWithIoException() throws Exception {
178 final URLStreamHandler handler = new URLStreamHandler() {
179 @Override
180 protected URLConnection openConnection(URL u) {
181 return new NoOperationUrlConnection(u);
182 }
183 };
184
185 final URL url = URL.of(URI.create("test://dummy"), handler);
186
187 final Enumeration<URL> enumeration = Collections.enumeration(Collections.singleton(url));
188
189 final CheckstyleException exc =
190 getExpectedThrowable(CheckstyleException.class, () -> {
191 PackageNamesLoader.getPackageNames(new TestUrlsClassLoader(enumeration));
192 }, "CheckstyleException is expected");
193 assertWithMessage("Invalid exception cause class")
194 .that(exc)
195 .hasCauseThat()
196 .isInstanceOf(IOException.class);
197 assertWithMessage("Invalid exception message")
198 .that(exc)
199 .hasMessageThat()
200 .isNotEqualTo("unable to get package file resources");
201 assertWithMessage("Exception message must contain URL")
202 .that(exc.getMessage())
203 .contains(url.toString());
204 }
205
206 @Test
207 public void testPackagesWithIoExceptionGetResources() {
208 final CheckstyleException exc =
209 getExpectedThrowable(CheckstyleException.class, () -> {
210 PackageNamesLoader.getPackageNames(new TestIoExceptionClassLoader());
211 }, "CheckstyleException is expected");
212 assertWithMessage("Invalid exception cause class")
213 .that(exc)
214 .hasCauseThat()
215 .isInstanceOf(IOException.class);
216 assertWithMessage("Invalid exception message")
217 .that(exc.getMessage())
218 .isEqualTo("unable to get package file resources");
219 }
220
221 @Test
222 public void testUnmodifiableCollection() throws Exception {
223 final Set<String> actualPackageNames = PackageNamesLoader
224 .getPackageNames(new TestUrlsClassLoader(Collections.emptyEnumeration()));
225
226 final Exception ex = getExpectedThrowable(UnsupportedOperationException.class,
227 () -> actualPackageNames.add("com.puppycrawl.tools.checkstyle.checks.modifier"));
228
229 assertWithMessage("Exception class is not expected")
230 .that(ex.getClass())
231 .isEqualTo(UnsupportedOperationException.class);
232 }
233
234 @Test
235 public void testMapping() throws Exception {
236 final Enumeration<URL> enumeration = Collections.enumeration(Collections.singleton(
237 new File(getPath("InputPackageNamesLoader1.xml")).toURI().toURL()));
238
239 final Set<String> actualPackageNames = PackageNamesLoader
240 .getPackageNames(new TestUrlsClassLoader(enumeration));
241
242 assertWithMessage("Invalid package names length.")
243 .that(actualPackageNames)
244 .hasSize(3);
245 }
246
247 @Test
248 public void testMapping2() throws Exception {
249 final Enumeration<URL> enumeration = Collections.enumeration(Collections.singleton(
250 new File(getPath("InputPackageNamesLoader2.xml")).toURI().toURL()));
251
252 final Set<String> actualPackageNames = PackageNamesLoader
253 .getPackageNames(new TestUrlsClassLoader(enumeration));
254
255 assertWithMessage("Invalid package names length.")
256 .that(actualPackageNames)
257 .hasSize(3);
258 }
259
260
261
262
263
264
265
266
267 private static final class TestUrlsClassLoader extends ClassLoader {
268
269 private final Enumeration<URL> urls;
270
271 private TestUrlsClassLoader(Enumeration<URL> urls) {
272 this.urls = urls;
273 }
274
275 @Override
276 public Enumeration<URL> getResources(String name) {
277 return urls;
278 }
279 }
280
281
282
283
284
285
286
287
288 private static final class TestIoExceptionClassLoader extends ClassLoader {
289 @Override
290 public Enumeration<URL> getResources(String name) throws IOException {
291 throw new IOException("test");
292 }
293 }
294
295
296
297
298 private static class NoOperationUrlConnection extends URLConnection {
299
300 NoOperationUrlConnection(URL url) {
301 super(url);
302 }
303
304 @Override
305 public void connect() {
306
307 }
308
309 @Override
310 public InputStream getInputStream() throws IOException {
311 throw new IOException("Simulated IO failure");
312 }
313 }
314 }