use of cn.taketoday.test.context.ContextConfiguration in project today-infrastructure by TAKETODAY.
the class ContextLoaderUtils method resolveContextHierarchyAttributes.
/**
* Resolve the list of lists of {@linkplain ContextConfigurationAttributes context
* configuration attributes} for the supplied {@linkplain Class test class} and its
* superclasses, taking into account context hierarchies declared via
* {@link ContextHierarchy @ContextHierarchy} and
* {@link ContextConfiguration @ContextConfiguration}.
* <p>The outer list represents a top-down ordering of context configuration
* attributes, where each element in the list represents the context configuration
* declared on a given test class in the class hierarchy. Each nested list
* contains the context configuration attributes declared either via a single
* instance of {@code @ContextConfiguration} on the particular class or via
* multiple instances of {@code @ContextConfiguration} declared within a
* single {@code @ContextHierarchy} instance on the particular class.
* Furthermore, each nested list maintains the order in which
* {@code @ContextConfiguration} instances are declared.
* <p>Note that the {@link ContextConfiguration#inheritLocations inheritLocations} and
* {@link ContextConfiguration#inheritInitializers() inheritInitializers} flags of
* {@link ContextConfiguration @ContextConfiguration} will <strong>not</strong>
* be taken into consideration. If these flags need to be honored, that must be
* handled manually when traversing the nested lists returned by this method.
*
* @param testClass the class for which to resolve the context hierarchy attributes
* (must not be {@code null})
* @return the list of lists of configuration attributes for the specified class;
* never {@code null}
* @throws IllegalArgumentException if the supplied class is {@code null}; or if
* neither {@code @ContextConfiguration} nor {@code @ContextHierarchy} is
* <em>present</em> on the supplied class
* @throws IllegalStateException if a test class or composed annotation
* in the class hierarchy declares both {@code @ContextConfiguration} and
* {@code @ContextHierarchy} as top-level annotations.
* @see #buildContextHierarchyMap(Class)
* @see #resolveContextConfigurationAttributes(Class)
* @since 4.0
*/
@SuppressWarnings("unchecked")
static List<List<ContextConfigurationAttributes>> resolveContextHierarchyAttributes(Class<?> testClass) {
Assert.notNull(testClass, "Class must not be null");
Class<ContextConfiguration> contextConfigType = ContextConfiguration.class;
Class<ContextHierarchy> contextHierarchyType = ContextHierarchy.class;
List<List<ContextConfigurationAttributes>> hierarchyAttributes = new ArrayList<>();
UntypedAnnotationDescriptor desc = findAnnotationDescriptorForTypes(testClass, contextConfigType, contextHierarchyType);
Assert.notNull(desc, () -> String.format("Could not find an 'annotation declaring class' for annotation type [%s] or [%s] and test class [%s]", contextConfigType.getName(), contextHierarchyType.getName(), testClass.getName()));
while (desc != null) {
Class<?> rootDeclaringClass = desc.getRootDeclaringClass();
Class<?> declaringClass = desc.getDeclaringClass();
boolean contextConfigDeclaredLocally = isAnnotationDeclaredLocally(contextConfigType, declaringClass);
boolean contextHierarchyDeclaredLocally = isAnnotationDeclaredLocally(contextHierarchyType, declaringClass);
if (contextConfigDeclaredLocally && contextHierarchyDeclaredLocally) {
String msg = String.format("Class [%s] has been configured with both @ContextConfiguration " + "and @ContextHierarchy. Only one of these annotations may be declared on a test class " + "or composed annotation.", declaringClass.getName());
logger.error(msg);
throw new IllegalStateException(msg);
}
List<ContextConfigurationAttributes> configAttributesList = new ArrayList<>();
if (contextConfigDeclaredLocally) {
ContextConfiguration contextConfiguration = (ContextConfiguration) desc.getAnnotation();
convertContextConfigToConfigAttributesAndAddToList(contextConfiguration, rootDeclaringClass, configAttributesList);
} else if (contextHierarchyDeclaredLocally) {
ContextHierarchy contextHierarchy = getAnnotation(declaringClass, contextHierarchyType);
if (contextHierarchy != null) {
for (ContextConfiguration contextConfiguration : contextHierarchy.value()) {
convertContextConfigToConfigAttributesAndAddToList(contextConfiguration, rootDeclaringClass, configAttributesList);
}
}
} else {
// This should theoretically never happen...
String msg = String.format("Test class [%s] has been configured with neither @ContextConfiguration " + "nor @ContextHierarchy as a class-level annotation.", rootDeclaringClass.getName());
logger.error(msg);
throw new IllegalStateException(msg);
}
hierarchyAttributes.add(0, configAttributesList);
desc = desc.next();
}
return hierarchyAttributes;
}
use of cn.taketoday.test.context.ContextConfiguration in project today-infrastructure by TAKETODAY.
the class ContextLoaderUtils method resolveContextConfigurationAttributes.
/**
* Resolve the list of {@linkplain ContextConfigurationAttributes context
* configuration attributes} for the supplied {@linkplain Class test class} and its
* superclasses.
* <p>Note that the {@link ContextConfiguration#inheritLocations inheritLocations} and
* {@link ContextConfiguration#inheritInitializers() inheritInitializers} flags of
* {@link ContextConfiguration @ContextConfiguration} will <strong>not</strong>
* be taken into consideration. If these flags need to be honored, that must be
* handled manually when traversing the list returned by this method.
*
* @param testClass the class for which to resolve the configuration attributes
* (must not be {@code null})
* @return the list of configuration attributes for the specified class, ordered
* <em>bottom-up</em> (i.e., as if we were traversing up the class hierarchy);
* never {@code null}
* @throws IllegalArgumentException if the supplied class is {@code null} or if
* {@code @ContextConfiguration} is not <em>present</em> on the supplied class
*/
static List<ContextConfigurationAttributes> resolveContextConfigurationAttributes(Class<?> testClass) {
Assert.notNull(testClass, "Class must not be null");
Class<ContextConfiguration> annotationType = ContextConfiguration.class;
AnnotationDescriptor<ContextConfiguration> descriptor = findAnnotationDescriptor(testClass, annotationType);
Assert.notNull(descriptor, () -> String.format("Could not find an 'annotation declaring class' for annotation type [%s] and class [%s]", annotationType.getName(), testClass.getName()));
List<ContextConfigurationAttributes> attributesList = new ArrayList<>();
ContextConfiguration previousAnnotation = null;
Class<?> previousDeclaringClass = null;
while (descriptor != null) {
ContextConfiguration currentAnnotation = descriptor.getAnnotation();
// annotated class.
if (currentAnnotation.equals(previousAnnotation) && hasResources(currentAnnotation)) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Ignoring duplicate %s declaration on [%s], " + "since it is also declared on [%s].", currentAnnotation, previousDeclaringClass.getName(), descriptor.getRootDeclaringClass().getName()));
}
} else {
convertContextConfigToConfigAttributesAndAddToList(currentAnnotation, descriptor.getRootDeclaringClass(), attributesList);
}
previousAnnotation = currentAnnotation;
previousDeclaringClass = descriptor.getRootDeclaringClass();
descriptor = descriptor.next();
}
return attributesList;
}
use of cn.taketoday.test.context.ContextConfiguration in project today-infrastructure by TAKETODAY.
the class ApplicationTestContextBootstrapper method isWebEnvironmentSupported.
private boolean isWebEnvironmentSupported(MergedContextConfiguration mergedConfig) {
Class<?> testClass = mergedConfig.getTestClass();
ContextHierarchy hierarchy = AnnotationUtils.getAnnotation(testClass, ContextHierarchy.class);
if (hierarchy == null || hierarchy.value().length == 0) {
return true;
}
ContextConfiguration[] configurations = hierarchy.value();
return isFromConfiguration(mergedConfig, configurations[configurations.length - 1]);
}
Aggregations