Allow TestCompiler to access and generate resources

Update `TestCompiler` so that it can access and generate resources.
This change will allow the `TestCompiler` to be used with annotation
processor tests that generate resources.

Closes gh-29174

Co-authored-by: Phillip Webb <pwebb@vmware.com>
This commit is contained in:
Scott Frederick
2022-09-19 21:00:53 -07:00
committed by Phillip Webb
parent cc7552ec61
commit c9009453c9
14 changed files with 397 additions and 86 deletions

View File

@@ -34,22 +34,19 @@ class DynamicClassFileObjectTests {
@Test
void getUriReturnsGeneratedUriBasedOnClassName() {
DynamicClassFileObject fileObject = new DynamicClassFileObject(
"com.example.MyClass");
DynamicClassFileObject fileObject = new DynamicClassFileObject("com.example.MyClass");
assertThat(fileObject.toUri()).hasToString("class:///com/example/MyClass.class");
}
@Test
void getKindReturnsClass() {
DynamicClassFileObject fileObject = new DynamicClassFileObject(
"com.example.MyClass");
DynamicClassFileObject fileObject = new DynamicClassFileObject("com.example.MyClass");
assertThat(fileObject.getKind()).isEqualTo(Kind.CLASS);
}
@Test
void openOutputStreamWritesToBytes() throws Exception {
DynamicClassFileObject fileObject = new DynamicClassFileObject(
"com.example.MyClass");
DynamicClassFileObject fileObject = new DynamicClassFileObject("com.example.MyClass");
try(OutputStream outputStream = fileObject.openOutputStream()) {
new ByteArrayInputStream("test".getBytes()).transferTo(outputStream);
}

View File

@@ -17,8 +17,10 @@
package org.springframework.aot.test.generate.compile;
import java.io.IOException;
import java.io.OutputStream;
import java.util.EnumSet;
import javax.tools.FileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
@@ -31,6 +33,9 @@ import org.mockito.MockitoAnnotations;
import org.springframework.aot.test.generate.file.ClassFile;
import org.springframework.aot.test.generate.file.ClassFiles;
import org.springframework.aot.test.generate.file.ResourceFile;
import org.springframework.aot.test.generate.file.ResourceFiles;
import org.springframework.util.StreamUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.then;
@@ -39,11 +44,14 @@ import static org.mockito.BDDMockito.then;
* Tests for {@link DynamicJavaFileManager}.
*
* @author Phillip Webb
* @author Scott Frederick
*/
class DynamicJavaFileManagerTests {
private static final byte[] DUMMY_BYTECODE = new byte[] { 'a' };
private static final String DUMMY_RESOURCE = "a";
@Mock
private JavaFileManager parentFileManager;
@@ -58,9 +66,14 @@ class DynamicJavaFileManagerTests {
void setup() {
MockitoAnnotations.openMocks(this);
this.classLoader = new ClassLoader() {};
ClassFiles classFiles = ClassFiles.of(
ClassFile.of("com.example.one.ClassOne", DUMMY_BYTECODE),
ClassFile.of("com.example.two.ClassTwo", DUMMY_BYTECODE));
ResourceFiles resourceFiles = ResourceFiles.of(
ResourceFile.of("com/example/one/resource.one", DUMMY_RESOURCE),
ResourceFile.of("com/example/two/resource.two", DUMMY_RESOURCE));
this.fileManager = new DynamicJavaFileManager(this.parentFileManager, this.classLoader,
ClassFiles.of(ClassFile.of("com.example.one.ClassOne", DUMMY_BYTECODE),
ClassFile.of("com.example.two.ClassTwo", DUMMY_BYTECODE)));
classFiles, resourceFiles);
}
@Test
@@ -81,6 +94,7 @@ class DynamicJavaFileManagerTests {
throws Exception {
JavaFileObject fileObject1 = this.fileManager.getJavaFileForOutput(this.location,
"com.example.MyClass", Kind.CLASS, null);
writeDummyResource(fileObject1);
JavaFileObject fileObject2 = this.fileManager.getJavaFileForOutput(this.location,
"com.example.MyClass", Kind.CLASS, null);
assertThat(fileObject1).isSameAs(fileObject2);
@@ -97,11 +111,11 @@ class DynamicJavaFileManagerTests {
@Test
void getClassFilesReturnsClassFiles() throws Exception {
this.fileManager.getJavaFileForOutput(this.location, "com.example.MyClass1",
Kind.CLASS, null);
this.fileManager.getJavaFileForOutput(this.location, "com.example.MyClass2",
Kind.CLASS, null);
assertThat(this.fileManager.getCompiledClasses()).containsKeys(
writeDummyBytecode(this.fileManager.getJavaFileForOutput(this.location, "com.example.MyClass1",
Kind.CLASS, null));
writeDummyBytecode(this.fileManager.getJavaFileForOutput(this.location, "com.example.MyClass2",
Kind.CLASS, null));
assertThat(this.fileManager.getDynamicClassFiles()).containsKeys(
"com.example.MyClass1", "com.example.MyClass2");
}
@@ -129,4 +143,31 @@ class DynamicJavaFileManagerTests {
assertThat(listed).hasSize(0);
}
@Test
void getFileForOutputReturnsDynamicResourceFile() {
FileObject fileObject = this.fileManager.getFileForOutput(this.location,
"", "META-INF/generated.properties", null);
assertThat(fileObject).isInstanceOf(DynamicResourceFileObject.class);
}
@Test
void getFileForOutputReturnsFile() throws Exception {
writeDummyResource(this.fileManager.getFileForOutput(this.location, "", "META-INF/first.properties", null));
writeDummyResource(this.fileManager.getFileForOutput(this.location, "", "META-INF/second.properties", null));
assertThat(this.fileManager.getDynamicResourceFiles()).containsKeys("META-INF/first.properties",
"META-INF/second.properties");
}
private void writeDummyBytecode(JavaFileObject fileObject) throws IOException {
try (OutputStream outputStream = fileObject.openOutputStream()) {
StreamUtils.copy(DUMMY_BYTECODE, outputStream);
}
}
private void writeDummyResource(FileObject fileObject) throws IOException {
try (OutputStream outputStream = fileObject.openOutputStream()) {
StreamUtils.copy(DUMMY_RESOURCE.getBytes(), outputStream);
}
}
}

View File

@@ -34,7 +34,7 @@ class DynamicJavaFileObjectTests {
@Test
void getUriReturnsPath() {
DynamicJavaFileObject fileObject = new DynamicJavaFileObject(SourceFile.of(CONTENT));
assertThat(fileObject.toUri()).hasToString("com/example/Hello.java");
assertThat(fileObject.toUri()).hasToString("java:///com/example/Hello.java");
}
@Test

View File

@@ -0,0 +1,77 @@
/*
* Copyright 2002-2022 the original author or authors.
*
* 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
*
* https://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 org.springframework.aot.test.generate.compile;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.tools.JavaFileObject.Kind;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIOException;
/**
* Tests for {@link DynamicResourceFileObject}.
*
* @author Phillip Webb
* @author Scott Frederick
* @since 6.0
*/
class DynamicResourceFileObjectTests {
@Test
void getUriReturnsFileUri() {
DynamicResourceFileObject fileObject = new DynamicResourceFileObject("META-INF/test.properties");
assertThat(fileObject.toUri()).hasToString("resource:///META-INF/test.properties");
}
@Test
void getKindReturnsOther() {
DynamicResourceFileObject fileObject = new DynamicResourceFileObject("META-INF/test.properties");
assertThat(fileObject.getKind()).isEqualTo(Kind.OTHER);
}
@Test
void openOutputStreamWritesToBytes() throws Exception {
DynamicResourceFileObject fileObject = new DynamicResourceFileObject("META-INF/test.properties");
try(OutputStream outputStream = fileObject.openOutputStream()) {
new ByteArrayInputStream("test".getBytes()).transferTo(outputStream);
}
assertThat(fileObject.getBytes()).isEqualTo("test".getBytes());
}
@Test
void openInputStreamReadsFromBytes() throws Exception {
DynamicResourceFileObject fileObject = new DynamicResourceFileObject("META-INF/test.properties");
try(OutputStream outputStream = fileObject.openOutputStream()) {
new ByteArrayInputStream("test".getBytes()).transferTo(outputStream);
}
try(InputStream inputStream = fileObject.openInputStream()) {
assertThat(inputStream.readAllBytes()).isEqualTo("test".getBytes());
}
}
@Test
void openInputStreamWhenNothingWrittenThrowsException() {
DynamicResourceFileObject fileObject = new DynamicResourceFileObject("META-INF/test.properties");
assertThatIOException().isThrownBy(fileObject::openInputStream);
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.aot.test.generate.file;
import java.io.File;
import java.io.IOException;
import org.junit.jupiter.api.Test;
@@ -27,6 +28,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
* Tests for {@link SourceFile}.
*
* @author Phillip Webb
* @author Scott Frederick
*/
class SourceFileTests {
@@ -83,6 +85,20 @@ class SourceFileTests {
assertThat(sourceFile.getPath()).isEqualTo("com/example/DifferentPath.java");
}
@Test
void forClassWithClassUsesClass() {
SourceFile sourceFile = SourceFile.forClass(new File("src/test/java"), SourceFileTests.class);
assertThat(sourceFile.getPath()).isEqualTo("org/springframework/aot/test/generate/file/SourceFileTests.java");
assertThat(sourceFile.getClassName()).isEqualTo("org.springframework.aot.test.generate.file.SourceFileTests");
}
@Test
void forTestClassWithClassUsesClass() {
SourceFile sourceFile = SourceFile.forTestClass(SourceFileTests.class);
assertThat(sourceFile.getPath()).isEqualTo("org/springframework/aot/test/generate/file/SourceFileTests.java");
assertThat(sourceFile.getClassName()).isEqualTo("org.springframework.aot.test.generate.file.SourceFileTests");
}
@Test
void getContentReturnsContent() {
SourceFile sourceFile = SourceFile.of(HELLO_WORLD);