1 /* 2 * Copyright 2019 Google Inc. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.turbine.processing; 18 19 import static com.google.common.collect.Iterables.getOnlyElement; 20 import static com.google.common.truth.Truth.assertThat; 21 import static java.nio.charset.StandardCharsets.UTF_8; 22 import static org.junit.Assert.fail; 23 24 import com.google.common.base.Function; 25 import com.google.common.base.Supplier; 26 import com.google.common.io.ByteStreams; 27 import com.google.common.io.CharStreams; 28 import com.google.turbine.diag.SourceFile; 29 import java.io.FileNotFoundException; 30 import java.io.IOException; 31 import java.io.OutputStream; 32 import java.io.Writer; 33 import java.util.Arrays; 34 import java.util.Collection; 35 import java.util.HashSet; 36 import java.util.Map; 37 import java.util.Set; 38 import javax.annotation.processing.FilerException; 39 import javax.lang.model.element.Element; 40 import javax.tools.FileObject; 41 import javax.tools.JavaFileObject; 42 import javax.tools.StandardLocation; 43 import org.checkerframework.checker.nullness.qual.Nullable; 44 import org.junit.Before; 45 import org.junit.Test; 46 import org.junit.runner.RunWith; 47 import org.junit.runners.JUnit4; 48 49 @RunWith(JUnit4.class) 50 public class TurbineFilerTest { 51 52 private final Set<String> seen = new HashSet<>(); 53 private TurbineFiler filer; 54 55 @Before setup()56 public void setup() { 57 Function<String, Supplier<byte[]>> classpath = 58 new Function<String, Supplier<byte[]>>() { 59 @Nullable 60 @Override 61 public Supplier<byte[]> apply(String input) { 62 return null; 63 } 64 }; 65 this.filer = new TurbineFiler(seen, classpath, TurbineFilerTest.class.getClassLoader()); 66 } 67 68 @Test hello()69 public void hello() throws IOException { 70 JavaFileObject sourceFile = filer.createSourceFile("com.foo.Bar", (Element[]) null); 71 try (OutputStream os = sourceFile.openOutputStream()) { 72 os.write("hello".getBytes(UTF_8)); 73 } 74 assertThat(sourceFile.getLastModified()).isEqualTo(0); 75 76 JavaFileObject classFile = filer.createClassFile("com.foo.Baz", (Element[]) null); 77 try (OutputStream os = classFile.openOutputStream()) { 78 os.write("goodbye".getBytes(UTF_8)); 79 } 80 assertThat(classFile.getLastModified()).isEqualTo(0); 81 82 Collection<SourceFile> roundSources = filer.finishRound(); 83 assertThat(roundSources).hasSize(1); 84 assertThat(filer.generatedSources()).hasSize(1); 85 assertThat(filer.generatedClasses()).hasSize(1); 86 87 SourceFile source = getOnlyElement(roundSources); 88 assertThat(source.path()).isEqualTo("com/foo/Bar.java"); 89 assertThat(source.source()).isEqualTo("hello"); 90 91 Map.Entry<String, byte[]> clazz = getOnlyElement(filer.generatedClasses().entrySet()); 92 assertThat(clazz.getKey()).isEqualTo("com/foo/Baz.class"); 93 assertThat(new String(clazz.getValue(), UTF_8)).isEqualTo("goodbye"); 94 } 95 96 @Test existing()97 public void existing() throws IOException { 98 seen.add("com/foo/Bar.java"); 99 seen.add("com/foo/Baz.class"); 100 101 try { 102 filer.createSourceFile("com.foo.Bar", (Element[]) null); 103 fail(); 104 } catch (FilerException expected) { 105 } 106 filer.createSourceFile("com.foo.Baz", (Element[]) null); 107 108 filer.createClassFile("com.foo.Bar", (Element[]) null); 109 try { 110 filer.createClassFile("com.foo.Baz", (Element[]) null); 111 fail(); 112 } catch (FilerException expected) { 113 } 114 } 115 116 @Test get()117 public void get() throws IOException { 118 for (StandardLocation location : 119 Arrays.asList( 120 StandardLocation.CLASS_OUTPUT, 121 StandardLocation.SOURCE_OUTPUT, 122 StandardLocation.ANNOTATION_PROCESSOR_PATH, 123 StandardLocation.CLASS_PATH)) { 124 try { 125 filer.getResource(location, "", "NoSuch"); 126 fail(); 127 } catch (FileNotFoundException expected) { 128 } 129 } 130 } 131 132 @Test sourceOutput()133 public void sourceOutput() throws IOException { 134 JavaFileObject classFile = filer.createSourceFile("com.foo.Bar", (Element[]) null); 135 try (Writer writer = classFile.openWriter()) { 136 writer.write("hello"); 137 } 138 filer.finishRound(); 139 140 FileObject output = filer.getResource(StandardLocation.SOURCE_OUTPUT, "com.foo", "Bar.java"); 141 assertThat(new String(ByteStreams.toByteArray(output.openInputStream()), UTF_8)) 142 .isEqualTo("hello"); 143 assertThat(output.getCharContent(false).toString()).isEqualTo("hello"); 144 assertThat(CharStreams.toString(output.openReader(true))).isEqualTo("hello"); 145 } 146 147 @Test classOutput()148 public void classOutput() throws IOException { 149 JavaFileObject classFile = filer.createClassFile("com.foo.Baz", (Element[]) null); 150 try (OutputStream os = classFile.openOutputStream()) { 151 os.write("goodbye".getBytes(UTF_8)); 152 } 153 filer.finishRound(); 154 155 FileObject output = filer.getResource(StandardLocation.CLASS_OUTPUT, "com.foo", "Baz.class"); 156 assertThat(new String(ByteStreams.toByteArray(output.openInputStream()), UTF_8)) 157 .isEqualTo("goodbye"); 158 assertThat(output.getCharContent(false).toString()).isEqualTo("goodbye"); 159 assertThat(CharStreams.toString(output.openReader(true))).isEqualTo("goodbye"); 160 } 161 162 @Test classpathResources()163 public void classpathResources() throws IOException { 164 FileObject resource = 165 filer.getResource(StandardLocation.ANNOTATION_PROCESSOR_PATH, "META-INF", "MANIFEST.MF"); 166 167 assertThat(new String(ByteStreams.toByteArray(resource.openInputStream()), UTF_8)) 168 .contains("Manifest-Version:"); 169 assertThat(CharStreams.toString(resource.openReader(true))).contains("Manifest-Version:"); 170 assertThat(resource.getCharContent(false).toString()).contains("Manifest-Version:"); 171 } 172 } 173