diff --git a/spring-test/src/main/java/org/springframework/test/context/TestContextAnnotationUtils.java b/spring-test/src/main/java/org/springframework/test/context/TestContextAnnotationUtils.java index 949ed8afbc..fa7a2e63e0 100644 --- a/spring-test/src/main/java/org/springframework/test/context/TestContextAnnotationUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/TestContextAnnotationUtils.java @@ -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 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 declared - * as well as the actual {@linkplain #getAnnotation() annotation} instance. - *

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 root declaring class is - * not directly annotated with the annotation but rather indirectly via the - * composed annotation. + * as well as the {@linkplain #getAnnotation() merged annotation} instance. + *

If the annotation is used as a meta-annotation, the root declaring + * class is not directly annotated with the annotation but rather + * indirectly via a composed annotation. *

Given the following example, if we are searching for the {@code @Transactional} * annotation on the {@code TransactionalTests} class, then the * properties of the {@code AnnotationDescriptor} would be as follows. *

*

@@ -465,7 +459,6 @@ public abstract class TestContextAnnotationUtils {
 	 * 
 	 * 

@@ -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) this.annotation.annotationType();
 		}
 
-		AnnotationAttributes getAnnotationAttributes() {
-			return this.annotationAttributes;
-		}
-
-		@Nullable
-		Annotation getComposedAnnotation() {
-			return this.composedAnnotation;
-		}
-
-		@Nullable
-		Class 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.
 		 * 

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 all 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 all 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[] annotationTypes) { - this(rootDeclaringClass, rootDeclaringClass, null, annotation, annotationTypes); + this(rootDeclaringClass, rootDeclaringClass, annotation, annotationTypes); } UntypedAnnotationDescriptor(Class rootDeclaringClass, Class declaringClass, - @Nullable Annotation composedAnnotation, Annotation annotation, - Class[] annotationTypes) { + Annotation annotation, Class[] annotationTypes) { - super(rootDeclaringClass, declaringClass, composedAnnotation, annotation); + super(rootDeclaringClass, declaringClass, annotation); this.annotationTypes = annotationTypes; } diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java index 06fee14ec5..17bddaf5b4 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java @@ -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())); diff --git a/spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java index 3cb723130e..901b1d3a72 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/ActiveProfilesUtils.java @@ -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]", diff --git a/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java index 983dc31401..8e37932c55 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/ContextLoaderUtils.java @@ -126,7 +126,7 @@ abstract class ContextLoaderUtils { List 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. diff --git a/spring-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java b/spring-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java index 6f87fb0289..a15606d1b7 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/DefaultActiveProfilesResolver.java @@ -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())); diff --git a/spring-test/src/test/java/org/springframework/test/context/OverriddenMetaAnnotationAttributesTestContextAnnotationUtilsTests.java b/spring-test/src/test/java/org/springframework/test/context/OverriddenMetaAnnotationAttributesTestContextAnnotationUtilsTests.java new file mode 100644 index 0000000000..aaafad4413 --- /dev/null +++ b/spring-test/src/test/java/org/springframework/test/context/OverriddenMetaAnnotationAttributesTestContextAnnotationUtilsTests.java @@ -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. + * + *

See SPR-10181. + * + * @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 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 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 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 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 { + } + +} diff --git a/spring-test/src/test/java/org/springframework/test/context/OverriddenMetaAnnotationAttributesTests.java b/spring-test/src/test/java/org/springframework/test/context/OverriddenMetaAnnotationAttributesTests.java deleted file mode 100644 index a38664f247..0000000000 --- a/spring-test/src/test/java/org/springframework/test/context/OverriddenMetaAnnotationAttributesTests.java +++ /dev/null @@ -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. - * - *

See SPR-10181. - * - * @author Sam Brannen - * @since 4.0 - * @see TestContextAnnotationUtilsTests - */ -class OverriddenMetaAnnotationAttributesTests { - - @Test - void contextConfigurationValue() throws Exception { - Class declaringClass = MetaValueConfigTestCase.class; - AnnotationDescriptor 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 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 declaringClass = MetaLocationsConfigTestCase.class; - AnnotationDescriptor 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 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 { - } - -} diff --git a/spring-test/src/test/java/org/springframework/test/context/TestContextAnnotationUtilsTests.java b/spring-test/src/test/java/org/springframework/test/context/TestContextAnnotationUtilsTests.java index 3c2b7c0355..d5eee230de 100644 --- a/spring-test/src/test/java/org/springframework/test/context/TestContextAnnotationUtilsTests.java +++ b/spring-test/src/test/java/org/springframework/test/context/TestContextAnnotationUtilsTests.java @@ -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 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 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 composedAnnotationType) { - assertAtComponentOnComposedAnnotation(startClass, rootDeclaringClass, composedAnnotationType, name, composedAnnotationType); + assertAtComponentOnComposedAnnotation(startClass, rootDeclaringClass, composedAnnotationType, name); } private void assertAtComponentOnComposedAnnotation(Class startClass, Class rootDeclaringClass, - Class declaringClass, String name, Class composedAnnotationType) { + Class declaringClass, String name) { AnnotationDescriptor 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 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 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 startClass = ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class; + Class startClass = ClassWithLocalMetaAnnotationAndMetaAnnotatedInterface.class; assertAtComponentOnComposedAnnotationForMultipleCandidateTypes(startClass, "meta2", Meta2.class); } @@ -447,9 +436,9 @@ class TestContextAnnotationUtilsTests { */ @Test void findAnnotationDescriptorForTypesOnMetaMetaAnnotatedClass() { - Class 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 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 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 composedAnnotationType) { + Class rootDeclaringClass, Class declaringClass, String name) { Class 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); } }