1 /*
2  * Copyright (C) 2015 Square, Inc.
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 package com.squareup.javapoet;
17 
18 import com.google.common.io.ByteStreams;
19 import java.io.IOException;
20 import java.net.URI;
21 import java.util.Collections;
22 import java.util.Locale;
23 import java.util.concurrent.Callable;
24 import javax.lang.model.element.Modifier;
25 import javax.tools.DiagnosticCollector;
26 import javax.tools.JavaCompiler;
27 import javax.tools.JavaCompiler.CompilationTask;
28 import javax.tools.JavaFileObject;
29 import javax.tools.JavaFileObject.Kind;
30 import javax.tools.StandardJavaFileManager;
31 import javax.tools.StandardLocation;
32 import javax.tools.ToolProvider;
33 import org.junit.Rule;
34 import org.junit.Test;
35 import org.junit.rules.TemporaryFolder;
36 import org.junit.runner.RunWith;
37 import org.junit.runners.JUnit4;
38 
39 import static com.google.common.truth.Truth.assertThat;
40 import static java.nio.charset.StandardCharsets.UTF_8;
41 
42 @RunWith(JUnit4.class)
43 public class FileReadingTest {
44 
45   // Used for storing compilation output.
46   @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder();
47 
javaFileObjectUri()48   @Test public void javaFileObjectUri() {
49     TypeSpec type = TypeSpec.classBuilder("Test").build();
50     assertThat(JavaFile.builder("", type).build().toJavaFileObject().toUri())
51         .isEqualTo(URI.create("Test.java"));
52     assertThat(JavaFile.builder("foo", type).build().toJavaFileObject().toUri())
53         .isEqualTo(URI.create("foo/Test.java"));
54     assertThat(JavaFile.builder("com.example", type).build().toJavaFileObject().toUri())
55         .isEqualTo(URI.create("com/example/Test.java"));
56   }
57 
javaFileObjectKind()58   @Test public void javaFileObjectKind() {
59     JavaFile javaFile = JavaFile.builder("", TypeSpec.classBuilder("Test").build()).build();
60     assertThat(javaFile.toJavaFileObject().getKind()).isEqualTo(Kind.SOURCE);
61   }
62 
javaFileObjectCharacterContent()63   @Test public void javaFileObjectCharacterContent() throws IOException {
64     TypeSpec type = TypeSpec.classBuilder("Test")
65         .addJavadoc("Pi\u00f1ata\u00a1")
66         .addMethod(MethodSpec.methodBuilder("fooBar").build())
67         .build();
68     JavaFile javaFile = JavaFile.builder("foo", type).build();
69     JavaFileObject javaFileObject = javaFile.toJavaFileObject();
70 
71     // We can never have encoding issues (everything is in process)
72     assertThat(javaFileObject.getCharContent(true)).isEqualTo(javaFile.toString());
73     assertThat(javaFileObject.getCharContent(false)).isEqualTo(javaFile.toString());
74   }
75 
javaFileObjectInputStreamIsUtf8()76   @Test public void javaFileObjectInputStreamIsUtf8() throws IOException {
77     JavaFile javaFile = JavaFile.builder("foo", TypeSpec.classBuilder("Test").build())
78         .addFileComment("Pi\u00f1ata\u00a1")
79         .build();
80     byte[] bytes = ByteStreams.toByteArray(javaFile.toJavaFileObject().openInputStream());
81 
82     // JavaPoet always uses UTF-8.
83     assertThat(bytes).isEqualTo(javaFile.toString().getBytes(UTF_8));
84   }
85 
compileJavaFile()86   @Test public void compileJavaFile() throws Exception {
87     final String value = "Hello World!";
88     TypeSpec type = TypeSpec.classBuilder("Test")
89         .addModifiers(Modifier.PUBLIC)
90         .addSuperinterface(ParameterizedTypeName.get(Callable.class, String.class))
91         .addMethod(MethodSpec.methodBuilder("call")
92             .returns(String.class)
93             .addModifiers(Modifier.PUBLIC)
94             .addStatement("return $S", value)
95             .build())
96         .build();
97     JavaFile javaFile = JavaFile.builder("foo", type).build();
98 
99     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
100     DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<>();
101     StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnosticCollector,
102         Locale.getDefault(), UTF_8);
103     fileManager.setLocation(StandardLocation.CLASS_OUTPUT,
104         Collections.singleton(temporaryFolder.newFolder()));
105     CompilationTask task = compiler.getTask(null,
106         fileManager,
107         diagnosticCollector,
108         Collections.emptySet(),
109         Collections.emptySet(),
110         Collections.singleton(javaFile.toJavaFileObject()));
111 
112     assertThat(task.call()).isTrue();
113     assertThat(diagnosticCollector.getDiagnostics()).isEmpty();
114 
115     ClassLoader loader = fileManager.getClassLoader(StandardLocation.CLASS_OUTPUT);
116     Callable<?> test = Class.forName("foo.Test", true, loader)
117             .asSubclass(Callable.class)
118             .getDeclaredConstructor()
119             .newInstance();
120     assertThat(Callable.class.getMethod("call").invoke(test)).isEqualTo(value);
121   }
122 }
123