Finalize API for TestContextAnnotationUtils
This commit is contained in:
parent
82fa3f3fc1
commit
fc9650a9a6
|
@ -24,7 +24,6 @@ import java.util.function.Predicate;
|
|||
|
||||
import org.springframework.core.SpringProperties;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.core.annotation.MergedAnnotation;
|
||||
import org.springframework.core.annotation.MergedAnnotationCollectors;
|
||||
|
@ -112,7 +111,7 @@ public abstract class TestContextAnnotationUtils {
|
|||
|
||||
AnnotationDescriptor<T> descriptor =
|
||||
findAnnotationDescriptor(clazz, annotationType, searchEnclosingClass, new HashSet<>());
|
||||
return (descriptor != null ? descriptor.synthesizeAnnotation() : null);
|
||||
return (descriptor != null ? descriptor.getAnnotation() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -234,8 +233,7 @@ public abstract class TestContextAnnotationUtils {
|
|||
if (!AnnotationUtils.isInJavaLangAnnotationPackage(composedType.getName()) && visited.add(composedAnn)) {
|
||||
descriptor = findAnnotationDescriptor(composedType, annotationType, searchEnclosingClass, visited);
|
||||
if (descriptor != null) {
|
||||
return new AnnotationDescriptor<>(
|
||||
clazz, descriptor.getDeclaringClass(), composedAnn, descriptor.getAnnotation());
|
||||
return new AnnotationDescriptor<>(clazz, descriptor.getDeclaringClass(), descriptor.getAnnotation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -244,8 +242,7 @@ public abstract class TestContextAnnotationUtils {
|
|||
for (Class<?> ifc : clazz.getInterfaces()) {
|
||||
descriptor = findAnnotationDescriptor(ifc, annotationType, searchEnclosingClass, visited);
|
||||
if (descriptor != null) {
|
||||
return new AnnotationDescriptor<>(clazz, descriptor.getDeclaringClass(),
|
||||
descriptor.getComposedAnnotation(), descriptor.getAnnotation());
|
||||
return new AnnotationDescriptor<>(clazz, descriptor.getDeclaringClass(), descriptor.getAnnotation());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,7 +337,7 @@ public abstract class TestContextAnnotationUtils {
|
|||
composedAnnotation.annotationType(), annotationTypes, visited);
|
||||
if (descriptor != null) {
|
||||
return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(),
|
||||
composedAnnotation, descriptor.getAnnotation(), annotationTypes);
|
||||
descriptor.getAnnotation(), annotationTypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -350,7 +347,7 @@ public abstract class TestContextAnnotationUtils {
|
|||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(ifc, annotationTypes, visited);
|
||||
if (descriptor != null) {
|
||||
return new UntypedAnnotationDescriptor(clazz, descriptor.getDeclaringClass(),
|
||||
descriptor.getComposedAnnotation(), descriptor.getAnnotation(), annotationTypes);
|
||||
descriptor.getAnnotation(), annotationTypes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -439,19 +436,16 @@ public abstract class TestContextAnnotationUtils {
|
|||
/**
|
||||
* Descriptor for an {@link Annotation}, including the {@linkplain
|
||||
* #getDeclaringClass() class} on which the annotation is <em>declared</em>
|
||||
* as well as the actual {@linkplain #getAnnotation() annotation} instance.
|
||||
* <p>If the annotation is used as a meta-annotation, the descriptor also includes
|
||||
* the {@linkplain #getComposedAnnotation() composed annotation} on which the
|
||||
* annotation is present. In such cases, the <em>root declaring class</em> is
|
||||
* not directly annotated with the annotation but rather indirectly via the
|
||||
* composed annotation.
|
||||
* as well as the {@linkplain #getAnnotation() merged annotation} instance.
|
||||
* <p>If the annotation is used as a meta-annotation, the <em>root declaring
|
||||
* class</em> is not directly annotated with the annotation but rather
|
||||
* indirectly via a composed annotation.
|
||||
* <p>Given the following example, if we are searching for the {@code @Transactional}
|
||||
* annotation <em>on</em> the {@code TransactionalTests} class, then the
|
||||
* properties of the {@code AnnotationDescriptor} would be as follows.
|
||||
* <ul>
|
||||
* <li>rootDeclaringClass: {@code TransactionalTests} class object</li>
|
||||
* <li>declaringClass: {@code TransactionalTests} class object</li>
|
||||
* <li>composedAnnotation: {@code null}</li>
|
||||
* <li>annotation: instance of the {@code Transactional} annotation</li>
|
||||
* </ul>
|
||||
* <p><pre style="code">
|
||||
|
@ -465,7 +459,6 @@ public abstract class TestContextAnnotationUtils {
|
|||
* <ul>
|
||||
* <li>rootDeclaringClass: {@code UserRepositoryTests} class object</li>
|
||||
* <li>declaringClass: {@code RepositoryTests} class object</li>
|
||||
* <li>composedAnnotation: instance of the {@code RepositoryTests} annotation</li>
|
||||
* <li>annotation: instance of the {@code Transactional} annotation</li>
|
||||
* </ul>
|
||||
* <p><pre style="code">
|
||||
|
@ -486,31 +479,23 @@ public abstract class TestContextAnnotationUtils {
|
|||
|
||||
private final Class<?> declaringClass;
|
||||
|
||||
@Nullable
|
||||
private final Annotation composedAnnotation;
|
||||
|
||||
private final T annotation;
|
||||
|
||||
private final AnnotationAttributes annotationAttributes;
|
||||
|
||||
AnnotationDescriptor(Class<?> rootDeclaringClass, T annotation) {
|
||||
this(rootDeclaringClass, rootDeclaringClass, null, annotation);
|
||||
this(rootDeclaringClass, rootDeclaringClass, annotation);
|
||||
}
|
||||
|
||||
AnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
||||
@Nullable Annotation composedAnnotation, T annotation) {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
AnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass, T annotation) {
|
||||
Assert.notNull(rootDeclaringClass, "'rootDeclaringClass' must not be null");
|
||||
Assert.notNull(declaringClass, "'declaringClass' must not be null");
|
||||
Assert.notNull(annotation, "Annotation must not be null");
|
||||
this.rootDeclaringClass = rootDeclaringClass;
|
||||
this.declaringClass = declaringClass;
|
||||
this.composedAnnotation = composedAnnotation;
|
||||
this.annotation = annotation;
|
||||
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
|
||||
rootDeclaringClass, annotation.annotationType().getName(), false, false);
|
||||
Assert.state(attributes != null, "No annotation attributes");
|
||||
this.annotationAttributes = attributes;
|
||||
this.annotation = (T) AnnotatedElementUtils.findMergedAnnotation(
|
||||
rootDeclaringClass, annotation.annotationType());
|
||||
Assert.state(this.annotation != null,
|
||||
() -> "Failed to find merged annotation for " + annotation);
|
||||
}
|
||||
|
||||
public Class<?> getRootDeclaringClass() {
|
||||
|
@ -521,21 +506,11 @@ public abstract class TestContextAnnotationUtils {
|
|||
return this.declaringClass;
|
||||
}
|
||||
|
||||
T getAnnotation() {
|
||||
return this.annotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize the merged {@link #getAnnotationAttributes AnnotationAttributes}
|
||||
* in this descriptor back into an annotation of the target
|
||||
* {@linkplain #getAnnotationType annotation type}.
|
||||
* @see #getAnnotationAttributes()
|
||||
* @see #getAnnotationType()
|
||||
* @see AnnotationUtils#synthesizeAnnotation(java.util.Map, Class, java.lang.reflect.AnnotatedElement)
|
||||
* Get the merged annotation for this descriptor.
|
||||
*/
|
||||
public T synthesizeAnnotation() {
|
||||
return AnnotationUtils.synthesizeAnnotation(
|
||||
getAnnotationAttributes(), getAnnotationType(), getRootDeclaringClass());
|
||||
public T getAnnotation() {
|
||||
return this.annotation;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -543,25 +518,10 @@ public abstract class TestContextAnnotationUtils {
|
|||
return (Class<T>) this.annotation.annotationType();
|
||||
}
|
||||
|
||||
AnnotationAttributes getAnnotationAttributes() {
|
||||
return this.annotationAttributes;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Annotation getComposedAnnotation() {
|
||||
return this.composedAnnotation;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
Class<? extends Annotation> getComposedAnnotationType() {
|
||||
return (this.composedAnnotation != null ? this.composedAnnotation.annotationType() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the next {@link AnnotationDescriptor} for the specified
|
||||
* {@linkplain #getAnnotationType() annotation type} in the hierarchy
|
||||
* above the {@linkplain #getRootDeclaringClass() root declaring class}
|
||||
* of this descriptor.
|
||||
* Find the next {@link AnnotationDescriptor} for the specified annotation
|
||||
* type in the hierarchy above the {@linkplain #getRootDeclaringClass()
|
||||
* root declaring class} of this descriptor.
|
||||
* <p>If a corresponding annotation is found in the superclass hierarchy
|
||||
* of the root declaring class, that will be returned. Otherwise, an
|
||||
* attempt will be made to find a corresponding annotation in the
|
||||
|
@ -583,10 +543,9 @@ public abstract class TestContextAnnotationUtils {
|
|||
}
|
||||
|
||||
/**
|
||||
* Find <strong>all</strong> annotations of the specified
|
||||
* {@linkplain #getAnnotationType() annotation type} that are present or
|
||||
* meta-present on the {@linkplain #getRootDeclaringClass() root declaring
|
||||
* class} of this descriptor.
|
||||
* Find <strong>all</strong> annotations of the specified annotation type
|
||||
* that are present or meta-present on the {@linkplain #getRootDeclaringClass()
|
||||
* root declaring class} of this descriptor.
|
||||
* @return the set of all merged, synthesized {@code Annotations} found,
|
||||
* or an empty set if none were found
|
||||
*/
|
||||
|
@ -609,7 +568,6 @@ public abstract class TestContextAnnotationUtils {
|
|||
return new ToStringCreator(this)
|
||||
.append("rootDeclaringClass", this.rootDeclaringClass.getName())
|
||||
.append("declaringClass", this.declaringClass.getName())
|
||||
.append("composedAnnotation", this.composedAnnotation)
|
||||
.append("annotation", this.annotation)
|
||||
.toString();
|
||||
}
|
||||
|
@ -628,14 +586,13 @@ public abstract class TestContextAnnotationUtils {
|
|||
UntypedAnnotationDescriptor(Class<?> rootDeclaringClass, Annotation annotation,
|
||||
Class<? extends Annotation>[] annotationTypes) {
|
||||
|
||||
this(rootDeclaringClass, rootDeclaringClass, null, annotation, annotationTypes);
|
||||
this(rootDeclaringClass, rootDeclaringClass, annotation, annotationTypes);
|
||||
}
|
||||
|
||||
UntypedAnnotationDescriptor(Class<?> rootDeclaringClass, Class<?> declaringClass,
|
||||
@Nullable Annotation composedAnnotation, Annotation annotation,
|
||||
Class<? extends Annotation>[] annotationTypes) {
|
||||
Annotation annotation, Class<? extends Annotation>[] annotationTypes) {
|
||||
|
||||
super(rootDeclaringClass, declaringClass, composedAnnotation, annotation);
|
||||
super(rootDeclaringClass, declaringClass, annotation);
|
||||
this.annotationTypes = annotationTypes;
|
||||
}
|
||||
|
||||
|
|
|
@ -131,7 +131,7 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot
|
|||
// Traverse the class hierarchy...
|
||||
while (descriptor != null) {
|
||||
Class<?> declaringClass = descriptor.getDeclaringClass();
|
||||
TestExecutionListeners testExecutionListeners = descriptor.synthesizeAnnotation();
|
||||
TestExecutionListeners testExecutionListeners = descriptor.getAnnotation();
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(String.format("Retrieved @TestExecutionListeners [%s] for declaring class [%s].",
|
||||
testExecutionListeners, declaringClass.getName()));
|
||||
|
|
|
@ -81,7 +81,7 @@ abstract class ActiveProfilesUtils {
|
|||
|
||||
while (descriptor != null) {
|
||||
Class<?> rootDeclaringClass = descriptor.getRootDeclaringClass();
|
||||
ActiveProfiles annotation = descriptor.synthesizeAnnotation();
|
||||
ActiveProfiles annotation = descriptor.getAnnotation();
|
||||
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(String.format("Retrieved @ActiveProfiles [%s] for declaring class [%s]",
|
||||
|
|
|
@ -126,7 +126,7 @@ abstract class ContextLoaderUtils {
|
|||
List<ContextConfigurationAttributes> configAttributesList = new ArrayList<>();
|
||||
|
||||
if (contextConfigDeclaredLocally) {
|
||||
ContextConfiguration contextConfiguration = (ContextConfiguration) desc.synthesizeAnnotation();
|
||||
ContextConfiguration contextConfiguration = (ContextConfiguration) desc.getAnnotation();
|
||||
convertContextConfigToConfigAttributesAndAddToList(
|
||||
contextConfiguration, rootDeclaringClass, configAttributesList);
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ abstract class ContextLoaderUtils {
|
|||
ContextConfiguration previousAnnotation = null;
|
||||
Class<?> previousDeclaringClass = null;
|
||||
while (descriptor != null) {
|
||||
ContextConfiguration currentAnnotation = descriptor.synthesizeAnnotation();
|
||||
ContextConfiguration currentAnnotation = descriptor.getAnnotation();
|
||||
// Don't ignore duplicate @ContextConfiguration declaration without resources,
|
||||
// because the ContextLoader will likely detect default resources specific to the
|
||||
// annotated class.
|
||||
|
|
|
@ -67,7 +67,7 @@ public class DefaultActiveProfilesResolver implements ActiveProfilesResolver {
|
|||
return EMPTY_STRING_ARRAY;
|
||||
}
|
||||
else {
|
||||
ActiveProfiles annotation = descriptor.synthesizeAnnotation();
|
||||
ActiveProfiles annotation = descriptor.getAnnotation();
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace(String.format("Retrieved @ActiveProfiles [%s] for declaring class [%s].", annotation,
|
||||
descriptor.getDeclaringClass().getName()));
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright 2002-2020 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.test.context;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.annotation.AliasFor;
|
||||
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.context.TestContextAnnotationUtils.findAnnotationDescriptor;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link TestContextAnnotationUtils} that verify support for
|
||||
* overridden meta-annotation attributes.
|
||||
*
|
||||
* <p>See <a href="https://jira.spring.io/browse/SPR-10181">SPR-10181</a>.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 5.3, though originally since 4.0 for the deprecated
|
||||
* {@link org.springframework.test.util.MetaAnnotationUtils} support
|
||||
* @see TestContextAnnotationUtilsTests
|
||||
*/
|
||||
class OverriddenMetaAnnotationAttributesTestContextAnnotationUtilsTests {
|
||||
|
||||
@Test
|
||||
void contextConfigurationValue() {
|
||||
Class<?> rootDeclaringClass = MetaValueConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(rootDeclaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(rootDeclaringClass);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(MetaValueConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getAnnotation().value()).containsExactly("foo.xml");
|
||||
assertThat(descriptor.getAnnotation().locations()).containsExactly("foo.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void overriddenContextConfigurationValue() {
|
||||
Class<?> rootDeclaringClass = OverriddenMetaValueConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(rootDeclaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(rootDeclaringClass);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(MetaValueConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getAnnotation().value()).containsExactly("bar.xml");
|
||||
assertThat(descriptor.getAnnotation().locations()).containsExactly("bar.xml");
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextConfigurationLocationsAndInheritLocations() {
|
||||
Class<?> rootDeclaringClass = MetaLocationsConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(rootDeclaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(rootDeclaringClass);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(MetaLocationsConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getAnnotation().value()).isEmpty();
|
||||
assertThat(descriptor.getAnnotation().locations()).isEmpty();
|
||||
assertThat(descriptor.getAnnotation().inheritLocations()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void overriddenContextConfigurationLocationsAndInheritLocations() {
|
||||
Class<?> rootDeclaringClass = OverriddenMetaLocationsConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(rootDeclaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(rootDeclaringClass);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(MetaLocationsConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getAnnotation().value()).containsExactly("bar.xml");
|
||||
assertThat(descriptor.getAnnotation().locations()).containsExactly("bar.xml");
|
||||
assertThat(descriptor.getAnnotation().inheritLocations()).isTrue();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ContextConfiguration
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface MetaValueConfig {
|
||||
|
||||
@AliasFor(annotation = ContextConfiguration.class)
|
||||
String[] value() default "foo.xml";
|
||||
}
|
||||
|
||||
@MetaValueConfig
|
||||
static class MetaValueConfigTestCase {
|
||||
}
|
||||
|
||||
@MetaValueConfig("bar.xml")
|
||||
static class OverriddenMetaValueConfigTestCase {
|
||||
}
|
||||
|
||||
@ContextConfiguration(locations = "foo.xml", inheritLocations = false)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface MetaLocationsConfig {
|
||||
|
||||
String[] locations() default {};
|
||||
|
||||
boolean inheritLocations();
|
||||
}
|
||||
|
||||
@MetaLocationsConfig(inheritLocations = true)
|
||||
static class MetaLocationsConfigTestCase {
|
||||
}
|
||||
|
||||
@MetaLocationsConfig(locations = "bar.xml", inheritLocations = true)
|
||||
static class OverriddenMetaLocationsConfigTestCase {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2020 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.test.context;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.test.context.TestContextAnnotationUtils.AnnotationDescriptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.test.context.TestContextAnnotationUtils.findAnnotationDescriptor;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link TestContextAnnotationUtils} that verify support for
|
||||
* overridden meta-annotation attributes.
|
||||
*
|
||||
* <p>See <a href="https://jira.spring.io/browse/SPR-10181">SPR-10181</a>.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.0
|
||||
* @see TestContextAnnotationUtilsTests
|
||||
*/
|
||||
class OverriddenMetaAnnotationAttributesTests {
|
||||
|
||||
@Test
|
||||
void contextConfigurationValue() throws Exception {
|
||||
Class<MetaValueConfigTestCase> declaringClass = MetaValueConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
|
||||
|
||||
// direct access to annotation value:
|
||||
assertThat(descriptor.getAnnotation().value()).isEqualTo(new String[] { "foo.xml" });
|
||||
}
|
||||
|
||||
@Test
|
||||
void overriddenContextConfigurationValue() throws Exception {
|
||||
Class<?> declaringClass = OverriddenMetaValueConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaValueConfig.class);
|
||||
|
||||
// direct access to annotation value:
|
||||
assertThat(descriptor.getAnnotation().value()).isEqualTo(new String[] { "foo.xml" });
|
||||
|
||||
// overridden attribute:
|
||||
AnnotationAttributes attributes = descriptor.getAnnotationAttributes();
|
||||
|
||||
// NOTE: we would like to be able to override the 'value' attribute; however,
|
||||
// Spring currently does not allow overrides for the 'value' attribute.
|
||||
// See SPR-11393 for related discussions.
|
||||
assertThat(attributes.getStringArray("value")).isEqualTo(new String[] { "foo.xml" });
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextConfigurationLocationsAndInheritLocations() throws Exception {
|
||||
Class<MetaLocationsConfigTestCase> declaringClass = MetaLocationsConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
|
||||
|
||||
// direct access to annotation attributes:
|
||||
assertThat(descriptor.getAnnotation().locations()).isEqualTo(new String[] { "foo.xml" });
|
||||
assertThat(descriptor.getAnnotation().inheritLocations()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void overriddenContextConfigurationLocationsAndInheritLocations() throws Exception {
|
||||
Class<?> declaringClass = OverriddenMetaLocationsConfigTestCase.class;
|
||||
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(declaringClass,
|
||||
ContextConfiguration.class);
|
||||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaLocationsConfig.class);
|
||||
|
||||
// direct access to annotation attributes:
|
||||
assertThat(descriptor.getAnnotation().locations()).isEqualTo(new String[] { "foo.xml" });
|
||||
assertThat(descriptor.getAnnotation().inheritLocations()).isFalse();
|
||||
|
||||
// overridden attributes:
|
||||
AnnotationAttributes attributes = descriptor.getAnnotationAttributes();
|
||||
assertThat(attributes.getStringArray("locations")).isEqualTo(new String[] { "bar.xml" });
|
||||
assertThat(attributes.getBoolean("inheritLocations")).isTrue();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@ContextConfiguration("foo.xml")
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface MetaValueConfig {
|
||||
|
||||
String[] value() default {};
|
||||
}
|
||||
|
||||
@MetaValueConfig
|
||||
static class MetaValueConfigTestCase {
|
||||
}
|
||||
|
||||
@MetaValueConfig("bar.xml")
|
||||
static class OverriddenMetaValueConfigTestCase {
|
||||
}
|
||||
|
||||
@ContextConfiguration(locations = "foo.xml", inheritLocations = false)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface MetaLocationsConfig {
|
||||
|
||||
String[] locations() default {};
|
||||
|
||||
boolean inheritLocations();
|
||||
}
|
||||
|
||||
@MetaLocationsConfig(inheritLocations = true)
|
||||
static class MetaLocationsConfigTestCase {
|
||||
}
|
||||
|
||||
@MetaLocationsConfig(locations = "bar.xml", inheritLocations = true)
|
||||
static class OverriddenMetaLocationsConfigTestCase {
|
||||
}
|
||||
|
||||
}
|
|
@ -47,8 +47,9 @@ import static org.springframework.test.context.TestContextAnnotationUtils.search
|
|||
* Unit tests for {@link TestContextAnnotationUtils}.
|
||||
*
|
||||
* @author Sam Brannen
|
||||
* @since 4.0
|
||||
* @see OverriddenMetaAnnotationAttributesTests
|
||||
* @since 5.3, though originally since 4.0 for the deprecated
|
||||
* {@link org.springframework.test.util.MetaAnnotationUtils} support
|
||||
* @see OverriddenMetaAnnotationAttributesTestContextAnnotationUtilsTests
|
||||
*/
|
||||
class TestContextAnnotationUtilsTests {
|
||||
|
||||
|
@ -167,8 +168,6 @@ class TestContextAnnotationUtilsTests {
|
|||
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(HasLocalAndMetaComponentAnnotation.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -186,7 +185,6 @@ class TestContextAnnotationUtilsTests {
|
|||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(ClassWithMetaAnnotatedInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(Meta1.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
assertThat(descriptor.getComposedAnnotation().annotationType()).isEqualTo(Meta1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -198,10 +196,8 @@ class TestContextAnnotationUtilsTests {
|
|||
assertThat(descriptor.getRootDeclaringClass()).as("rootDeclaringClass").isEqualTo(MetaAnnotatedAndSuperAnnotatedContextConfigClass.class);
|
||||
assertThat(descriptor.getDeclaringClass()).as("declaringClass").isEqualTo(MetaConfig.class);
|
||||
assertThat(descriptor.getAnnotationType()).as("annotationType").isEqualTo(ContextConfiguration.class);
|
||||
assertThat(descriptor.getComposedAnnotation()).as("composedAnnotation should not be null").isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).as("composedAnnotationType").isEqualTo(MetaConfig.class);
|
||||
|
||||
assertThat(descriptor.getAnnotationAttributes().getClassArray("classes")).as("configured classes").isEqualTo(new Class<?>[] {String.class});
|
||||
assertThat(descriptor.getAnnotation().classes()).as("configured classes").containsExactly(String.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -220,8 +216,8 @@ class TestContextAnnotationUtilsTests {
|
|||
*/
|
||||
@Test
|
||||
void findAnnotationDescriptorOnMetaMetaAnnotatedClass() {
|
||||
Class<MetaMetaAnnotatedClass> startClass = MetaMetaAnnotatedClass.class;
|
||||
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2", MetaMeta.class);
|
||||
Class<?> startClass = MetaMetaAnnotatedClass.class;
|
||||
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,8 +225,8 @@ class TestContextAnnotationUtilsTests {
|
|||
*/
|
||||
@Test
|
||||
void findAnnotationDescriptorOnMetaMetaMetaAnnotatedClass() {
|
||||
Class<MetaMetaMetaAnnotatedClass> startClass = MetaMetaMetaAnnotatedClass.class;
|
||||
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2", MetaMetaMeta.class);
|
||||
Class<?> startClass = MetaMetaMetaAnnotatedClass.class;
|
||||
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,11 +259,11 @@ class TestContextAnnotationUtilsTests {
|
|||
private void assertAtComponentOnComposedAnnotation(
|
||||
Class<?> startClass, Class<?> rootDeclaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
|
||||
|
||||
assertAtComponentOnComposedAnnotation(startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType);
|
||||
assertAtComponentOnComposedAnnotation(startClass, rootDeclaringClass, composedAnnotationType, name);
|
||||
}
|
||||
|
||||
private void assertAtComponentOnComposedAnnotation(Class<?> startClass, Class<?> rootDeclaringClass,
|
||||
Class<?> declaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
|
||||
Class<?> declaringClass, String name) {
|
||||
|
||||
AnnotationDescriptor<Component> descriptor = findAnnotationDescriptor(startClass, Component.class);
|
||||
assertThat(descriptor).as("AnnotationDescriptor should not be null").isNotNull();
|
||||
|
@ -275,8 +271,6 @@ class TestContextAnnotationUtilsTests {
|
|||
assertThat(descriptor.getDeclaringClass()).as("declaringClass").isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getAnnotationType()).as("annotationType").isEqualTo(Component.class);
|
||||
assertThat(descriptor.getAnnotation().value()).as("component name").isEqualTo(name);
|
||||
assertThat(descriptor.getComposedAnnotation()).as("composedAnnotation should not be null").isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).as("composedAnnotationType").isEqualTo(composedAnnotationType);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -362,13 +356,11 @@ class TestContextAnnotationUtilsTests {
|
|||
HasLocalAndMetaComponentAnnotation.class, Transactional.class, annotationType, Order.class);
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(HasLocalAndMetaComponentAnnotation.class);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
|
||||
assertThat(descriptor.getComposedAnnotation()).isNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesWithMetaComponentAnnotation() {
|
||||
Class<HasMetaComponentAnnotation> startClass = HasMetaComponentAnnotation.class;
|
||||
Class<?> startClass = HasMetaComponentAnnotation.class;
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta1", Meta1.class);
|
||||
}
|
||||
|
||||
|
@ -384,10 +376,9 @@ class TestContextAnnotationUtilsTests {
|
|||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(startClass);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
|
||||
assertThat(((ContextConfiguration) descriptor.getAnnotation()).value()).isEqualTo(new Class<?>[] {});
|
||||
assertThat(descriptor.getAnnotationAttributes().getClassArray("classes")).isEqualTo(new Class<?>[] {MetaConfig.DevConfig.class, MetaConfig.ProductionConfig.class});
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaConfig.class);
|
||||
assertThat(((ContextConfiguration) descriptor.getAnnotation()).value()).isEmpty();
|
||||
assertThat(((ContextConfiguration) descriptor.getAnnotation()).classes())
|
||||
.containsExactly(MetaConfig.DevConfig.class, MetaConfig.ProductionConfig.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -402,15 +393,14 @@ class TestContextAnnotationUtilsTests {
|
|||
assertThat(descriptor).isNotNull();
|
||||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(startClass);
|
||||
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
|
||||
assertThat(((ContextConfiguration) descriptor.getAnnotation()).value()).isEqualTo(new Class<?>[] {});
|
||||
assertThat(descriptor.getAnnotationAttributes().getClassArray("classes")).isEqualTo(new Class<?>[] {TestContextAnnotationUtilsTests.class});
|
||||
assertThat(descriptor.getComposedAnnotation()).isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaConfig.class);
|
||||
assertThat(((ContextConfiguration) descriptor.getAnnotation()).value()).isEmpty();
|
||||
assertThat(((ContextConfiguration) descriptor.getAnnotation()).classes())
|
||||
.containsExactly(TestContextAnnotationUtilsTests.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesForInterfaceWithMetaAnnotation() {
|
||||
Class<InterfaceWithMetaAnnotation> startClass = InterfaceWithMetaAnnotation.class;
|
||||
Class<?> startClass = InterfaceWithMetaAnnotation.class;
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta1", Meta1.class);
|
||||
}
|
||||
|
||||
|
@ -426,12 +416,11 @@ class TestContextAnnotationUtilsTests {
|
|||
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(ClassWithMetaAnnotatedInterface.class);
|
||||
assertThat(descriptor.getDeclaringClass()).isEqualTo(Meta1.class);
|
||||
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
|
||||
assertThat(descriptor.getComposedAnnotation().annotationType()).isEqualTo(Meta1.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesForClassWithLocalMetaAnnotationAndMetaAnnotatedInterface() {
|
||||
Class<ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface> startClass = ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class;
|
||||
Class<?> startClass = ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class;
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta2", Meta2.class);
|
||||
}
|
||||
|
||||
|
@ -447,9 +436,9 @@ class TestContextAnnotationUtilsTests {
|
|||
*/
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesOnMetaMetaAnnotatedClass() {
|
||||
Class<MetaMetaAnnotatedClass> startClass = MetaMetaAnnotatedClass.class;
|
||||
Class<?> startClass = MetaMetaAnnotatedClass.class;
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
|
||||
startClass, startClass, Meta2.class, "meta2", MetaMeta.class);
|
||||
startClass, startClass, Meta2.class, "meta2");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -457,9 +446,9 @@ class TestContextAnnotationUtilsTests {
|
|||
*/
|
||||
@Test
|
||||
void findAnnotationDescriptorForTypesOnMetaMetaMetaAnnotatedClass() {
|
||||
Class<MetaMetaMetaAnnotatedClass> startClass = MetaMetaMetaAnnotatedClass.class;
|
||||
Class<?> startClass = MetaMetaMetaAnnotatedClass.class;
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
|
||||
startClass, startClass, Meta2.class, "meta2", MetaMetaMeta.class);
|
||||
startClass, startClass, Meta2.class, "meta2");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -497,13 +486,12 @@ class TestContextAnnotationUtilsTests {
|
|||
Class<?> rootDeclaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
|
||||
|
||||
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
|
||||
startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType);
|
||||
startClass, rootDeclaringClass, composedAnnotationType, name);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(Class<?> startClass,
|
||||
Class<?> rootDeclaringClass, Class<?> declaringClass, String name,
|
||||
Class<? extends Annotation> composedAnnotationType) {
|
||||
Class<?> rootDeclaringClass, Class<?> declaringClass, String name) {
|
||||
|
||||
Class<Component> annotationType = Component.class;
|
||||
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
|
||||
|
@ -514,8 +502,6 @@ class TestContextAnnotationUtilsTests {
|
|||
assertThat(descriptor.getDeclaringClass()).as("declaringClass").isEqualTo(declaringClass);
|
||||
assertThat(descriptor.getAnnotationType()).as("annotationType").isEqualTo(annotationType);
|
||||
assertThat(((Component) descriptor.getAnnotation()).value()).as("component name").isEqualTo(name);
|
||||
assertThat(descriptor.getComposedAnnotation()).as("composedAnnotation should not be null").isNotNull();
|
||||
assertThat(descriptor.getComposedAnnotationType()).as("composedAnnotationType").isEqualTo(composedAnnotationType);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue