/*
* Copyright 2015-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.facebook.buck.jvm.java;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import com.facebook.buck.testutil.TestJar;
import com.facebook.buck.zip.JarBuilder;
import com.google.common.collect.ImmutableSet;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.jar.JarFile;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
/** Tests {@link JavaInMemoryFileManager} */
public class JavaInMemoryFileManagerTest {
@Rule public TemporaryFolder temp = new TemporaryFolder();
private JavaInMemoryFileManager inMemoryFileManager;
@Before
public void setUp() {
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
inMemoryFileManager =
new JavaInMemoryFileManager(
ToolProvider.getSystemJavaCompiler().getStandardFileManager(diagnostics, null, null),
Paths.get(URI.create("file:///tmp/test.jar!/")),
/*classesToBeRemovedFromJar */ ImmutableSet.of());
}
@Test
public void testJavaFileName() throws Exception {
JavaFileObject fileObject =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"com.facebook.buck.jvm.java.JavaFileParser",
JavaFileObject.Kind.CLASS,
null);
assertEquals(JavaFileObject.Kind.CLASS, fileObject.getKind());
assertEquals("com/facebook/buck/jvm/java/JavaFileParser.class", fileObject.getName());
}
@Test
public void testWriteContent() throws Exception {
JavaFileObject fileObject =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT, "JavaFileParser", JavaFileObject.Kind.CLASS, null);
OutputStream stream = fileObject.openOutputStream();
stream.write("Hello World!".getBytes());
stream.close();
TestJar jar = writeToJar();
List<String> entries = jar.getEntriesContent();
assertEquals(3, entries.size());
assertEquals("Hello World!", entries.get(2));
}
@Test
public void testFilesWrittenInSortedOrder() throws Exception {
JavaFileObject fileObject =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT, "B.C", JavaFileObject.Kind.CLASS, null);
fileObject.openOutputStream().close();
fileObject =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT, "A", JavaFileObject.Kind.CLASS, null);
fileObject.openOutputStream().close();
fileObject =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT, "B", JavaFileObject.Kind.CLASS, null);
fileObject.openOutputStream().close();
fileObject =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT, "B$D", JavaFileObject.Kind.CLASS, null);
fileObject.openOutputStream().close();
TestJar jar = writeToJar();
assertThat(
jar.getZipEntries().stream().map(ZipEntry::getName).collect(Collectors.toList()),
Matchers.contains(
"META-INF/",
JarFile.MANIFEST_NAME,
"A.class",
"B$D.class",
"B.class",
"B/",
"B/C.class"));
}
@Test
public void testIntermediateDirectoriesAreCreated() throws Exception {
JavaFileObject fileObject =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaFileParser",
JavaFileObject.Kind.CLASS,
null);
fileObject.openOutputStream().close();
TestJar jar = writeToJar();
List<String> zipEntries =
jar.getZipEntries().stream().map(ZipEntry::getName).collect(Collectors.toList());
assertThat(
zipEntries,
Matchers.contains(
"META-INF/",
JarFile.MANIFEST_NAME,
"jvm/",
"jvm/java/",
"jvm/java/JavaFileParser.class"));
}
@Test
public void testMultipleFilesInSamePackage() throws Exception {
JavaFileObject fileObject1 =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaFileParser",
JavaFileObject.Kind.CLASS,
null);
JavaFileObject fileObject2 =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaInMemoryFileManager",
JavaFileObject.Kind.CLASS,
null);
fileObject1.openOutputStream().close();
fileObject2.openOutputStream().close();
TestJar jar = writeToJar();
List<String> zipEntries =
jar.getZipEntries().stream().map(ZipEntry::getName).collect(Collectors.toList());
assertThat(
zipEntries,
Matchers.contains(
"META-INF/",
JarFile.MANIFEST_NAME,
"jvm/",
"jvm/java/",
"jvm/java/JavaFileParser.class",
"jvm/java/JavaInMemoryFileManager.class"));
}
@Test
public void testIsNotSameFile() throws Exception {
JavaFileObject fileObject1 =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaFileParser",
JavaFileObject.Kind.CLASS,
null);
JavaFileObject fileObject2 =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaInMemoryFileManager",
JavaFileObject.Kind.CLASS,
null);
assertFalse(inMemoryFileManager.isSameFile(fileObject1, fileObject2));
}
@Test
public void testIsSameFile() throws Exception {
JavaFileObject fileObject1 =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaFileParser",
JavaFileObject.Kind.CLASS,
null);
JavaFileObject fileObject2 =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaFileParser",
JavaFileObject.Kind.CLASS,
null);
assertTrue(inMemoryFileManager.isSameFile(fileObject1, fileObject2));
}
@Test
public void testNonRecursiveListOperationReturnsNewlyCreatedFile() throws Exception {
JavaFileObject fileObject1 =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaFileParser",
JavaFileObject.Kind.CLASS,
null);
Iterator<JavaFileObject> nonRecursiveIterable =
inMemoryFileManager
.list(
StandardLocation.CLASS_OUTPUT,
"jvm.java",
Collections.singleton(JavaFileObject.Kind.CLASS),
false)
.iterator();
assertEquals(fileObject1, nonRecursiveIterable.next());
assertFalse(nonRecursiveIterable.hasNext());
}
@Test
public void testNonRecursiveListOperationDoesntReturnNewlyCreatedFileOnOtherDir()
throws Exception {
JavaFileObject fileObject1 =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaFileParser",
JavaFileObject.Kind.CLASS,
null);
assertEquals("jvm/java/JavaFileParser.class", fileObject1.getName());
Iterator<JavaFileObject> recursiveIterable =
inMemoryFileManager
.list(
StandardLocation.CLASS_OUTPUT,
"jvm",
Collections.singleton(JavaFileObject.Kind.CLASS),
false)
.iterator();
assertFalse(recursiveIterable.hasNext());
}
@Test
public void testRecursiveListOperationReturnsNewlyCreatedFile() throws Exception {
JavaFileObject fileObject1 =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaFileParser",
JavaFileObject.Kind.CLASS,
null);
Iterator<JavaFileObject> recursiveIterable =
inMemoryFileManager
.list(
StandardLocation.CLASS_OUTPUT,
"jvm",
Collections.singleton(JavaFileObject.Kind.CLASS),
true)
.iterator();
assertEquals(fileObject1, recursiveIterable.next());
assertFalse(recursiveIterable.hasNext());
}
@Test
public void testGetFileForOutputWithoutOpeningWritesNothing() throws IOException {
inMemoryFileManager.getFileForOutput(
StandardLocation.CLASS_OUTPUT, "jvm.java", "JavaFileParser", null);
TestJar jar = writeToJar();
assertThat(
jar.getZipEntries().stream().map(ZipEntry::getName).collect(Collectors.toList()),
Matchers.contains("META-INF/", JarFile.MANIFEST_NAME));
}
@Test
public void testGetJavaFileForOutputWithoutOpeningWritesNothing() throws IOException {
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT, "jvm.java.JavaFileParser", JavaFileObject.Kind.OTHER, null);
TestJar jar = writeToJar();
assertThat(
jar.getZipEntries().stream().map(ZipEntry::getName).collect(Collectors.toList()),
Matchers.contains("META-INF/", JarFile.MANIFEST_NAME));
}
@Test
public void testWriteToStreamWithoutClosingWritesNothing() throws IOException {
JavaFileObject fileObject =
inMemoryFileManager.getJavaFileForOutput(
StandardLocation.CLASS_OUTPUT,
"jvm.java.JavaFileParser",
JavaFileObject.Kind.OTHER,
null);
fileObject.openOutputStream().write("Hello".getBytes());
TestJar jar = writeToJar();
assertThat(
jar.getZipEntries().stream().map(ZipEntry::getName).collect(Collectors.toList()),
Matchers.contains("META-INF/", JarFile.MANIFEST_NAME));
}
private TestJar writeToJar() throws IOException {
File jarFile = temp.newFile();
JarBuilder jarBuilder = new JarBuilder();
inMemoryFileManager.writeToJar(jarBuilder);
jarBuilder.createJarFile(jarFile.toPath());
return new TestJar(jarFile);
}
}