Fix bug when JAR file is stored in path with non-US-ASCII characters
[jSite.git] / src / test / java / de / todesbaum / jsite / main / JarFileLocatorTest.java
1 package de.todesbaum.jsite.main;
2
3 import static org.hamcrest.MatcherAssert.assertThat;
4 import static org.hamcrest.Matchers.is;
5
6 import java.io.File;
7 import java.io.FileOutputStream;
8 import java.io.IOException;
9 import java.io.InputStream;
10 import java.net.MalformedURLException;
11 import java.net.URL;
12 import java.net.URLClassLoader;
13 import java.util.Optional;
14 import java.util.jar.JarEntry;
15 import java.util.jar.JarOutputStream;
16
17 import net.pterodactylus.util.io.StreamCopier;
18
19 import de.todesbaum.jsite.main.JarFileLocator.DefaultJarFileLocator;
20 import org.junit.Rule;
21 import org.junit.Test;
22 import org.junit.rules.TemporaryFolder;
23
24 /**
25  * Unit test for {@link JarFileLocator}.
26  */
27 public class JarFileLocatorTest {
28
29         @Rule
30         public final TemporaryFolder temporaryFolder = new TemporaryFolder();
31
32         private static final Class<?> CLASS_TO_LOAD = Main.class;
33         private static final String RESOURCE_TO_COPY = CLASS_TO_LOAD.getName().replace('.', '/') + ".class";
34         private static final String PACKAGE_NAME = CLASS_TO_LOAD.getPackage().getName();
35         private static final String CLASS_FILENAME = CLASS_TO_LOAD.getSimpleName() + ".class";
36
37         @Test
38         public void jarFileCanBeLocatedOnPathWithNonUsAsciiCharacters() throws Exception {
39                 File jarFilePath = temporaryFolder.newFolder("Фото café");
40                 File jarFile = createJarFile(jarFilePath);
41                 URLClassLoader urlClassLoader = createClassLoader(jarFile.toURI().toURL());
42                 JarFileLocator jarFileLocator = new DefaultJarFileLocator(urlClassLoader);
43                 File locatedJarFile = jarFileLocator.locateJarFile().get();
44                 assertThat(locatedJarFile, is(jarFile));
45         }
46
47         private File createJarFile(File folder) throws Exception {
48                 File jarFile = new File(folder, "test.jar");
49                 copyClassFileToStream(RESOURCE_TO_COPY, new FileOutputStream(jarFile));
50                 return jarFile;
51         }
52
53         private void copyClassFileToStream(String fileToCopy, FileOutputStream outputStream) throws IOException {
54                 try (JarOutputStream jarOutputStream = new JarOutputStream(outputStream);
55                          InputStream inputStream = getClass().getResourceAsStream("/" + fileToCopy)) {
56                         jarOutputStream.putNextEntry(new JarEntry(fileToCopy));
57                         StreamCopier.copy(inputStream, jarOutputStream);
58                         jarOutputStream.closeEntry();
59                 }
60         }
61
62         private URLClassLoader createClassLoader(URL url) throws MalformedURLException {
63                 return new URLClassLoader(new URL[] { url }) {
64                         @Override
65                         public URL getResource(String name) {
66                                 /* ignore parent class loader here. */
67                                 return findResource(name);
68                         }
69                 };
70         }
71
72         @Test
73         public void jarFileCanNotBeLocatedWhenLoadedFromFile() throws Exception {
74                 File folder = temporaryFolder.newFolder(PACKAGE_NAME.split("\\."));
75                 createClassFile(folder);
76                 ClassLoader classLoader = createClassLoader(temporaryFolder.getRoot().toURI().toURL());
77                 JarFileLocator jarFileLocator = new DefaultJarFileLocator(classLoader);
78                 Optional<File> locatedJarFile = jarFileLocator.locateJarFile();
79                 assertThat(locatedJarFile.isPresent(), is(false));
80         }
81
82         private void createClassFile(File folder) throws IOException {
83                 File classFile = new File(folder, CLASS_FILENAME);
84                 try (FileOutputStream outputStream = new FileOutputStream(classFile)) {
85                         copyClassFileToStream(RESOURCE_TO_COPY, outputStream);
86                 }
87         }
88
89         @Test
90         public void jarFileCanNotBeLoadedIfClasspathIsSuperWeirdAndClassDoesNotExist() throws Exception {
91                 ClassLoader classLoader = createClassLoader(temporaryFolder.getRoot().toURI().toURL());
92                 JarFileLocator jarFileLocator = new DefaultJarFileLocator(classLoader);
93                 Optional<File> locatedJarFile = jarFileLocator.locateJarFile();
94                 assertThat(locatedJarFile.isPresent(), is(false));
95         }
96
97 }