Polish
This commit is contained in:
parent
321092ce6f
commit
2f84096af1
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.core.test.io.support;
|
package org.springframework.core.test.io.support;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -58,7 +59,8 @@ public class MockSpringFactoriesLoader extends SpringFactoriesLoader {
|
||||||
this(classLoader, new LinkedHashMap<>());
|
this(classLoader, new LinkedHashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MockSpringFactoriesLoader(ClassLoader classLoader, Map<String, List<String>> factories) {
|
protected MockSpringFactoriesLoader(@Nullable ClassLoader classLoader,
|
||||||
|
Map<String, List<String>> factories) {
|
||||||
super(classLoader, factories);
|
super(classLoader, factories);
|
||||||
this.factories = factories;
|
this.factories = factories;
|
||||||
}
|
}
|
||||||
|
@ -66,8 +68,8 @@ public class MockSpringFactoriesLoader extends SpringFactoriesLoader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T> T instantiateFactory(String implementationName, Class<T> type, ArgumentResolver argumentResolver,
|
protected <T> T instantiateFactory(String implementationName, Class<T> type,
|
||||||
FailureHandler failureHandler) {
|
@Nullable ArgumentResolver argumentResolver, FailureHandler failureHandler) {
|
||||||
if (implementationName.startsWith("!")) {
|
if (implementationName.startsWith("!")) {
|
||||||
Object implementation = this.implementations.get(implementationName);
|
Object implementation = this.implementations.get(implementationName);
|
||||||
if (implementation != null) {
|
if (implementation != null) {
|
||||||
|
@ -83,7 +85,6 @@ public class MockSpringFactoriesLoader extends SpringFactoriesLoader {
|
||||||
* @param factoryImplementations the implementation classes
|
* @param factoryImplementations the implementation classes
|
||||||
*/
|
*/
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public final <T> void add(Class<T> factoryType, Class<? extends T>... factoryImplementations) {
|
public final <T> void add(Class<T> factoryType, Class<? extends T>... factoryImplementations) {
|
||||||
for (Class<? extends T> factoryImplementation : factoryImplementations) {
|
for (Class<? extends T> factoryImplementation : factoryImplementations) {
|
||||||
add(factoryType.getName(), factoryImplementation.getName());
|
add(factoryType.getName(), factoryImplementation.getName());
|
||||||
|
@ -96,10 +97,9 @@ public class MockSpringFactoriesLoader extends SpringFactoriesLoader {
|
||||||
* @param factoryImplementations the implementation class names
|
* @param factoryImplementations the implementation class names
|
||||||
*/
|
*/
|
||||||
public void add(String factoryType, String... factoryImplementations) {
|
public void add(String factoryType, String... factoryImplementations) {
|
||||||
List<String> implementations = this.factories.computeIfAbsent(factoryType, key -> new ArrayList<>());
|
List<String> implementations = this.factories.computeIfAbsent(
|
||||||
for (String factoryImplementation : factoryImplementations) {
|
factoryType, key -> new ArrayList<>());
|
||||||
implementations.add(factoryImplementation);
|
Collections.addAll(implementations, factoryImplementations);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -38,12 +38,12 @@ public class CompilationException extends RuntimeException {
|
||||||
message.append(errors);
|
message.append(errors);
|
||||||
message.append("\n\n");
|
message.append("\n\n");
|
||||||
for (SourceFile sourceFile : sourceFiles) {
|
for (SourceFile sourceFile : sourceFiles) {
|
||||||
message.append("---- source: " + sourceFile.getPath() + "\n\n");
|
message.append("---- source: ").append(sourceFile.getPath()).append("\n\n");
|
||||||
message.append(sourceFile.getContent());
|
message.append(sourceFile.getContent());
|
||||||
message.append("\n\n");
|
message.append("\n\n");
|
||||||
}
|
}
|
||||||
for (ResourceFile resourceFile : resourceFiles) {
|
for (ResourceFile resourceFile : resourceFiles) {
|
||||||
message.append("---- resource: " + resourceFile.getPath() + "\n\n");
|
message.append("---- resource: ").append(resourceFile.getPath()).append("\n\n");
|
||||||
message.append(resourceFile.getContent());
|
message.append(resourceFile.getContent());
|
||||||
message.append("\n\n");
|
message.append("\n\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ import java.net.URI;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In-memory {@link JavaFileObject} used to hold class bytecode.
|
* In-memory {@link JavaFileObject} used to hold class bytecode.
|
||||||
*
|
*
|
||||||
|
@ -36,6 +38,7 @@ class DynamicClassFileObject extends SimpleJavaFileObject {
|
||||||
|
|
||||||
private final String className;
|
private final String className;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private volatile byte[] bytes;
|
private volatile byte[] bytes;
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,10 +60,11 @@ class DynamicClassFileObject extends SimpleJavaFileObject {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream openInputStream() throws IOException {
|
public InputStream openInputStream() throws IOException {
|
||||||
if (this.bytes == null) {
|
byte[] content = this.bytes;
|
||||||
|
if (content == null) {
|
||||||
throw new IOException("No data written");
|
throw new IOException("No data written");
|
||||||
}
|
}
|
||||||
return new ByteArrayInputStream(this.bytes);
|
return new ByteArrayInputStream(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -76,6 +80,7 @@ class DynamicClassFileObject extends SimpleJavaFileObject {
|
||||||
return this.className;
|
return this.className;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
byte[] getBytes() {
|
byte[] getBytes() {
|
||||||
return this.bytes;
|
return this.bytes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,12 +66,12 @@ public class DynamicClassLoader extends ClassLoader {
|
||||||
this.dynamicResourceFiles = dynamicResourceFiles;
|
this.dynamicResourceFiles = dynamicResourceFiles;
|
||||||
Class<? extends ClassLoader> parentClass = parent.getClass();
|
Class<? extends ClassLoader> parentClass = parent.getClass();
|
||||||
if (parentClass.getName().equals(CompileWithForkedClassLoaderClassLoader.class.getName())) {
|
if (parentClass.getName().equals(CompileWithForkedClassLoaderClassLoader.class.getName())) {
|
||||||
Method setClassResourceLookupMethod = ReflectionUtils.findMethod(parentClass,
|
Method setClassResourceLookupMethod = lookupMethod(parentClass,
|
||||||
"setClassResourceLookup", Function.class);
|
"setClassResourceLookup", Function.class);
|
||||||
ReflectionUtils.makeAccessible(setClassResourceLookupMethod);
|
ReflectionUtils.makeAccessible(setClassResourceLookupMethod);
|
||||||
ReflectionUtils.invokeMethod(setClassResourceLookupMethod,
|
ReflectionUtils.invokeMethod(setClassResourceLookupMethod,
|
||||||
getParent(), (Function<String, byte[]>) this::findClassBytes);
|
getParent(), (Function<String, byte[]>) this::findClassBytes);
|
||||||
this.defineClassMethod = ReflectionUtils.findMethod(parentClass,
|
this.defineClassMethod = lookupMethod(parentClass,
|
||||||
"defineDynamicClass", String.class, byte[].class, int.class, int.class);
|
"defineDynamicClass", String.class, byte[].class, int.class, int.class);
|
||||||
ReflectionUtils.makeAccessible(this.defineClassMethod);
|
ReflectionUtils.makeAccessible(this.defineClassMethod);
|
||||||
this.dynamicClassFiles.forEach((name, file) -> defineClass(name, file.getBytes()));
|
this.dynamicClassFiles.forEach((name, file) -> defineClass(name, file.getBytes()));
|
||||||
|
@ -84,12 +85,13 @@ public class DynamicClassLoader extends ClassLoader {
|
||||||
@Override
|
@Override
|
||||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||||
byte[] bytes = findClassBytes(name);
|
byte[] bytes = findClassBytes(name);
|
||||||
if(bytes != null) {
|
if (bytes != null) {
|
||||||
return defineClass(name, bytes);
|
return defineClass(name, bytes);
|
||||||
}
|
}
|
||||||
return super.findClass(name);
|
return super.findClass(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private byte[] findClassBytes(String name) {
|
private byte[] findClassBytes(String name) {
|
||||||
ClassFile classFile = this.classFiles.get(name);
|
ClassFile classFile = this.classFiles.get(name);
|
||||||
if (classFile != null) {
|
if (classFile != null) {
|
||||||
|
@ -141,6 +143,12 @@ public class DynamicClassLoader extends ClassLoader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Method lookupMethod(Class<?> target, String name, Class<?>... parameterTypes) {
|
||||||
|
Method method = ReflectionUtils.findMethod(target, name, parameterTypes);
|
||||||
|
Assert.notNull(method, "Expected method '" + name + "' on '" + target.getName());
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class SingletonEnumeration<E> implements Enumeration<E> {
|
private static class SingletonEnumeration<E> implements Enumeration<E> {
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
* Assertion methods for {@code DynamicFile} instances.
|
* Assertion methods for {@code DynamicFile} instances.
|
||||||
*
|
*
|
||||||
* @author Phillip Webb
|
* @author Phillip Webb
|
||||||
|
* @author Stephane Nicoll
|
||||||
* @since 6.0
|
* @since 6.0
|
||||||
* @param <A> the assertion type
|
* @param <A> the assertion type
|
||||||
* @param <F> the file type
|
* @param <F> the file type
|
||||||
|
@ -38,25 +39,35 @@ public class DynamicFileAssert<A extends DynamicFileAssert<A, F>, F extends Dyna
|
||||||
super(actual, selfType);
|
super(actual, selfType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that the actual content is equal to the given one.
|
||||||
|
* @param content the expected content of the file
|
||||||
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
*/
|
||||||
|
public A hasContent(@Nullable CharSequence content) {
|
||||||
|
assertThat(this.actual.getContent()).isEqualTo(
|
||||||
|
content != null ? content.toString() : null);
|
||||||
|
return this.myself;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that the actual content contains all the given values.
|
||||||
|
* @param values the values to look for
|
||||||
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
*/
|
||||||
public A contains(CharSequence... values) {
|
public A contains(CharSequence... values) {
|
||||||
assertThat(this.actual.getContent()).contains(values);
|
assertThat(this.actual.getContent()).contains(values);
|
||||||
return this.myself;
|
return this.myself;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify that the actual content does not contain any of the given values.
|
||||||
|
* @param values the values to look for
|
||||||
|
* @return {@code this}, to facilitate method chaining
|
||||||
|
*/
|
||||||
public A doesNotContain(CharSequence... values) {
|
public A doesNotContain(CharSequence... values) {
|
||||||
assertThat(this.actual.getContent()).doesNotContain(values);
|
assertThat(this.actual.getContent()).doesNotContain(values);
|
||||||
return this.myself;
|
return this.myself;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public A isEqualTo(@Nullable Object expected) {
|
|
||||||
if (expected instanceof DynamicFile) {
|
|
||||||
return super.isEqualTo(expected);
|
|
||||||
}
|
|
||||||
assertThat(this.actual.getContent()).isEqualTo(
|
|
||||||
expected != null ? expected.toString() : null);
|
|
||||||
return this.myself;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@ import java.net.URI;
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.SimpleJavaFileObject;
|
import javax.tools.SimpleJavaFileObject;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In-memory {@link JavaFileObject} used to hold generated resource file contents.
|
* In-memory {@link JavaFileObject} used to hold generated resource file contents.
|
||||||
*
|
*
|
||||||
|
@ -35,6 +37,7 @@ import javax.tools.SimpleJavaFileObject;
|
||||||
*/
|
*/
|
||||||
class DynamicResourceFileObject extends SimpleJavaFileObject {
|
class DynamicResourceFileObject extends SimpleJavaFileObject {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
private volatile byte[] bytes;
|
private volatile byte[] bytes;
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,10 +57,11 @@ class DynamicResourceFileObject extends SimpleJavaFileObject {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream openInputStream() throws IOException {
|
public InputStream openInputStream() throws IOException {
|
||||||
if (this.bytes == null) {
|
byte[] content = this.bytes;
|
||||||
|
if (content == null) {
|
||||||
throw new IOException("No data written");
|
throw new IOException("No data written");
|
||||||
}
|
}
|
||||||
return new ByteArrayInputStream(this.bytes);
|
return new ByteArrayInputStream(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -69,6 +73,7 @@ class DynamicResourceFileObject extends SimpleJavaFileObject {
|
||||||
this.bytes = bytes;
|
this.bytes = bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
byte[] getBytes() {
|
byte[] getBytes() {
|
||||||
return this.bytes;
|
return this.bytes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -309,12 +309,12 @@ public final class TestCompiler {
|
||||||
*/
|
*/
|
||||||
public TestCompiler printFiles(PrintStream printStream) {
|
public TestCompiler printFiles(PrintStream printStream) {
|
||||||
for (SourceFile sourceFile : this.sourceFiles) {
|
for (SourceFile sourceFile : this.sourceFiles) {
|
||||||
printStream.append("---- source: " + sourceFile.getPath() + "\n\n");
|
printStream.append("---- source: ").append(sourceFile.getPath()).append("\n\n");
|
||||||
printStream.append(sourceFile.getContent());
|
printStream.append(sourceFile.getContent());
|
||||||
printStream.append("\n\n");
|
printStream.append("\n\n");
|
||||||
}
|
}
|
||||||
for (ResourceFile resourceFile : this.resourceFiles) {
|
for (ResourceFile resourceFile : this.resourceFiles) {
|
||||||
printStream.append("---- resource: " + resourceFile.getPath() + "\n\n");
|
printStream.append("---- resource: ").append(resourceFile.getPath()).append("\n\n");
|
||||||
printStream.append(resourceFile.getContent());
|
printStream.append(resourceFile.getContent());
|
||||||
printStream.append("\n\n");
|
printStream.append("\n\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ class MockSpringFactoriesLoaderTests {
|
||||||
assertThat(factories.get(1)).isInstanceOf(TestFactoryTwo.class);
|
assertThat(factories.get(1)).isInstanceOf(TestFactoryTwo.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
static interface TestFactoryType {
|
interface TestFactoryType {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,13 +65,13 @@ class SourceFileAssertTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void isEqualToWhenEqual() {
|
void isEqualToWhenEqual() {
|
||||||
assertThat(this.sourceFile).isEqualTo(SAMPLE);
|
assertThat(this.sourceFile).hasContent(SAMPLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void isEqualToWhenNotEqualThrowsException() {
|
void isEqualToWhenNotEqualThrowsException() {
|
||||||
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
assertThatExceptionOfType(AssertionError.class).isThrownBy(
|
||||||
() -> assertThat(this.sourceFile).isEqualTo("no")).withMessageContaining(
|
() -> assertThat(this.sourceFile).hasContent("no")).withMessageContaining(
|
||||||
"expected", "but was");
|
"expected", "but was");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue