Migrate AOT tests to use GeneratedClasses and refine/polish AOT APIs

Migrate all AOT tests to make use of `GeneratedClasses` rather than
directly generating Java files. This commit also refines and polishes
AOT APIs to being greater consistency.

Specifically:

	- The `MethodGenerator` interface has been removed in favor of
	  working directly with `GeneratedMethods`.
	- The visibility of several constructors and methods has been
	  reduced to package-private.
	- The `using(...)` and `builder` methods have been removed in
	  favor of setting the `Consumer` callbacks directly as
	  constructor arguments.
	- Variable names for builders are now named `type` or `method`
	  depending on what they're building.

Closes gh-28831
This commit is contained in:
Phillip Webb
2022-06-23 13:48:38 -07:00
parent 4f8516e2c3
commit f2d31b7a20
51 changed files with 1255 additions and 1399 deletions

View File

@@ -36,72 +36,64 @@ class ClassNameGeneratorTests {
@Test
void generateClassNameWhenTargetClassIsNullUsesMainTarget() {
ClassName generated = this.generator.generateClassName(null, "test");
ClassName generated = this.generator.generateClassName("test", null);
assertThat(generated).hasToString("java.lang.Object__Test");
}
@Test
void generateClassNameUseFeatureNamePrefix() {
ClassName generated = new ClassNameGenerator(Object.class, "One")
.generateClassName(InputStream.class, "test");
.generateClassName("test", InputStream.class);
assertThat(generated).hasToString("java.io.InputStream__OneTest");
}
@Test
void generateClassNameWithNoTextFeatureNamePrefix() {
ClassName generated = new ClassNameGenerator(Object.class, " ")
.generateClassName(InputStream.class, "test");
.generateClassName("test", InputStream.class);
assertThat(generated).hasToString("java.io.InputStream__Test");
}
@Test
void generatedClassNameWhenFeatureIsEmptyThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.generator.generateClassName(InputStream.class, ""))
.isThrownBy(() -> this.generator.generateClassName("", InputStream.class))
.withMessage("'featureName' must not be empty");
}
@Test
void generatedClassNameWhenFeatureIsNotAllLettersThrowsException() {
assertThat(this.generator.generateClassName(InputStream.class, "name!"))
assertThat(this.generator.generateClassName("name!", InputStream.class))
.hasToString("java.io.InputStream__Name");
assertThat(this.generator.generateClassName(InputStream.class, "1NameHere"))
assertThat(this.generator.generateClassName("1NameHere", InputStream.class))
.hasToString("java.io.InputStream__NameHere");
assertThat(this.generator.generateClassName(InputStream.class, "Y0pe"))
assertThat(this.generator.generateClassName("Y0pe", InputStream.class))
.hasToString("java.io.InputStream__YPe");
}
@Test
void generateClassNameWithClassWhenLowercaseFeatureNameGeneratesName() {
ClassName generated = this.generator.generateClassName(InputStream.class, "bytes");
ClassName generated = this.generator.generateClassName("bytes", InputStream.class);
assertThat(generated).hasToString("java.io.InputStream__Bytes");
}
@Test
void generateClassNameWithClassWhenInnerClassGeneratesName() {
ClassName generated = this.generator.generateClassName(TestBean.class, "EventListener");
ClassName generated = this.generator.generateClassName("EventListener", TestBean.class);
assertThat(generated)
.hasToString("org.springframework.aot.generate.ClassNameGeneratorTests_TestBean__EventListener");
}
@Test
void generateClassWithClassWhenMultipleCallsGeneratesSequencedName() {
ClassName generated1 = this.generator.generateClassName(InputStream.class, "bytes");
ClassName generated2 = this.generator.generateClassName(InputStream.class, "bytes");
ClassName generated3 = this.generator.generateClassName(InputStream.class, "bytes");
ClassName generated1 = this.generator.generateClassName("bytes", InputStream.class);
ClassName generated2 = this.generator.generateClassName("bytes", InputStream.class);
ClassName generated3 = this.generator.generateClassName("bytes", InputStream.class);
assertThat(generated1).hasToString("java.io.InputStream__Bytes");
assertThat(generated2).hasToString("java.io.InputStream__Bytes1");
assertThat(generated3).hasToString("java.io.InputStream__Bytes2");
}
@Test
void getClassNameWhenMultipleCallsReturnsSameName() {
String name1 = this.generator.getClassName(InputStream.class, "bytes");
String name2 = this.generator.getClassName(InputStream.class, "bytes");
String name3 = this.generator.getClassName(InputStream.class, "bytes");
assertThat(name1).hasToString("java.io.InputStream__Bytes")
.isEqualTo(name2).isEqualTo(name3);
}
static class TestBean {

View File

@@ -23,7 +23,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.aot.generate.GeneratedFiles.Kind;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.core.testfixture.aot.generate.TestTarget;
import org.springframework.javapoet.TypeSpec.Builder;
import org.springframework.javapoet.TypeSpec;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -36,7 +36,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
*/
class DefaultGenerationContextTests {
private static final Consumer<Builder> typeSpecCustomizer = type -> {};
private static final Consumer<TypeSpec.Builder> typeSpecCustomizer = type -> {};
private final GeneratedClasses generatedClasses = new GeneratedClasses(
new ClassNameGenerator(TestTarget.class));
@@ -113,34 +113,34 @@ class DefaultGenerationContextTests {
new ClassNameGenerator(TestTarget.class), this.generatedFiles);
GenerationContext anotherContext = context.withName("Another");
GeneratedClass generatedClass = anotherContext.getGeneratedClasses()
.forFeature("Test").generate(typeSpecCustomizer);
.addForFeature("Test", typeSpecCustomizer);
assertThat(generatedClass.getName().simpleName()).endsWith("__AnotherTest");
}
@Test
void withNameKeepTrackOfAllGeneratedFiles() {
void withNameKeepsTrackOfAllGeneratedFiles() {
DefaultGenerationContext context = new DefaultGenerationContext(
new ClassNameGenerator(TestTarget.class), this.generatedFiles);
context.getGeneratedClasses().forFeature("Test").generate(typeSpecCustomizer);
context.getGeneratedClasses().addForFeature("Test", typeSpecCustomizer);
GenerationContext anotherContext = context.withName("Another");
assertThat(anotherContext.getGeneratedClasses()).isNotSameAs(context.getGeneratedClasses());
assertThat(anotherContext.getGeneratedFiles()).isSameAs(context.getGeneratedFiles());
assertThat(anotherContext.getRuntimeHints()).isSameAs(context.getRuntimeHints());
anotherContext.getGeneratedClasses().forFeature("Test").generate(typeSpecCustomizer);
anotherContext.getGeneratedClasses().addForFeature("Test", typeSpecCustomizer);
context.writeGeneratedContent();
assertThat(this.generatedFiles.getGeneratedFiles(Kind.SOURCE)).hasSize(2);
}
@Test
void withNameGenerateUniqueName() {
void withNameGeneratesUniqueName() {
DefaultGenerationContext context = new DefaultGenerationContext(
new ClassNameGenerator(Object.class), this.generatedFiles);
context.withName("Test").getGeneratedClasses()
.forFeature("Feature").generate(typeSpecCustomizer);
.addForFeature("Feature", typeSpecCustomizer);
context.withName("Test").getGeneratedClasses()
.forFeature("Feature").generate(typeSpecCustomizer);
.addForFeature("Feature", typeSpecCustomizer);
context.withName("Test").getGeneratedClasses()
.forFeature("Feature").generate(typeSpecCustomizer);
.addForFeature("Feature", typeSpecCustomizer);
context.writeGeneratedContent();
assertThat(this.generatedFiles.getGeneratedFiles(Kind.SOURCE)).containsOnlyKeys(
"java/lang/Object__TestFeature.java",

View File

@@ -21,9 +21,11 @@ import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
import org.springframework.javapoet.ClassName;
import org.springframework.javapoet.TypeSpec.Builder;
import org.springframework.javapoet.MethodSpec;
import org.springframework.javapoet.TypeSpec;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link GeneratedClass}.
@@ -33,26 +35,49 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
class GeneratedClassTests {
private static final Consumer<TypeSpec.Builder> emptyTypeCustomizer = type -> {};
private static final Consumer<MethodSpec.Builder> emptyMethodCustomizer = method -> {};
@Test
void getNameReturnsName() {
ClassName name = ClassName.bestGuess("com.example.Test");
GeneratedClass generatedClass = new GeneratedClass(emptyTypeSpec(), name);
GeneratedClass generatedClass = new GeneratedClass(name, emptyTypeCustomizer);
assertThat(generatedClass.getName()).isSameAs(name);
}
@Test
void reserveMethodNamesWhenNameUsedThrowsException() {
ClassName name = ClassName.bestGuess("com.example.Test");
GeneratedClass generatedClass = new GeneratedClass(name, emptyTypeCustomizer);
generatedClass.getMethods().add("apply", emptyMethodCustomizer);
assertThatIllegalStateException()
.isThrownBy(() -> generatedClass.reserveMethodNames("apply"));
}
@Test
void reserveMethodNamesReservesNames() {
ClassName name = ClassName.bestGuess("com.example.Test");
GeneratedClass generatedClass = new GeneratedClass(name, emptyTypeCustomizer);
generatedClass.reserveMethodNames("apply");
GeneratedMethod generatedMethod = generatedClass.getMethods().add("apply", emptyMethodCustomizer);
assertThat(generatedMethod.getName()).isEqualTo("apply1");
}
@Test
void generateMethodNameWhenAllEmptyPartsGeneratesSetName() {
ClassName name = ClassName.bestGuess("com.example.Test");
GeneratedClass generatedClass = new GeneratedClass(name, emptyTypeCustomizer);
GeneratedMethod generatedMethod = generatedClass.getMethods().add("123", emptyMethodCustomizer);
assertThat(generatedMethod.getName()).isEqualTo("$$aot");
}
@Test
void generateJavaFileIncludesGeneratedMethods() {
ClassName name = ClassName.bestGuess("com.example.Test");
GeneratedClass generatedClass = new GeneratedClass(emptyTypeSpec(), name);
MethodGenerator methodGenerator = generatedClass.getMethodGenerator();
methodGenerator.generateMethod("test")
.using(builder -> builder.addJavadoc("Test Method"));
GeneratedClass generatedClass = new GeneratedClass(name, emptyTypeCustomizer);
generatedClass.getMethods().add("test", method -> method.addJavadoc("Test Method"));
assertThat(generatedClass.generateJavaFile().toString()).contains("Test Method");
}
private Consumer<Builder> emptyTypeSpec() {
return type -> {};
}
}

View File

@@ -23,7 +23,6 @@ import org.junit.jupiter.api.Test;
import org.springframework.aot.generate.GeneratedFiles.Kind;
import org.springframework.javapoet.TypeSpec;
import org.springframework.javapoet.TypeSpec.Builder;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
@@ -52,93 +51,112 @@ class GeneratedClassesTests {
}
@Test
void forFeatureComponentWhenTargetIsNullThrowsException() {
void addForFeatureComponentWhenFeatureNameIsEmptyThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.generatedClasses.forFeatureComponent("test", null))
.withMessage("'component' must not be null");
}
@Test
void forFeatureComponentWhenFeatureNameIsEmptyThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.generatedClasses.forFeatureComponent("", TestComponent.class))
.isThrownBy(() -> this.generatedClasses.addForFeatureComponent("",
TestComponent.class, emptyTypeCustomizer))
.withMessage("'featureName' must not be empty");
}
@Test
void forFeatureWhenFeatureNameIsEmptyThrowsException() {
void addForFeatureWhenFeatureNameIsEmptyThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.generatedClasses.forFeature(""))
.isThrownBy(() -> this.generatedClasses.addForFeature("", emptyTypeCustomizer))
.withMessage("'featureName' must not be empty");
}
@Test
void generateWhenTypeSpecCustomizerIsNullThrowsException() {
void addForFeatureComponentWhenTypeSpecCustomizerIsNullThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> this.generatedClasses
.forFeatureComponent("test", TestComponent.class).generate(null))
.withMessage("'typeSpecCustomizer' must not be null");
.addForFeatureComponent("test", TestComponent.class, null))
.withMessage("'type' must not be null");
}
@Test
void forFeatureUsesDefaultTarget() {
GeneratedClass generatedClass = this.generatedClasses
.forFeature("Test").generate(emptyTypeCustomizer);
void addForFeatureUsesDefaultTarget() {
GeneratedClass generatedClass = this.generatedClasses.addForFeature("Test", emptyTypeCustomizer);
assertThat(generatedClass.getName()).hasToString("java.lang.Object__Test");
}
@Test
void forFeatureComponentUsesComponent() {
void addForFeatureComponentUsesTarget() {
GeneratedClass generatedClass = this.generatedClasses
.forFeatureComponent("Test", TestComponent.class).generate(emptyTypeCustomizer);
.addForFeatureComponent("Test", TestComponent.class, emptyTypeCustomizer);
assertThat(generatedClass.getName().toString()).endsWith("TestComponent__Test");
}
@Test
void generateReturnsDifferentInstances() {
Consumer<Builder> typeCustomizer = mockTypeCustomizer();
void addForFeatureComponentWithSameNameReturnsDifferentInstances() {
GeneratedClass generatedClass1 = this.generatedClasses
.forFeatureComponent("one", TestComponent.class).generate(typeCustomizer);
.addForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
GeneratedClass generatedClass2 = this.generatedClasses
.forFeatureComponent("one", TestComponent.class).generate(typeCustomizer);
.addForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
assertThat(generatedClass1).isNotSameAs(generatedClass2);
assertThat(generatedClass1.getName().simpleName()).endsWith("__One");
assertThat(generatedClass2.getName().simpleName()).endsWith("__One1");
}
@Test
void getOrGenerateWhenNewReturnsGeneratedMethod() {
Consumer<Builder> typeCustomizer = mockTypeCustomizer();
void getOrAddForFeatureComponentWhenNewReturnsGeneratedMethod() {
GeneratedClass generatedClass1 = this.generatedClasses
.forFeatureComponent("one", TestComponent.class).getOrGenerate("facet", typeCustomizer);
.getOrAddForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
GeneratedClass generatedClass2 = this.generatedClasses
.forFeatureComponent("two", TestComponent.class).getOrGenerate("facet", typeCustomizer);
.getOrAddForFeatureComponent("two", TestComponent.class, emptyTypeCustomizer);
assertThat(generatedClass1).isNotNull().isNotEqualTo(generatedClass2);
assertThat(generatedClass2).isNotNull();
}
@Test
void getOrGenerateWhenRepeatReturnsSameGeneratedMethod() {
Consumer<Builder> typeCustomizer = mockTypeCustomizer();
void getOrAddForFeatureWhenNewReturnsGeneratedMethod() {
GeneratedClass generatedClass1 = this.generatedClasses
.forFeatureComponent("one", TestComponent.class).getOrGenerate("facet", typeCustomizer);
.getOrAddForFeature("one", emptyTypeCustomizer);
GeneratedClass generatedClass2 = this.generatedClasses
.forFeatureComponent("one", TestComponent.class).getOrGenerate("facet", typeCustomizer);
.getOrAddForFeature("two", emptyTypeCustomizer);
assertThat(generatedClass1).isNotNull().isNotEqualTo(generatedClass2);
assertThat(generatedClass2).isNotNull();
}
@Test
void getOrAddForFeatureComponentWhenRepeatReturnsSameGeneratedMethod() {
GeneratedClass generatedClass1 = this.generatedClasses
.getOrAddForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
GeneratedClass generatedClass2 = this.generatedClasses
.getOrAddForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
GeneratedClass generatedClass3 = this.generatedClasses
.forFeatureComponent("one", TestComponent.class).getOrGenerate("facet", typeCustomizer);
.getOrAddForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
assertThat(generatedClass1).isNotNull().isSameAs(generatedClass2)
.isSameAs(generatedClass3);
verifyNoInteractions(typeCustomizer);
generatedClass1.generateJavaFile();
verify(typeCustomizer).accept(any());
}
@Test
void getOrAddForFeatureWhenRepeatReturnsSameGeneratedMethod() {
GeneratedClass generatedClass1 = this.generatedClasses
.getOrAddForFeature("one", emptyTypeCustomizer);
GeneratedClass generatedClass2 = this.generatedClasses
.getOrAddForFeature("one", emptyTypeCustomizer);
GeneratedClass generatedClass3 = this.generatedClasses
.getOrAddForFeature("one", emptyTypeCustomizer);
assertThat(generatedClass1).isNotNull().isSameAs(generatedClass2)
.isSameAs(generatedClass3);
}
@Test
void getOrAddForFeatureComponentWhenHasFeatureNamePrefix() {
GeneratedClasses prefixed = this.generatedClasses.withFeatureNamePrefix("prefix");
GeneratedClass generatedClass1 = this.generatedClasses.getOrAddForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
GeneratedClass generatedClass2 = this.generatedClasses.getOrAddForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
GeneratedClass generatedClass3 = prefixed.getOrAddForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
GeneratedClass generatedClass4 = prefixed.getOrAddForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
assertThat(generatedClass1).isSameAs(generatedClass2).isNotSameAs(generatedClass3);
assertThat(generatedClass3).isSameAs(generatedClass4);
}
@Test
@SuppressWarnings("unchecked")
void writeToInvokeTypeSpecCustomizer() throws IOException {
Consumer<TypeSpec.Builder> typeSpecCustomizer = mock(Consumer.class);
this.generatedClasses.forFeatureComponent("one", TestComponent.class)
.generate(typeSpecCustomizer);
this.generatedClasses.addForFeatureComponent("one", TestComponent.class, typeSpecCustomizer);
verifyNoInteractions(typeSpecCustomizer);
InMemoryGeneratedFiles generatedFiles = new InMemoryGeneratedFiles();
this.generatedClasses.writeTo(generatedFiles);
@@ -149,20 +167,14 @@ class GeneratedClassesTests {
@Test
void withNameUpdatesNamingConventions() {
GeneratedClass generatedClass1 = this.generatedClasses
.forFeatureComponent("one", TestComponent.class).generate(emptyTypeCustomizer);
GeneratedClass generatedClass2 = this.generatedClasses.withName("Another")
.forFeatureComponent("one", TestComponent.class).generate(emptyTypeCustomizer);
.addForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
GeneratedClass generatedClass2 = this.generatedClasses.withFeatureNamePrefix("Another")
.addForFeatureComponent("one", TestComponent.class, emptyTypeCustomizer);
assertThat(generatedClass1.getName().toString()).endsWith("TestComponent__One");
assertThat(generatedClass2.getName().toString()).endsWith("TestComponent__AnotherOne");
}
@SuppressWarnings("unchecked")
private Consumer<TypeSpec.Builder> mockTypeCustomizer() {
return mock(Consumer.class);
}
private static class TestComponent {
}

View File

@@ -16,12 +16,13 @@
package org.springframework.aot.generate;
import javax.lang.model.element.Modifier;
import java.util.function.Consumer;
import org.junit.jupiter.api.Test;
import org.springframework.javapoet.MethodSpec;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
@@ -31,42 +32,27 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
*/
class GeneratedMethodTests {
private static final Consumer<MethodSpec.Builder> methodSpecCustomizer = method -> {};
private static final String NAME = "spring";
@Test
void getNameReturnsName() {
GeneratedMethod method = new GeneratedMethod(NAME);
assertThat(method.getName()).isSameAs(NAME);
GeneratedMethod generatedMethod = new GeneratedMethod(NAME, methodSpecCustomizer);
assertThat(generatedMethod.getName()).isSameAs(NAME);
}
@Test
void getSpecReturnsSpec() {
GeneratedMethod method = new GeneratedMethod(NAME);
method.using(builder -> builder.addJavadoc("Test"));
assertThat(method.getSpec().javadoc).asString().contains("Test");
void generateMethodSpecReturnsMethodSpec() {
GeneratedMethod generatedMethod = new GeneratedMethod(NAME, method -> method.addJavadoc("Test"));
assertThat(generatedMethod.getMethodSpec().javadoc).asString().contains("Test");
}
@Test
void getSpecReturnsSpecWhenNoSpecDefinedThrowsException() {
GeneratedMethod method = new GeneratedMethod(NAME);
assertThatIllegalStateException().isThrownBy(() -> method.getSpec())
.withMessage("Method 'spring' has no method spec defined");
}
@Test
void usingAddsSpec() {
GeneratedMethod method = new GeneratedMethod(NAME);
method.using(builder -> builder.addModifiers(Modifier.PUBLIC));
assertThat(method.getSpec()).asString()
.isEqualToIgnoringNewLines("public void spring() {}");
}
@Test
void usingWhenBuilderChanagesNameThrowsException() {
GeneratedMethod method = new GeneratedMethod(NAME);
assertThatIllegalArgumentException()
.isThrownBy(() -> method.using(builder -> builder.setName("badname")))
.withMessage("'spec' must use the generated name 'spring'");
void generateMethodSpecWhenMethodNameIsChangedThrowsException() {
assertThatIllegalStateException().isThrownBy(() ->
new GeneratedMethod(NAME, method -> method.setName("badname")).getMethodSpec())
.withMessage("'method' consumer must not change the generated method name");
}
}

View File

@@ -17,8 +17,9 @@
package org.springframework.aot.generate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import org.junit.jupiter.api.Test;
@@ -26,7 +27,6 @@ import org.springframework.javapoet.MethodSpec;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link GeneratedMethods}.
@@ -35,7 +35,9 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
*/
class GeneratedMethodsTests {
private final GeneratedMethods methods = new GeneratedMethods();
private static final Consumer<MethodSpec.Builder> methodSpecCustomizer = method -> {};
private final GeneratedMethods methods = new GeneratedMethods(MethodName::toString);
@Test
void createWhenMethodNameGeneratorIsNullThrowsException() {
@@ -45,56 +47,82 @@ class GeneratedMethodsTests {
@Test
void createWithExistingGeneratorUsesGenerator() {
MethodNameGenerator generator = new MethodNameGenerator();
generator.generateMethodName("test");
Function<MethodName, String> generator = name -> "__" + name.toString();
GeneratedMethods methods = new GeneratedMethods(generator);
assertThat(methods.add("test").getName()).hasToString("test1");
assertThat(methods.add("test", methodSpecCustomizer).getName()).hasToString("__test");
}
@Test
void addWithMethodNameWhenSuggestedMethodIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() ->
this.methods.add((MethodName) null, methodSpecCustomizer))
.withMessage("'suggestedName' must not be null");
}
@Test
void addWithMethodNameWhenMethodIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() ->
this.methods.add(MethodName.of("test"), null))
.withMessage("'method' must not be null");
}
@Test
void addWithStringNameWhenSuggestedMethodIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() ->
this.methods.add((String) null, methodSpecCustomizer))
.withMessage("'suggestedName' must not be null");
}
@Test
void addWithStringNameWhenMethodIsNullThrowsException() {
assertThatIllegalArgumentException().isThrownBy(() ->
this.methods.add("test", null))
.withMessage("'method' must not be null");
}
@Test
void addAddsMethod() {
this.methods.add("spring", "beans").using(this::build);
this.methods.add("spring", "context").using(this::build);
assertThat(
this.methods.stream().map(GeneratedMethod::getName).map(Object::toString))
this.methods.add("springBeans", methodSpecCustomizer);
this.methods.add("springContext", methodSpecCustomizer);
assertThat(this.methods.stream().map(GeneratedMethod::getName).map(Object::toString))
.containsExactly("springBeans", "springContext");
}
@Test
void withPrefixWhenGeneratingGetMethodUsesPrefix() {
GeneratedMethod generateMethod = this.methods.withPrefix("myBean")
.add("getTest", methodSpecCustomizer);
assertThat(generateMethod.getName()).hasToString("getMyBeanTest");
}
@Test
void withPrefixWhenGeneratingSetMethodUsesPrefix() {
GeneratedMethod generateMethod = this.methods.withPrefix("myBean")
.add("setTest", methodSpecCustomizer);
assertThat(generateMethod.getName()).hasToString("setMyBeanTest");
}
@Test
void withPrefixWhenGeneratingIsMethodUsesPrefix() {
GeneratedMethod generateMethod = this.methods.withPrefix("myBean")
.add("isTest", methodSpecCustomizer);
assertThat(generateMethod.getName()).hasToString("isMyBeanTest");
}
@Test
void withPrefixWhenGeneratingOtherMethodUsesPrefix() {
GeneratedMethod generateMethod = this.methods.withPrefix("myBean")
.add("test", methodSpecCustomizer);
assertThat(generateMethod.getName()).hasToString("myBeanTest");
}
@Test
void doWithMethodSpecsAcceptsMethodSpecs() {
this.methods.add("spring", "beans").using(this::build);
this.methods.add("spring", "context").using(this::build);
this.methods.add("springBeans", methodSpecCustomizer);
this.methods.add("springContext", methodSpecCustomizer);
List<String> names = new ArrayList<>();
this.methods.doWithMethodSpecs(spec -> names.add(spec.name));
this.methods.doWithMethodSpecs(methodSpec -> names.add(methodSpec.name));
assertThat(names).containsExactly("springBeans", "springContext");
}
@Test
void doWithMethodSpecsWhenMethodHasNotHadSpecDefinedThrowsException() {
this.methods.add("spring");
assertThatIllegalStateException()
.isThrownBy(() -> this.methods.doWithMethodSpecs(spec -> {
})).withMessage("Method 'spring' has no method spec defined");
}
@Test
void iteratorIteratesMethods() {
this.methods.add("spring", "beans").using(this::build);
this.methods.add("spring", "context").using(this::build);
Iterator<GeneratedMethod> iterator = this.methods.iterator();
assertThat(iterator.next().getName()).hasToString("springBeans");
assertThat(iterator.next().getName()).hasToString("springContext");
assertThat(iterator.hasNext()).isFalse();
}
@Test
void streamStreamsMethods() {
this.methods.add("spring", "beans").using(this::build);
this.methods.add("spring", "context").using(this::build);
assertThat(this.methods.stream()).hasSize(2);
}
private void build(MethodSpec.Builder builder) {
}
}

View File

@@ -1,61 +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.generate;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests {@link MethodGeneratorWithName}.
*
* @author Phillip Webb
* @since 6.0
*/
class MethodGeneratorWithNameTests {
private final GeneratedMethods generatedMethods = new GeneratedMethods();
@Test
void withNameWhenGeneratingGetMethod() {
GeneratedMethod generateMethod = generatedMethods.withName("my", "bean")
.generateMethod("get", "test");
assertThat(generateMethod.getName()).hasToString("getMyBeanTest");
}
@Test
void withNameWhenGeneratingSetMethod() {
GeneratedMethod generateMethod = generatedMethods.withName("my", "bean")
.generateMethod("set", "test");
assertThat(generateMethod.getName()).hasToString("setMyBeanTest");
}
@Test
void withNameWhenGeneratingIsMethod() {
GeneratedMethod generateMethod = generatedMethods.withName("my", "bean")
.generateMethod("is", "test");
assertThat(generateMethod.getName()).hasToString("isMyBeanTest");
}
@Test
void withNameWhenGeneratingOtherMethod() {
GeneratedMethod generateMethod = generatedMethods.withName("my", "bean")
.generateMethod("test");
assertThat(generateMethod.getName()).hasToString("myBeanTest");
}
}

View File

@@ -1,93 +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.generate;
import java.io.InputStream;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link MethodNameGenerator}.
*
* @author Phillip Webb
*/
class MethodNameGeneratorTests {
private final MethodNameGenerator generator = new MethodNameGenerator();
@Test
void createWithReservedNamesReservesNames() {
MethodNameGenerator generator = new MethodNameGenerator("testName");
assertThat(generator.generateMethodName("test", "name")).hasToString("testName1");
}
@Test
void generateMethodNameGeneratesName() {
String generated = this.generator.generateMethodName("register", "myBean",
"bean");
assertThat(generated).isEqualTo("registerMyBeanBean");
}
@Test
void generateMethodNameWhenHasNonLettersGeneratesName() {
String generated = this.generator.generateMethodName("register", "myBean123",
"bean");
assertThat(generated).isEqualTo("registerMyBeanBean");
}
@Test
void generateMethodNameWhenHasDotsGeneratesCamelCaseName() {
String generated = this.generator.generateMethodName("register",
"org.springframework.example.bean");
assertThat(generated).isEqualTo("registerOrgSpringframeworkExampleBean");
}
@Test
void generateMethodNameWhenMultipleCallsGeneratesSequencedName() {
String generated1 = this.generator.generateMethodName("register", "myBean123",
"bean");
String generated2 = this.generator.generateMethodName("register", "myBean!",
"bean");
String generated3 = this.generator.generateMethodName("register", "myBean%%",
"bean");
assertThat(generated1).isEqualTo("registerMyBeanBean");
assertThat(generated2).isEqualTo("registerMyBeanBean1");
assertThat(generated3).isEqualTo("registerMyBeanBean2");
}
@Test
void generateMethodNameWhenAllEmptyPartsGeneratesSetName() {
String generated = this.generator.generateMethodName("123");
assertThat(generated).isEqualTo("$$aot");
}
@Test
void joinReturnsJoinedName() {
assertThat(MethodNameGenerator.join("get", "bean", "factory"))
.isEqualTo("getBeanFactory");
assertThat(MethodNameGenerator.join("get", null, "factory"))
.isEqualTo("getFactory");
assertThat(MethodNameGenerator.join(null, null)).isEqualTo("");
assertThat(MethodNameGenerator.join("", null)).isEqualTo("");
assertThat(MethodNameGenerator.join("get", InputStream.class))
.isEqualTo("getInputStream");
}
}

View File

@@ -0,0 +1,92 @@
/*
* 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.generate;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Tests for {@link MethodName}.
*
* @author Phillip Webb
*/
class MethodNameTests {
@Test
void ofWhenPartsIsNullThrowsException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> MethodName.of((String[]) null))
.withMessage("'parts' must not be null");
}
@Test
void ofReturnsMethodName() {
assertThat(MethodName.of("get", "bean", "factory")).hasToString("getBeanFactory");
assertThat(MethodName.of("get", null, "factory")).hasToString("getFactory");
assertThat(MethodName.of(null, null)).hasToString("$$aot");
assertThat(MethodName.of("", null)).hasToString("$$aot");
assertThat(MethodName.of("get", "InputStream")).hasToString("getInputStream");
assertThat(MethodName.of("register", "myBean123", "bean")).hasToString("registerMyBeanBean");
assertThat(MethodName.of("register", "org.springframework.example.bean"))
.hasToString("registerOrgSpringframeworkExampleBean");
}
@Test
void andPartsWhenPartsIsNullThrowsException() {
MethodName name = MethodName.of("myBean");
assertThatIllegalArgumentException()
.isThrownBy(() -> name.and(((String[]) null)))
.withMessage("'parts' must not be null");
}
@Test
void andPartsReturnsMethodName() {
MethodName name = MethodName.of("myBean");
assertThat(name.and("test")).hasToString("myBeanTest");
assertThat(name.and("test", null)).hasToString("myBeanTest");
assertThat(name.and("getName")).hasToString("getMyBeanName");
assertThat(name.and("setName")).hasToString("setMyBeanName");
assertThat(name.and("isDoingOk")).hasToString("isMyBeanDoingOk");
assertThat(name.and("this", "that", "the", "other")).hasToString("myBeanThisThatTheOther");
}
@Test
void andNameWhenPartsIsNullThrowsException() {
MethodName name = MethodName.of("myBean");
assertThatIllegalArgumentException()
.isThrownBy(() -> name.and(((MethodName) null)))
.withMessage("'name' must not be null");
}
@Test
void andNameReturnsMethodName() {
MethodName name = MethodName.of("myBean");
assertThat(name.and(MethodName.of("test"))).hasToString("myBeanTest");
}
@Test
void hashCodeAndEquals() {
MethodName name1 = MethodName.of("myBean");
MethodName name2 = MethodName.of("my", "bean");
MethodName name3 = MethodName.of("myOtherBean");
assertThat(name1.hashCode()).isEqualTo(name2.hashCode());
assertThat(name1).isEqualTo(name1).isEqualTo(name2).isNotEqualTo(name3);
}
}