Polish test to request the type under test

This commit is contained in:
Stephane Nicoll 2019-02-22 16:27:35 +01:00
parent c44a1e129d
commit 99c0b4561d
3 changed files with 85 additions and 37 deletions

View File

@ -20,15 +20,12 @@ import java.io.IOException;
import java.time.Duration;
import java.util.function.BiConsumer;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.springframework.boot.configurationprocessor.TypeUtils.TypeDescriptor;
import org.springframework.boot.configurationprocessor.test.RoundEnvironmentTester;
import org.springframework.boot.configurationprocessor.test.TestableAnnotationProcessor;
import org.springframework.boot.configurationsample.generic.AbstractGenericProperties;
import org.springframework.boot.configurationsample.generic.AbstractIntermediateGenericProperties;
@ -50,53 +47,51 @@ public class TypeUtilsTests {
@Test
public void resolveTypeDescriptorOnConcreteClass() throws IOException {
process(SimpleGenericProperties.class, (roundEnv, typeUtils) -> {
for (Element rootElement : roundEnv.getRootElements()) {
TypeDescriptor typeDescriptor = typeUtils
.resolveTypeDescriptor((TypeElement) rootElement);
assertThat(typeDescriptor.getGenerics().keySet().stream()
.map(Object::toString)).containsOnly("A", "B", "C");
assertThat(typeDescriptor.resolveGeneric("A"))
.hasToString(String.class.getName());
assertThat(typeDescriptor.resolveGeneric("B"))
.hasToString(Integer.class.getName());
assertThat(typeDescriptor.resolveGeneric("C"))
.hasToString(Duration.class.getName());
}
TypeDescriptor typeDescriptor = typeUtils.resolveTypeDescriptor(
roundEnv.getRootElement(SimpleGenericProperties.class));
assertThat(
typeDescriptor.getGenerics().keySet().stream().map(Object::toString))
.containsOnly("A", "B", "C");
assertThat(typeDescriptor.resolveGeneric("A"))
.hasToString(String.class.getName());
assertThat(typeDescriptor.resolveGeneric("B"))
.hasToString(Integer.class.getName());
assertThat(typeDescriptor.resolveGeneric("C"))
.hasToString(Duration.class.getName());
});
}
@Test
public void resolveTypeDescriptorOnIntermediateClass() throws IOException {
process(AbstractIntermediateGenericProperties.class, (roundEnv, typeUtils) -> {
for (Element rootElement : roundEnv.getRootElements()) {
TypeDescriptor typeDescriptor = typeUtils
.resolveTypeDescriptor((TypeElement) rootElement);
assertThat(typeDescriptor.getGenerics().keySet().stream()
.map(Object::toString)).containsOnly("A", "B", "C");
assertThat(typeDescriptor.resolveGeneric("A"))
.hasToString(String.class.getName());
assertThat(typeDescriptor.resolveGeneric("B"))
.hasToString(Integer.class.getName());
assertThat(typeDescriptor.resolveGeneric("C")).hasToString("C");
}
TypeDescriptor typeDescriptor = typeUtils.resolveTypeDescriptor(
roundEnv.getRootElement(AbstractIntermediateGenericProperties.class));
assertThat(
typeDescriptor.getGenerics().keySet().stream().map(Object::toString))
.containsOnly("A", "B", "C");
assertThat(typeDescriptor.resolveGeneric("A"))
.hasToString(String.class.getName());
assertThat(typeDescriptor.resolveGeneric("B"))
.hasToString(Integer.class.getName());
assertThat(typeDescriptor.resolveGeneric("C")).hasToString("C");
});
}
@Test
public void resolveTypeDescriptorWithOnlyGenerics() throws IOException {
process(AbstractGenericProperties.class, (roundEnv, typeUtils) -> {
for (Element rootElement : roundEnv.getRootElements()) {
TypeDescriptor typeDescriptor = typeUtils
.resolveTypeDescriptor((TypeElement) rootElement);
assertThat(typeDescriptor.getGenerics().keySet().stream()
.map(Object::toString)).containsOnly("A", "B", "C");
TypeDescriptor typeDescriptor = typeUtils.resolveTypeDescriptor(
roundEnv.getRootElement(AbstractGenericProperties.class));
assertThat(
typeDescriptor.getGenerics().keySet().stream().map(Object::toString))
.containsOnly("A", "B", "C");
}
});
}
private void process(Class<?> target,
BiConsumer<RoundEnvironment, TypeUtils> consumer) throws IOException {
BiConsumer<RoundEnvironmentTester, TypeUtils> consumer) throws IOException {
TestableAnnotationProcessor<TypeUtils> processor = new TestableAnnotationProcessor<>(
consumer, TypeUtils::new);
TestCompiler compiler = new TestCompiler(this.temporaryFolder);

View File

@ -0,0 +1,49 @@
/*
* Copyright 2012-2019 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
*
* http://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.boot.configurationprocessor.test;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.TypeElement;
/**
* A tester utility for {@link RoundEnvironment}.
*
* @author Stephane Nicoll
*/
public class RoundEnvironmentTester {
private final RoundEnvironment roundEnvironment;
RoundEnvironmentTester(RoundEnvironment roundEnvironment) {
this.roundEnvironment = roundEnvironment;
}
/**
* Return the root {@link TypeElement} for the specified {@code type}.
* @param type the type of the class
* @return the {@link TypeElement}
*/
public TypeElement getRootElement(Class<?> type) {
return (TypeElement) this.roundEnvironment.getRootElements().stream()
.filter((element) -> element.toString().equals(type.getName()))
.findFirst()
.orElseThrow(() -> new IllegalStateException("No element found for "
+ type
+ " make sure it is included in the list of classes to compile"));
}
}

View File

@ -39,13 +39,13 @@ import javax.lang.model.element.TypeElement;
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class TestableAnnotationProcessor<T> extends AbstractProcessor {
private final BiConsumer<RoundEnvironment, T> consumer;
private final BiConsumer<RoundEnvironmentTester, T> consumer;
private final Function<ProcessingEnvironment, T> factory;
private T target;
public TestableAnnotationProcessor(BiConsumer<RoundEnvironment, T> consumer,
public TestableAnnotationProcessor(BiConsumer<RoundEnvironmentTester, T> consumer,
Function<ProcessingEnvironment, T> factory) {
this.consumer = consumer;
this.factory = factory;
@ -59,7 +59,11 @@ public class TestableAnnotationProcessor<T> extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
this.consumer.accept(roundEnv, this.target);
RoundEnvironmentTester tester = new RoundEnvironmentTester(roundEnv);
if (!roundEnv.getRootElements().isEmpty()) {
this.consumer.accept(tester, this.target);
return true;
}
return false;
}