Merge branch 'gh-29207'

Closes gh-29207
This commit is contained in:
Stephane Nicoll
2022-09-27 10:33:27 +02:00
15 changed files with 142 additions and 116 deletions

View File

@@ -37,6 +37,7 @@ import org.springframework.beans.factory.support.InstanceSupplier;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.ResolvableType;
import org.springframework.javapoet.ClassName;
import org.springframework.javapoet.CodeBlock;
import org.springframework.lang.Nullable;
@@ -108,8 +109,8 @@ class ScopedProxyBeanRegistrationAotProcessor implements BeanRegistrationAotProc
}
@Override
public Class<?> getTarget(RegisteredBean registeredBean, Executable constructorOrFactoryMethod) {
return this.targetBeanDefinition.getResolvableType().toClass();
public ClassName getTarget(RegisteredBean registeredBean, Executable constructorOrFactoryMethod) {
return ClassName.get(this.targetBeanDefinition.getResolvableType().toClass());
}
@Override

View File

@@ -94,9 +94,9 @@ class BeanDefinitionMethodGenerator {
registerRuntimeHintsIfNecessary(generationContext.getRuntimeHints());
BeanRegistrationCodeFragments codeFragments = getCodeFragments(generationContext,
beanRegistrationsCode);
Class<?> target = codeFragments.getTarget(this.registeredBean,
ClassName target = codeFragments.getTarget(this.registeredBean,
this.constructorOrFactoryMethod);
if (!target.getName().startsWith("java.")) {
if (!target.canonicalName().startsWith("java.")) {
GeneratedClass generatedClass = generationContext.getGeneratedClasses()
.getOrAddForFeatureComponent("BeanDefinitions", target, type -> {
type.addJavadoc("Bean definitions for {@link $T}", target);

View File

@@ -26,6 +26,7 @@ import org.springframework.beans.factory.support.InstanceSupplier;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.ResolvableType;
import org.springframework.javapoet.ClassName;
import org.springframework.javapoet.CodeBlock;
/**
@@ -52,9 +53,9 @@ public interface BeanRegistrationCodeFragments {
* the code.
* @param registeredBean the registered bean
* @param constructorOrFactoryMethod the constructor or factory method
* @return the target class
* @return the target {@link ClassName}
*/
Class<?> getTarget(RegisteredBean registeredBean,
ClassName getTarget(RegisteredBean registeredBean,
Executable constructorOrFactoryMethod);
/**

View File

@@ -26,6 +26,7 @@ import org.springframework.aot.generate.MethodReference;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.ResolvableType;
import org.springframework.javapoet.ClassName;
import org.springframework.javapoet.CodeBlock;
import org.springframework.util.Assert;
@@ -51,7 +52,7 @@ public class BeanRegistrationCodeFragmentsDecorator implements BeanRegistrationC
}
@Override
public Class<?> getTarget(RegisteredBean registeredBean,
public ClassName getTarget(RegisteredBean registeredBean,
Executable constructorOrFactoryMethod) {
return this.delegate.getTarget(registeredBean, constructorOrFactoryMethod);

View File

@@ -32,6 +32,7 @@ import org.springframework.beans.factory.support.InstanceSupplier;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.ResolvableType;
import org.springframework.javapoet.ClassName;
import org.springframework.javapoet.CodeBlock;
import org.springframework.javapoet.ParameterizedTypeName;
import org.springframework.lang.Nullable;
@@ -70,7 +71,7 @@ class DefaultBeanRegistrationCodeFragments implements BeanRegistrationCodeFragme
@Override
public Class<?> getTarget(RegisteredBean registeredBean,
public ClassName getTarget(RegisteredBean registeredBean,
Executable constructorOrFactoryMethod) {
Class<?> target = extractDeclaringClass(registeredBean.getBeanType(), constructorOrFactoryMethod);
@@ -79,7 +80,7 @@ class DefaultBeanRegistrationCodeFragments implements BeanRegistrationCodeFragme
Assert.state(parent != null, "No parent available for inner bean");
target = parent.getBeanClass();
}
return target;
return ClassName.get(target);
}
private Class<?> extractDeclaringClass(ResolvableType beanType, Executable executable) {

View File

@@ -33,7 +33,6 @@ import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.generate.MethodReference;
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
import org.springframework.aot.test.generate.TestGenerationContext;
import org.springframework.aot.test.generate.TestTarget;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -97,7 +96,7 @@ class BeanRegistrationsAotContributionTests {
@Test
void applyToWhenHasNameGeneratesPrefixedFeatureName() {
this.generationContext = new TestGenerationContext(
new ClassNameGenerator(TestTarget.class, "Management"));
new ClassNameGenerator(TestGenerationContext.TEST_TARGET, "Management"));
this.beanFactoryInitializationCode = new MockBeanFactoryInitializationCode(this.generationContext);
Map<String, BeanDefinitionMethodGenerator> registrations = new LinkedHashMap<>();
RegisteredBean registeredBean = registerBean(

View File

@@ -34,6 +34,7 @@ import org.springframework.beans.testfixture.beans.factory.aot.SimpleBean;
import org.springframework.beans.testfixture.beans.factory.aot.SimpleBeanConfiguration;
import org.springframework.beans.testfixture.beans.factory.aot.SimpleBeanFactoryBean;
import org.springframework.core.ResolvableType;
import org.springframework.javapoet.ClassName;
import org.springframework.util.ReflectionUtils;
import static org.assertj.core.api.Assertions.assertThat;
@@ -52,45 +53,45 @@ class DefaultBeanRegistrationCodeFragmentsTests {
@Test
void getTargetOnConstructor() {
RegisteredBean registeredBean = registerTestBean(SimpleBean.class);
assertThat(createInstance(registeredBean).getTarget(registeredBean,
SimpleBean.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
assertTarget(createInstance(registeredBean).getTarget(registeredBean,
SimpleBean.class.getDeclaredConstructors()[0]), SimpleBean.class);
}
@Test
void getTargetOnConstructorToPublicFactoryBean() {
RegisteredBean registeredBean = registerTestBean(SimpleBean.class);
assertThat(createInstance(registeredBean).getTarget(registeredBean,
SimpleBeanFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
assertTarget(createInstance(registeredBean).getTarget(registeredBean,
SimpleBeanFactoryBean.class.getDeclaredConstructors()[0]), SimpleBean.class);
}
@Test
void getTargetOnConstructorToPublicGenericFactoryBeanExtractTargetFromFactoryBeanType() {
RegisteredBean registeredBean = registerTestBean(ResolvableType
.forClassWithGenerics(GenericFactoryBean.class, SimpleBean.class));
assertThat(createInstance(registeredBean).getTarget(registeredBean,
GenericFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
assertTarget(createInstance(registeredBean).getTarget(registeredBean,
GenericFactoryBean.class.getDeclaredConstructors()[0]), SimpleBean.class);
}
@Test
void getTargetOnConstructorToPublicGenericFactoryBeanWithBoundExtractTargetFromFactoryBeanType() {
RegisteredBean registeredBean = registerTestBean(ResolvableType
.forClassWithGenerics(NumberFactoryBean.class, Integer.class));
assertThat(createInstance(registeredBean).getTarget(registeredBean,
NumberFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(Integer.class);
assertTarget(createInstance(registeredBean).getTarget(registeredBean,
NumberFactoryBean.class.getDeclaredConstructors()[0]), Integer.class);
}
@Test
void getTargetOnConstructorToPublicGenericFactoryBeanUseBeanTypeAsFallback() {
RegisteredBean registeredBean = registerTestBean(SimpleBean.class);
assertThat(createInstance(registeredBean).getTarget(registeredBean,
GenericFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
assertTarget(createInstance(registeredBean).getTarget(registeredBean,
GenericFactoryBean.class.getDeclaredConstructors()[0]), SimpleBean.class);
}
@Test
void getTargetOnConstructorToProtectedFactoryBean() {
RegisteredBean registeredBean = registerTestBean(SimpleBean.class);
assertThat(createInstance(registeredBean).getTarget(registeredBean,
PrivilegedTestBeanFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(
assertTarget(createInstance(registeredBean).getTarget(registeredBean,
PrivilegedTestBeanFactoryBean.class.getDeclaredConstructors()[0]),
PrivilegedTestBeanFactoryBean.class);
}
@@ -99,8 +100,8 @@ class DefaultBeanRegistrationCodeFragmentsTests {
RegisteredBean registeredBean = registerTestBean(SimpleBean.class);
Method method = ReflectionUtils.findMethod(SimpleBeanConfiguration.class, "simpleBean");
assertThat(method).isNotNull();
assertThat(createInstance(registeredBean).getTarget(registeredBean,
method)).isEqualTo(SimpleBeanConfiguration.class);
assertTarget(createInstance(registeredBean).getTarget(registeredBean, method),
SimpleBeanConfiguration.class);
}
@Test
@@ -110,16 +111,15 @@ class DefaultBeanRegistrationCodeFragmentsTests {
new RootBeanDefinition(String.class));
Method method = ReflectionUtils.findMethod(getClass(), "createString");
assertThat(method).isNotNull();
assertThat(createInstance(innerBean).getTarget(innerBean,
method)).isEqualTo(getClass());
assertTarget(createInstance(innerBean).getTarget(innerBean, method), getClass());
}
@Test
void getTargetOnConstructorWithInnerBeanInJavaPackage() {
RegisteredBean registeredBean = registerTestBean(SimpleBean.class);
RegisteredBean innerBean = RegisteredBean.ofInnerBean(registeredBean, "innerTestBean", new RootBeanDefinition(String.class));
assertThat(createInstance(innerBean).getTarget(innerBean,
String.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
assertTarget(createInstance(innerBean).getTarget(innerBean,
String.class.getDeclaredConstructors()[0]), SimpleBean.class);
}
@Test
@@ -127,8 +127,8 @@ class DefaultBeanRegistrationCodeFragmentsTests {
RegisteredBean registeredBean = registerTestBean(SimpleBean.class);
RegisteredBean innerBean = RegisteredBean.ofInnerBean(registeredBean, "innerTestBean",
new RootBeanDefinition(StringFactoryBean.class));
assertThat(createInstance(innerBean).getTarget(innerBean,
StringFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
assertTarget(createInstance(innerBean).getTarget(innerBean,
StringFactoryBean.class.getDeclaredConstructors()[0]), SimpleBean.class);
}
@Test
@@ -138,8 +138,8 @@ class DefaultBeanRegistrationCodeFragmentsTests {
new RootBeanDefinition(SimpleBean.class));
Method method = ReflectionUtils.findMethod(SimpleBeanConfiguration.class, "simpleBean");
assertThat(method).isNotNull();
assertThat(createInstance(innerBean).getTarget(innerBean, method))
.isEqualTo(SimpleBeanConfiguration.class);
assertTarget(createInstance(innerBean).getTarget(innerBean, method),
SimpleBeanConfiguration.class);
}
@Test
@@ -147,8 +147,8 @@ class DefaultBeanRegistrationCodeFragmentsTests {
RegisteredBean registeredBean = registerTestBean(DummyFactory.class);
RegisteredBean innerBean = RegisteredBean.ofInnerBean(registeredBean, "innerTestBean",
new RootBeanDefinition(SimpleBean.class));
assertThat(createInstance(innerBean).getTarget(innerBean,
SimpleBean.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
assertTarget(createInstance(innerBean).getTarget(innerBean,
SimpleBean.class.getDeclaredConstructors()[0]), SimpleBean.class);
}
@Test
@@ -156,8 +156,12 @@ class DefaultBeanRegistrationCodeFragmentsTests {
RegisteredBean registeredBean = registerTestBean(DummyFactory.class);
RegisteredBean innerBean = RegisteredBean.ofInnerBean(registeredBean, "innerTestBean",
new RootBeanDefinition(SimpleBean.class));
assertThat(createInstance(innerBean).getTarget(innerBean,
SimpleBeanFactoryBean.class.getDeclaredConstructors()[0])).isEqualTo(SimpleBean.class);
assertTarget(createInstance(innerBean).getTarget(innerBean,
SimpleBeanFactoryBean.class.getDeclaredConstructors()[0]), SimpleBean.class);
}
private void assertTarget(ClassName target, Class<?> expected) {
assertThat(target).isEqualTo(ClassName.get(expected));
}

View File

@@ -23,6 +23,7 @@ import org.springframework.aot.generate.DefaultGenerationContext;
import org.springframework.aot.generate.GenerationContext;
import org.springframework.aot.generate.InMemoryGeneratedFiles;
import org.springframework.core.test.tools.TestCompiler;
import org.springframework.javapoet.ClassName;
/**
* {@link GenerationContext} test implementation that uses
@@ -35,6 +36,11 @@ import org.springframework.core.test.tools.TestCompiler;
*/
public class TestGenerationContext extends DefaultGenerationContext implements UnaryOperator<TestCompiler> {
/**
* The default test target {@link ClassName}.
*/
public static final ClassName TEST_TARGET = ClassName.get("com.example", "TestTarget");
/**
* Create an instance using the specified {@link ClassNameGenerator}.
* @param classNameGenerator the class name generator to use
@@ -47,15 +53,15 @@ public class TestGenerationContext extends DefaultGenerationContext implements U
* Create an instance using the specified {@code target}.
* @param target the default target class to use
*/
public TestGenerationContext(Class<?> target) {
public TestGenerationContext(ClassName target) {
this(new ClassNameGenerator(target));
}
/**
* Create an instance using {@link TestTarget} as the {@code target}.
* Create an instance using {@link #TEST_TARGET} as the {@code target}.
*/
public TestGenerationContext() {
this(TestTarget.class);
this(TEST_TARGET);
}

View File

@@ -1,26 +0,0 @@
/*
* 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;
/**
* A <em>default target class</em> used by tests of code generation.
*
* @author Stephane Nicoll
* @since 6.0
*/
public class TestTarget {
}

View File

@@ -27,8 +27,8 @@ import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Generate unique class names based on a target {@link Class} and a feature
* name.
* Generate unique class names based on a target {@link ClassName} and a
* feature name.
*
* <p>This class is stateful, so the same instance should be used for all name
* generation.
@@ -43,7 +43,7 @@ public final class ClassNameGenerator {
private static final String AOT_FEATURE = "Aot";
private final Class<?> defaultTarget;
private final ClassName defaultTarget;
private final String featureNamePrefix;
@@ -55,7 +55,7 @@ public final class ClassNameGenerator {
* feature name prefix.
* @param defaultTarget the default target class to use
*/
public ClassNameGenerator(Class<?> defaultTarget) {
public ClassNameGenerator(ClassName defaultTarget) {
this(defaultTarget, "");
}
@@ -65,11 +65,11 @@ public final class ClassNameGenerator {
* @param defaultTarget the default target class to use
* @param featureNamePrefix the prefix to use to qualify feature names
*/
public ClassNameGenerator(Class<?> defaultTarget, String featureNamePrefix) {
public ClassNameGenerator(ClassName defaultTarget, String featureNamePrefix) {
this(defaultTarget, featureNamePrefix, new ConcurrentHashMap<>());
}
private ClassNameGenerator(Class<?> defaultTarget, String featureNamePrefix,
private ClassNameGenerator(ClassName defaultTarget, String featureNamePrefix,
Map<String, AtomicInteger> sequenceGenerator) {
Assert.notNull(defaultTarget, "'defaultTarget' must not be null");
this.defaultTarget = defaultTarget;
@@ -98,16 +98,16 @@ public final class ClassNameGenerator {
* {@code null} to use the main target
* @return a unique generated class name
*/
public ClassName generateClassName(String featureName, @Nullable Class<?> target) {
public ClassName generateClassName(String featureName, @Nullable ClassName target) {
return generateSequencedClassName(getRootName(featureName, target));
}
private String getRootName(String featureName, @Nullable Class<?> target) {
private String getRootName(String featureName, @Nullable ClassName target) {
Assert.hasLength(featureName, "'featureName' must not be empty");
featureName = clean(featureName);
Class<?> targetToUse = (target != null ? target : this.defaultTarget);
ClassName targetToUse = (target != null ? target : this.defaultTarget);
String featureNameToUse = this.featureNamePrefix + featureName;
return targetToUse.getName().replace("$", "_") + SEPARATOR + StringUtils.capitalize(featureNameToUse);
return toName(targetToUse).replace("$", "_") + SEPARATOR + StringUtils.capitalize(featureNameToUse);
}
private String clean(String name) {
@@ -147,4 +147,8 @@ public final class ClassNameGenerator {
this.sequenceGenerator);
}
private static String toName(ClassName className) {
return GeneratedTypeReference.of(className).getName();
}
}

View File

@@ -99,7 +99,7 @@ public class GeneratedClasses {
* @return an existing or newly generated class
*/
public GeneratedClass getOrAddForFeatureComponent(String featureName,
Class<?> targetComponent, Consumer<TypeSpec.Builder> type) {
ClassName targetComponent, Consumer<TypeSpec.Builder> type) {
Assert.hasLength(featureName, "'featureName' must not be empty");
Assert.notNull(targetComponent, "'targetComponent' must not be null");
@@ -111,6 +111,24 @@ public class GeneratedClasses {
return generatedClass;
}
/**
* Get or add a generated class for the specified {@code featureName}
* targeting the specified {@code component}. If this method has previously
* been called with the given {@code featureName}/{@code target} the
* existing class will be returned, otherwise a new class will be generated,
* otherwise a new class will be generated.
* @param featureName the name of the feature to associate with the
* generated class
* @param targetComponent the target component
* @param type a {@link Consumer} used to build the type
* @return an existing or newly generated class
*/
public GeneratedClass getOrAddForFeatureComponent(String featureName,
Class<?> targetComponent, Consumer<TypeSpec.Builder> type) {
return getOrAddForFeatureComponent(featureName, ClassName.get(targetComponent), type);
}
/**
* Add a new generated class for the specified {@code featureName} and no
* particular component.
@@ -135,7 +153,7 @@ public class GeneratedClasses {
* @return the newly generated class
*/
public GeneratedClass addForFeatureComponent(String featureName,
Class<?> targetComponent, Consumer<TypeSpec.Builder> type) {
ClassName targetComponent, Consumer<TypeSpec.Builder> type) {
Assert.hasLength(featureName, "'featureName' must not be empty");
Assert.notNull(targetComponent, "'targetComponent' must not be null");
@@ -143,8 +161,23 @@ public class GeneratedClasses {
return createAndAddGeneratedClass(featureName, targetComponent, type);
}
/**
* Add a new generated class for the specified {@code featureName} targeting
* the specified {@code component}.
* @param featureName the name of the feature to associate with the
* generated class
* @param targetComponent the target component
* @param type a {@link Consumer} used to build the type
* @return the newly generated class
*/
public GeneratedClass addForFeatureComponent(String featureName,
Class<?> targetComponent, Consumer<TypeSpec.Builder> type) {
return addForFeatureComponent(featureName, ClassName.get(targetComponent), type);
}
private GeneratedClass createAndAddGeneratedClass(String featureName,
@Nullable Class<?> targetComponent, Consumer<TypeSpec.Builder> type) {
@Nullable ClassName targetComponent, Consumer<TypeSpec.Builder> type) {
ClassName className = this.classNameGenerator.generateClassName(featureName, targetComponent);
GeneratedClass generatedClass = new GeneratedClass(className, type);
@@ -171,7 +204,7 @@ public class GeneratedClasses {
this.classes, this.classesByOwner);
}
private record Owner(String featureNamePrefix, String featureName, @Nullable Class<?> target) {
private record Owner(String featureNamePrefix, String featureName, @Nullable ClassName target) {
}
}

View File

@@ -32,71 +32,69 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
*/
class ClassNameGeneratorTests {
private final ClassNameGenerator generator = new ClassNameGenerator(Object.class);
private static final ClassName TEST_TARGET = ClassName.get("com.example", "Test");
private final ClassNameGenerator generator = new ClassNameGenerator(TEST_TARGET);
@Test
void generateClassNameWhenTargetClassIsNullUsesMainTarget() {
ClassName generated = this.generator.generateClassName("test", null);
assertThat(generated).hasToString("java.lang.Object__Test");
assertThat(generated).hasToString("com.example.Test__Test");
}
@Test
void generateClassNameUseFeatureNamePrefix() {
ClassName generated = new ClassNameGenerator(Object.class, "One")
.generateClassName("test", InputStream.class);
ClassName generated = new ClassNameGenerator(TEST_TARGET, "One")
.generateClassName("test", ClassName.get(InputStream.class));
assertThat(generated).hasToString("java.io.InputStream__OneTest");
}
@Test
void generateClassNameWithNoTextFeatureNamePrefix() {
ClassName generated = new ClassNameGenerator(Object.class, " ")
.generateClassName("test", InputStream.class);
ClassName generated = new ClassNameGenerator(TEST_TARGET, " ")
.generateClassName("test", ClassName.get(InputStream.class));
assertThat(generated).hasToString("java.io.InputStream__Test");
}
@Test
void generatedClassNameWhenFeatureIsEmptyThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.generator.generateClassName("", InputStream.class))
.isThrownBy(() -> this.generator.generateClassName("", ClassName.get(InputStream.class)))
.withMessage("'featureName' must not be empty");
}
@Test
void generatedClassNameWhenFeatureIsNotAllLettersThrowsException() {
assertThat(this.generator.generateClassName("name!", InputStream.class))
assertThat(this.generator.generateClassName("name!", ClassName.get(InputStream.class)))
.hasToString("java.io.InputStream__Name");
assertThat(this.generator.generateClassName("1NameHere", InputStream.class))
assertThat(this.generator.generateClassName("1NameHere", ClassName.get(InputStream.class)))
.hasToString("java.io.InputStream__NameHere");
assertThat(this.generator.generateClassName("Y0pe", InputStream.class))
assertThat(this.generator.generateClassName("Y0pe", ClassName.get(InputStream.class)))
.hasToString("java.io.InputStream__YPe");
}
@Test
void generateClassNameWithClassWhenLowercaseFeatureNameGeneratesName() {
ClassName generated = this.generator.generateClassName("bytes", InputStream.class);
ClassName generated = this.generator.generateClassName("bytes", ClassName.get(InputStream.class));
assertThat(generated).hasToString("java.io.InputStream__Bytes");
}
@Test
void generateClassNameWithClassWhenInnerClassGeneratesName() {
ClassName generated = this.generator.generateClassName("EventListener", TestBean.class);
ClassName innerBean = ClassName.get("com.example", "Test", "InnerBean");
ClassName generated = this.generator.generateClassName("EventListener", innerBean);
assertThat(generated)
.hasToString("org.springframework.aot.generate.ClassNameGeneratorTests_TestBean__EventListener");
.hasToString("com.example.Test_InnerBean__EventListener");
}
@Test
void generateClassWithClassWhenMultipleCallsGeneratesSequencedName() {
ClassName generated1 = this.generator.generateClassName("bytes", InputStream.class);
ClassName generated2 = this.generator.generateClassName("bytes", InputStream.class);
ClassName generated3 = this.generator.generateClassName("bytes", InputStream.class);
ClassName generated1 = this.generator.generateClassName("bytes",ClassName.get(InputStream.class));
ClassName generated2 = this.generator.generateClassName("bytes", ClassName.get(InputStream.class));
ClassName generated3 = this.generator.generateClassName("bytes", ClassName.get(InputStream.class));
assertThat(generated1).hasToString("java.io.InputStream__Bytes");
assertThat(generated2).hasToString("java.io.InputStream__Bytes1");
assertThat(generated3).hasToString("java.io.InputStream__Bytes2");
}
static class TestBean {
}
}

View File

@@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.aot.generate.GeneratedFiles.Kind;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.javapoet.ClassName;
import org.springframework.javapoet.TypeSpec;
import static org.assertj.core.api.Assertions.assertThat;
@@ -35,10 +36,12 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
*/
class DefaultGenerationContextTests {
private static final ClassName SAMPLE_TARGET = ClassName.get("com.example", "SampleTarget");
private static final Consumer<TypeSpec.Builder> typeSpecCustomizer = type -> {};
private final GeneratedClasses generatedClasses = new GeneratedClasses(
new ClassNameGenerator(SampleTarget.class));
new ClassNameGenerator(SAMPLE_TARGET));
private final InMemoryGeneratedFiles generatedFiles = new InMemoryGeneratedFiles();
@@ -48,7 +51,7 @@ class DefaultGenerationContextTests {
@Test
void createWithOnlyGeneratedFilesCreatesContext() {
DefaultGenerationContext context = new DefaultGenerationContext(
new ClassNameGenerator(SampleTarget.class), this.generatedFiles);
new ClassNameGenerator(SAMPLE_TARGET), this.generatedFiles);
assertThat(context.getGeneratedFiles()).isSameAs(this.generatedFiles);
assertThat(context.getRuntimeHints()).isInstanceOf(RuntimeHints.class);
}
@@ -109,7 +112,7 @@ class DefaultGenerationContextTests {
@Test
void withNameUpdateNamingConvention() {
DefaultGenerationContext context = new DefaultGenerationContext(
new ClassNameGenerator(SampleTarget.class), this.generatedFiles);
new ClassNameGenerator(SAMPLE_TARGET), this.generatedFiles);
GenerationContext anotherContext = context.withName("Another");
GeneratedClass generatedClass = anotherContext.getGeneratedClasses()
.addForFeature("Test", typeSpecCustomizer);
@@ -119,7 +122,7 @@ class DefaultGenerationContextTests {
@Test
void withNameKeepsTrackOfAllGeneratedFiles() {
DefaultGenerationContext context = new DefaultGenerationContext(
new ClassNameGenerator(SampleTarget.class), this.generatedFiles);
new ClassNameGenerator(SAMPLE_TARGET), this.generatedFiles);
context.getGeneratedClasses().addForFeature("Test", typeSpecCustomizer);
GenerationContext anotherContext = context.withName("Another");
assertThat(anotherContext.getGeneratedClasses()).isNotSameAs(context.getGeneratedClasses());
@@ -133,7 +136,7 @@ class DefaultGenerationContextTests {
@Test
void withNameGeneratesUniqueName() {
DefaultGenerationContext context = new DefaultGenerationContext(
new ClassNameGenerator(Object.class), this.generatedFiles);
new ClassNameGenerator(SAMPLE_TARGET), this.generatedFiles);
context.withName("Test").getGeneratedClasses()
.addForFeature("Feature", typeSpecCustomizer);
context.withName("Test").getGeneratedClasses()
@@ -142,11 +145,9 @@ class DefaultGenerationContextTests {
.addForFeature("Feature", typeSpecCustomizer);
context.writeGeneratedContent();
assertThat(this.generatedFiles.getGeneratedFiles(Kind.SOURCE)).containsOnlyKeys(
"java/lang/Object__TestFeature.java",
"java/lang/Object__Test1Feature.java",
"java/lang/Object__Test2Feature.java");
"com/example/SampleTarget__TestFeature.java",
"com/example/SampleTarget__Test1Feature.java",
"com/example/SampleTarget__Test2Feature.java");
}
static class SampleTarget {}
}

View File

@@ -22,6 +22,7 @@ import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
import org.springframework.aot.generate.GeneratedFiles.Kind;
import org.springframework.javapoet.ClassName;
import org.springframework.javapoet.TypeSpec;
import static org.assertj.core.api.Assertions.assertThat;
@@ -42,7 +43,7 @@ class GeneratedClassesTests {
private static final Consumer<TypeSpec.Builder> emptyTypeCustomizer = type -> {};
private final GeneratedClasses generatedClasses = new GeneratedClasses(
new ClassNameGenerator(Object.class));
new ClassNameGenerator(ClassName.get("com.example", "Test")));
@Test
void createWhenClassNameGeneratorIsNullThrowsException() {
@@ -76,7 +77,7 @@ class GeneratedClassesTests {
@Test
void addForFeatureUsesDefaultTarget() {
GeneratedClass generatedClass = this.generatedClasses.addForFeature("Test", emptyTypeCustomizer);
assertThat(generatedClass.getName()).hasToString("java.lang.Object__Test");
assertThat(generatedClass.getName()).hasToString("com.example.Test__Test");
}
@Test

View File

@@ -234,7 +234,7 @@ public class TestContextAotGenerator {
}
DefaultGenerationContext createGenerationContext(Class<?> testClass) {
ClassNameGenerator classNameGenerator = new ClassNameGenerator(testClass);
ClassNameGenerator classNameGenerator = new ClassNameGenerator(ClassName.get(testClass));
DefaultGenerationContext generationContext =
new DefaultGenerationContext(classNameGenerator, this.generatedFiles, this.runtimeHints);
return generationContext.withName(nextTestContextId());
@@ -245,7 +245,8 @@ public class TestContextAotGenerator {
}
private void generateTestAotMappings(MultiValueMap<ClassName, Class<?>> initializerClassMappings) {
ClassNameGenerator classNameGenerator = new ClassNameGenerator(AotTestContextInitializers.class);
ClassNameGenerator classNameGenerator = new ClassNameGenerator(
ClassName.get(AotTestContextInitializers.class));
DefaultGenerationContext generationContext =
new DefaultGenerationContext(classNameGenerator, this.generatedFiles, this.runtimeHints);
GeneratedClasses generatedClasses = generationContext.getGeneratedClasses();
@@ -258,7 +259,8 @@ public class TestContextAotGenerator {
}
private void generateAotTestAttributes() {
ClassNameGenerator classNameGenerator = new ClassNameGenerator(AotTestAttributes.class);
ClassNameGenerator classNameGenerator = new ClassNameGenerator(
ClassName.get(AotTestAttributes.class));
DefaultGenerationContext generationContext =
new DefaultGenerationContext(classNameGenerator, this.generatedFiles, this.runtimeHints);
GeneratedClasses generatedClasses = generationContext.getGeneratedClasses();