Browse Source

Reinstate tests for deprecated MetaAnnotationUtils

pull/25991/head
Sam Brannen 5 years ago
parent
commit
82fa3f3fc1
  1. 639
      spring-test/src/test/java/org/springframework/test/util/MetaAnnotationUtilsTests.java
  2. 158
      spring-test/src/test/java/org/springframework/test/util/OverriddenMetaAnnotationAttributesTests.java

639
spring-test/src/test/java/org/springframework/test/util/MetaAnnotationUtilsTests.java

@ -0,0 +1,639 @@ @@ -0,0 +1,639 @@
/*
* 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.util;
import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.Test;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor;
import org.springframework.test.util.MetaAnnotationUtils.UntypedAnnotationDescriptor;
import org.springframework.transaction.annotation.Transactional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptor;
import static org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptorForTypes;
/**
* Unit tests for {@link MetaAnnotationUtils}.
*
* @author Sam Brannen
* @since 4.0
* @see OverriddenMetaAnnotationAttributesTests
*/
@SuppressWarnings("deprecation")
class MetaAnnotationUtilsTests {
private void assertAtComponentOnComposedAnnotation(
Class<?> rootDeclaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
assertAtComponentOnComposedAnnotation(rootDeclaringClass, rootDeclaringClass, name, composedAnnotationType);
}
private void assertAtComponentOnComposedAnnotation(
Class<?> startClass, Class<?> rootDeclaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
assertAtComponentOnComposedAnnotation(startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType);
}
private void assertAtComponentOnComposedAnnotation(Class<?> startClass, Class<?> rootDeclaringClass,
Class<?> declaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
AnnotationDescriptor<Component> descriptor = findAnnotationDescriptor(startClass, Component.class);
assertThat(descriptor).as("AnnotationDescriptor should not be null").isNotNull();
assertThat(descriptor.getRootDeclaringClass()).as("rootDeclaringClass").isEqualTo(rootDeclaringClass);
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);
}
private void assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
Class<?> startClass, String name, Class<? extends Annotation> composedAnnotationType) {
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
startClass, startClass, name, composedAnnotationType);
}
private void assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(Class<?> startClass,
Class<?> rootDeclaringClass, String name, Class<? extends Annotation> composedAnnotationType) {
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType);
}
@SuppressWarnings("unchecked")
private void assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(Class<?> startClass,
Class<?> rootDeclaringClass, Class<?> declaringClass, String name,
Class<? extends Annotation> composedAnnotationType) {
Class<Component> annotationType = Component.class;
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
startClass, Service.class, annotationType, Order.class, Transactional.class);
assertThat(descriptor).as("UntypedAnnotationDescriptor should not be null").isNotNull();
assertThat(descriptor.getRootDeclaringClass()).as("rootDeclaringClass").isEqualTo(rootDeclaringClass);
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);
}
@Test
void findAnnotationDescriptorWithNoAnnotationPresent() {
assertThat(findAnnotationDescriptor(NonAnnotatedInterface.class, Transactional.class)).isNull();
assertThat(findAnnotationDescriptor(NonAnnotatedClass.class, Transactional.class)).isNull();
}
@Test
void findAnnotationDescriptorWithInheritedAnnotationOnClass() {
// Note: @Transactional is inherited
assertThat(findAnnotationDescriptor(InheritedAnnotationClass.class, Transactional.class).getRootDeclaringClass()).isEqualTo(InheritedAnnotationClass.class);
assertThat(findAnnotationDescriptor(SubInheritedAnnotationClass.class, Transactional.class).getRootDeclaringClass()).isEqualTo(InheritedAnnotationClass.class);
}
@Test
void findAnnotationDescriptorWithInheritedAnnotationOnInterface() {
// Note: @Transactional is inherited
Transactional rawAnnotation = InheritedAnnotationInterface.class.getAnnotation(Transactional.class);
AnnotationDescriptor<Transactional> descriptor =
findAnnotationDescriptor(InheritedAnnotationInterface.class, Transactional.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
descriptor = findAnnotationDescriptor(SubInheritedAnnotationInterface.class, Transactional.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubInheritedAnnotationInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
descriptor = findAnnotationDescriptor(SubSubInheritedAnnotationInterface.class, Transactional.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubSubInheritedAnnotationInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
}
@Test
void findAnnotationDescriptorForNonInheritedAnnotationOnClass() {
// Note: @Order is not inherited.
assertThat(findAnnotationDescriptor(NonInheritedAnnotationClass.class, Order.class).getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationClass.class);
assertThat(findAnnotationDescriptor(SubNonInheritedAnnotationClass.class, Order.class).getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationClass.class);
}
@Test
void findAnnotationDescriptorForNonInheritedAnnotationOnInterface() {
// Note: @Order is not inherited.
Order rawAnnotation = NonInheritedAnnotationInterface.class.getAnnotation(Order.class);
AnnotationDescriptor<Order> descriptor =
findAnnotationDescriptor(NonInheritedAnnotationInterface.class, Order.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
descriptor = findAnnotationDescriptor(SubNonInheritedAnnotationInterface.class, Order.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubNonInheritedAnnotationInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
}
@Test
void findAnnotationDescriptorWithMetaComponentAnnotation() {
assertAtComponentOnComposedAnnotation(HasMetaComponentAnnotation.class, "meta1", Meta1.class);
}
@Test
void findAnnotationDescriptorWithLocalAndMetaComponentAnnotation() {
Class<Component> annotationType = Component.class;
AnnotationDescriptor<Component> descriptor = findAnnotationDescriptor(
HasLocalAndMetaComponentAnnotation.class, annotationType);
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(HasLocalAndMetaComponentAnnotation.class);
assertThat(descriptor.getAnnotationType()).isEqualTo(annotationType);
assertThat(descriptor.getComposedAnnotation()).isNull();
assertThat(descriptor.getComposedAnnotationType()).isNull();
}
@Test
void findAnnotationDescriptorForInterfaceWithMetaAnnotation() {
assertAtComponentOnComposedAnnotation(InterfaceWithMetaAnnotation.class, "meta1", Meta1.class);
}
@Test
void findAnnotationDescriptorForClassWithMetaAnnotatedInterface() {
Component rawAnnotation = AnnotationUtils.findAnnotation(ClassWithMetaAnnotatedInterface.class, Component.class);
AnnotationDescriptor<Component> descriptor =
findAnnotationDescriptor(ClassWithMetaAnnotatedInterface.class, Component.class);
assertThat(descriptor).isNotNull();
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 findAnnotationDescriptorForClassWithLocalMetaAnnotationAndAnnotatedSuperclass() {
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(
MetaAnnotatedAndSuperAnnotatedContextConfigClass.class, ContextConfiguration.class);
assertThat(descriptor).as("AnnotationDescriptor should not be null").isNotNull();
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});
}
@Test
void findAnnotationDescriptorForClassWithLocalMetaAnnotationAndMetaAnnotatedInterface() {
assertAtComponentOnComposedAnnotation(ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class, "meta2", Meta2.class);
}
@Test
void findAnnotationDescriptorForSubClassWithLocalMetaAnnotationAndMetaAnnotatedInterface() {
assertAtComponentOnComposedAnnotation(SubClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class,
ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class, "meta2", Meta2.class);
}
/**
* @since 4.0.3
*/
@Test
void findAnnotationDescriptorOnMetaMetaAnnotatedClass() {
Class<MetaMetaAnnotatedClass> startClass = MetaMetaAnnotatedClass.class;
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2", MetaMeta.class);
}
/**
* @since 4.0.3
*/
@Test
void findAnnotationDescriptorOnMetaMetaMetaAnnotatedClass() {
Class<MetaMetaMetaAnnotatedClass> startClass = MetaMetaMetaAnnotatedClass.class;
assertAtComponentOnComposedAnnotation(startClass, startClass, Meta2.class, "meta2", MetaMetaMeta.class);
}
/**
* @since 4.0.3
*/
@Test
void findAnnotationDescriptorOnAnnotatedClassWithMissingTargetMetaAnnotation() {
// InheritedAnnotationClass is NOT annotated or meta-annotated with @Component
AnnotationDescriptor<Component> descriptor = findAnnotationDescriptor(
InheritedAnnotationClass.class, Component.class);
assertThat(descriptor).as("Should not find @Component on InheritedAnnotationClass").isNull();
}
/**
* @since 4.0.3
*/
@Test
void findAnnotationDescriptorOnMetaCycleAnnotatedClassWithMissingTargetMetaAnnotation() {
AnnotationDescriptor<Component> descriptor = findAnnotationDescriptor(
MetaCycleAnnotatedClass.class, Component.class);
assertThat(descriptor).as("Should not find @Component on MetaCycleAnnotatedClass").isNull();
}
// -------------------------------------------------------------------------
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesWithNoAnnotationPresent() {
assertThat(findAnnotationDescriptorForTypes(NonAnnotatedInterface.class, Transactional.class, Component.class)).isNull();
assertThat(findAnnotationDescriptorForTypes(NonAnnotatedClass.class, Transactional.class, Order.class)).isNull();
}
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesWithInheritedAnnotationOnClass() {
// Note: @Transactional is inherited
assertThat(findAnnotationDescriptorForTypes(InheritedAnnotationClass.class, Transactional.class).getRootDeclaringClass()).isEqualTo(InheritedAnnotationClass.class);
assertThat(findAnnotationDescriptorForTypes(SubInheritedAnnotationClass.class, Transactional.class).getRootDeclaringClass()).isEqualTo(InheritedAnnotationClass.class);
}
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesWithInheritedAnnotationOnInterface() {
// Note: @Transactional is inherited
Transactional rawAnnotation = InheritedAnnotationInterface.class.getAnnotation(Transactional.class);
UntypedAnnotationDescriptor descriptor =
findAnnotationDescriptorForTypes(InheritedAnnotationInterface.class, Transactional.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
descriptor = findAnnotationDescriptorForTypes(SubInheritedAnnotationInterface.class, Transactional.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubInheritedAnnotationInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
descriptor = findAnnotationDescriptorForTypes(SubSubInheritedAnnotationInterface.class, Transactional.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubSubInheritedAnnotationInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(InheritedAnnotationInterface.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
}
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesForNonInheritedAnnotationOnClass() {
// Note: @Order is not inherited.
assertThat(findAnnotationDescriptorForTypes(NonInheritedAnnotationClass.class, Order.class).getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationClass.class);
assertThat(findAnnotationDescriptorForTypes(SubNonInheritedAnnotationClass.class, Order.class).getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationClass.class);
}
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesForNonInheritedAnnotationOnInterface() {
// Note: @Order is not inherited.
Order rawAnnotation = NonInheritedAnnotationInterface.class.getAnnotation(Order.class);
UntypedAnnotationDescriptor descriptor =
findAnnotationDescriptorForTypes(NonInheritedAnnotationInterface.class, Order.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
descriptor = findAnnotationDescriptorForTypes(SubNonInheritedAnnotationInterface.class, Order.class);
assertThat(descriptor).isNotNull();
assertThat(descriptor.getRootDeclaringClass()).isEqualTo(SubNonInheritedAnnotationInterface.class);
assertThat(descriptor.getDeclaringClass()).isEqualTo(NonInheritedAnnotationInterface.class);
assertThat(descriptor.getAnnotation()).isEqualTo(rawAnnotation);
}
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesWithLocalAndMetaComponentAnnotation() {
Class<Component> annotationType = Component.class;
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
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;
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta1", Meta1.class);
}
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesWithMetaAnnotationWithDefaultAttributes() {
Class<?> startClass = MetaConfigWithDefaultAttributesTestCase.class;
Class<ContextConfiguration> annotationType = ContextConfiguration.class;
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(startClass,
Service.class, ContextConfiguration.class, Order.class, Transactional.class);
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);
}
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesWithMetaAnnotationWithOverriddenAttributes() {
Class<?> startClass = MetaConfigWithOverriddenAttributesTestCase.class;
Class<ContextConfiguration> annotationType = ContextConfiguration.class;
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
startClass, Service.class, ContextConfiguration.class, Order.class, Transactional.class);
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<?>[] {MetaAnnotationUtilsTests.class});
assertThat(descriptor.getComposedAnnotation()).isNotNull();
assertThat(descriptor.getComposedAnnotationType()).isEqualTo(MetaConfig.class);
}
@Test
void findAnnotationDescriptorForTypesForInterfaceWithMetaAnnotation() {
Class<InterfaceWithMetaAnnotation> startClass = InterfaceWithMetaAnnotation.class;
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta1", Meta1.class);
}
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesForClassWithMetaAnnotatedInterface() {
Component rawAnnotation = AnnotationUtils.findAnnotation(ClassWithMetaAnnotatedInterface.class, Component.class);
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
ClassWithMetaAnnotatedInterface.class, Service.class, Component.class, Order.class, Transactional.class);
assertThat(descriptor).isNotNull();
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;
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta2", Meta2.class);
}
@Test
void findAnnotationDescriptorForTypesForSubClassWithLocalMetaAnnotationAndMetaAnnotatedInterface() {
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
SubClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class,
ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class, "meta2", Meta2.class);
}
/**
* @since 4.0.3
*/
@Test
void findAnnotationDescriptorForTypesOnMetaMetaAnnotatedClass() {
Class<MetaMetaAnnotatedClass> startClass = MetaMetaAnnotatedClass.class;
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
startClass, startClass, Meta2.class, "meta2", MetaMeta.class);
}
/**
* @since 4.0.3
*/
@Test
void findAnnotationDescriptorForTypesOnMetaMetaMetaAnnotatedClass() {
Class<MetaMetaMetaAnnotatedClass> startClass = MetaMetaMetaAnnotatedClass.class;
assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(
startClass, startClass, Meta2.class, "meta2", MetaMetaMeta.class);
}
/**
* @since 4.0.3
*/
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesOnAnnotatedClassWithMissingTargetMetaAnnotation() {
// InheritedAnnotationClass is NOT annotated or meta-annotated with @Component,
// @Service, or @Order, but it is annotated with @Transactional.
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
InheritedAnnotationClass.class, Service.class, Component.class, Order.class);
assertThat(descriptor).as("Should not find @Component on InheritedAnnotationClass").isNull();
}
/**
* @since 4.0.3
*/
@Test
@SuppressWarnings("unchecked")
void findAnnotationDescriptorForTypesOnMetaCycleAnnotatedClassWithMissingTargetMetaAnnotation() {
UntypedAnnotationDescriptor descriptor = findAnnotationDescriptorForTypes(
MetaCycleAnnotatedClass.class, Service.class, Component.class, Order.class);
assertThat(descriptor).as("Should not find @Component on MetaCycleAnnotatedClass").isNull();
}
// -------------------------------------------------------------------------
@Component(value = "meta1")
@Order
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
static @interface Meta1 {
}
@Component(value = "meta2")
@Transactional
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
static @interface Meta2 {
}
@Meta2
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@interface MetaMeta {
}
@MetaMeta
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@interface MetaMetaMeta {
}
@MetaCycle3
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
@Documented
@interface MetaCycle1 {
}
@MetaCycle1
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
@Documented
@interface MetaCycle2 {
}
@MetaCycle2
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@interface MetaCycle3 {
}
@ContextConfiguration
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
static @interface MetaConfig {
static class DevConfig {
}
static class ProductionConfig {
}
Class<?>[] classes() default { DevConfig.class, ProductionConfig.class };
}
// -------------------------------------------------------------------------
@Meta1
static class HasMetaComponentAnnotation {
}
@Meta1
@Component(value = "local")
@Meta2
static class HasLocalAndMetaComponentAnnotation {
}
@Meta1
static interface InterfaceWithMetaAnnotation {
}
static class ClassWithMetaAnnotatedInterface implements InterfaceWithMetaAnnotation {
}
@Meta2
static class ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface implements InterfaceWithMetaAnnotation {
}
static class SubClassWithLocalMetaAnnotationAndMetaAnnotatedInterface extends
ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface {
}
@MetaMeta
static class MetaMetaAnnotatedClass {
}
@MetaMetaMeta
static class MetaMetaMetaAnnotatedClass {
}
@MetaCycle3
static class MetaCycleAnnotatedClass {
}
@MetaConfig
class MetaConfigWithDefaultAttributesTestCase {
}
@MetaConfig(classes = MetaAnnotationUtilsTests.class)
class MetaConfigWithOverriddenAttributesTestCase {
}
// -------------------------------------------------------------------------
@Transactional
static interface InheritedAnnotationInterface {
}
static interface SubInheritedAnnotationInterface extends InheritedAnnotationInterface {
}
static interface SubSubInheritedAnnotationInterface extends SubInheritedAnnotationInterface {
}
@Order
static interface NonInheritedAnnotationInterface {
}
static interface SubNonInheritedAnnotationInterface extends NonInheritedAnnotationInterface {
}
static class NonAnnotatedClass {
}
static interface NonAnnotatedInterface {
}
@Transactional
static class InheritedAnnotationClass {
}
static class SubInheritedAnnotationClass extends InheritedAnnotationClass {
}
@Order
static class NonInheritedAnnotationClass {
}
static class SubNonInheritedAnnotationClass extends NonInheritedAnnotationClass {
}
@ContextConfiguration(classes = Number.class)
static class AnnotatedContextConfigClass {
}
@MetaConfig(classes = String.class)
static class MetaAnnotatedAndSuperAnnotatedContextConfigClass extends AnnotatedContextConfigClass {
}
}

158
spring-test/src/test/java/org/springframework/test/util/OverriddenMetaAnnotationAttributesTests.java

@ -0,0 +1,158 @@ @@ -0,0 +1,158 @@
/*
* 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.util;
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.ContextConfiguration;
import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.test.util.MetaAnnotationUtils.findAnnotationDescriptor;
/**
* Unit tests for {@link MetaAnnotationUtils} 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 MetaAnnotationUtilsTests
*/
@SuppressWarnings("deprecation")
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 {
}
}
Loading…
Cancel
Save