Nullability refinements (no IntelliJ warnings, fewer null checks)
Includes consistent ignoring of all java.lang (meta-)annotations. Closes gh-22586
This commit is contained in:
@@ -700,17 +700,12 @@ public class AnnotatedElementUtilsTests {
|
||||
assertArrayEquals("path attribute: ", asArray("/test"), webMapping.path());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void javaLangAnnotationTypeViaFindMergedAnnotation() throws Exception {
|
||||
Constructor<?> deprecatedCtor = Date.class.getConstructor(String.class);
|
||||
assertEquals(deprecatedCtor.getAnnotation(Deprecated.class), findMergedAnnotation(deprecatedCtor, Deprecated.class));
|
||||
assertEquals(Date.class.getAnnotation(Deprecated.class), findMergedAnnotation(Date.class, Deprecated.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void javaxAnnotationTypeViaFindMergedAnnotation() throws Exception {
|
||||
assertEquals(ResourceHolder.class.getAnnotation(Resource.class), findMergedAnnotation(ResourceHolder.class, Resource.class));
|
||||
assertEquals(SpringAppConfigClass.class.getAnnotation(Resource.class), findMergedAnnotation(SpringAppConfigClass.class, Resource.class));
|
||||
assertEquals(ResourceHolder.class.getAnnotation(Resource.class),
|
||||
findMergedAnnotation(ResourceHolder.class, Resource.class));
|
||||
assertEquals(SpringAppConfigClass.class.getAnnotation(Resource.class),
|
||||
findMergedAnnotation(SpringAppConfigClass.class, Resource.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -16,19 +16,16 @@
|
||||
|
||||
package org.springframework.core.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Tests for {@link AnnotationFilter}.
|
||||
@@ -37,35 +34,22 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
*/
|
||||
public class AnnotationFilterTests {
|
||||
|
||||
private static final AnnotationFilter FILTER = annotationType -> ObjectUtils.nullSafeEquals(
|
||||
annotationType, TestAnnotation.class.getName());
|
||||
private static final AnnotationFilter FILTER = annotationType ->
|
||||
ObjectUtils.nullSafeEquals(annotationType, TestAnnotation.class.getName());
|
||||
|
||||
@Test
|
||||
public void matchesAnnotationWhenAnnotationIsNullReturnsFalse() {
|
||||
TestAnnotation annotation = null;
|
||||
assertThat(FILTER.matches(annotation)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchesAnnotationWhenMatchReturnsTrue() {
|
||||
TestAnnotation annotation = WithTestAnnotation.class.getDeclaredAnnotation(
|
||||
TestAnnotation.class);
|
||||
TestAnnotation annotation = WithTestAnnotation.class.getDeclaredAnnotation(TestAnnotation.class);
|
||||
assertThat(FILTER.matches(annotation)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchesAnnotationWhenNoMatchReturnsFalse() {
|
||||
OtherAnnotation annotation = WithOtherAnnotation.class.getDeclaredAnnotation(
|
||||
OtherAnnotation.class);
|
||||
OtherAnnotation annotation = WithOtherAnnotation.class.getDeclaredAnnotation(OtherAnnotation.class);
|
||||
assertThat(FILTER.matches(annotation)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchesAnnotationClassWhenAnnotationClassIsNullReturnsFalse() {
|
||||
Class<Annotation> annotationType = null;
|
||||
assertThat(FILTER.matches(annotationType)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchesAnnotationClassWhenMatchReturnsTrue() {
|
||||
Class<TestAnnotation> annotationType = TestAnnotation.class;
|
||||
@@ -109,27 +93,15 @@ public class AnnotationFilterTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noneWhenNonNullReturnsFalse() {
|
||||
public void noneReturnsFalse() {
|
||||
assertThat(AnnotationFilter.NONE.matches(Retention.class)).isFalse();
|
||||
assertThat(AnnotationFilter.NONE.matches(Nullable.class)).isFalse();
|
||||
assertThat(AnnotationFilter.NONE.matches(TestAnnotation.class)).isFalse();
|
||||
assertThat(AnnotationFilter.NONE.matches((Annotation) null)).isFalse();
|
||||
assertThat(AnnotationFilter.NONE.matches((Class<Annotation>) null)).isFalse();
|
||||
assertThat(AnnotationFilter.NONE.matches((String) null)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void pacakgesReturnsPackagesAnnotationFilter() {
|
||||
assertThat(AnnotationFilter.packages("com.example")).isInstanceOf(
|
||||
PackagesAnnotationFilter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mostAppropriateForCollectionWhenAnnotationTypesIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> AnnotationFilter.mostAppropriateFor(
|
||||
(Collection<Class<? extends Annotation>>) null)).withMessage(
|
||||
"AnnotationTypes must not be null");
|
||||
assertThat(AnnotationFilter.packages("com.example")).isInstanceOf(PackagesAnnotationFilter.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,14 +118,6 @@ public class AnnotationFilterTests {
|
||||
assertThat(filter).isSameAs(AnnotationFilter.NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mostAppropriateForArrayWhenAnnotationTypesIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> AnnotationFilter.mostAppropriateFor(
|
||||
(Class<? extends Annotation>[]) null)).withMessage(
|
||||
"AnnotationTypes must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mostAppropriateForArrayReturnsPlainWhenPossible() {
|
||||
AnnotationFilter filter = AnnotationFilter.mostAppropriateFor(
|
||||
@@ -168,24 +132,21 @@ public class AnnotationFilterTests {
|
||||
assertThat(filter).isSameAs(AnnotationFilter.NONE);
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface TestAnnotation {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface TestAnnotation {
|
||||
}
|
||||
|
||||
@TestAnnotation
|
||||
static class WithTestAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface OtherAnnotation {
|
||||
|
||||
@interface OtherAnnotation {
|
||||
}
|
||||
|
||||
@OtherAnnotation
|
||||
static class WithOtherAnnotation {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -47,35 +46,24 @@ import static org.assertj.core.api.Assertions.*;
|
||||
*/
|
||||
public class AnnotationTypeMappingsTests {
|
||||
|
||||
@Test
|
||||
public void forAnnotationTypeWhenAnnotationIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> AnnotationTypeMappings.forAnnotationType(null)).withMessage(
|
||||
"AnnotationType must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forAnnotationTypeWhenNoMetaAnnotationsReturnsMappings() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
|
||||
SimpleAnnotation.class);
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(SimpleAnnotation.class);
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(mappings.get(0).getAnnotationType()).isEqualTo(SimpleAnnotation.class);
|
||||
assertThat(getAll(mappings)).flatExtracting(
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(
|
||||
SimpleAnnotation.class);
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(SimpleAnnotation.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forAnnotationWhenHasSpringAnnotationReturnsFilteredMappings() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
|
||||
WithSpringLangAnnotation.class);
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithSpringLangAnnotation.class);
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forAnnotationTypeWhenMetaAnnotationsReturnsMappings() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
|
||||
MetaAnnotated.class);
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(MetaAnnotated.class);
|
||||
assertThat(mappings.size()).isEqualTo(6);
|
||||
assertThat(getAll(mappings)).flatExtracting(
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(
|
||||
@@ -85,33 +73,27 @@ public class AnnotationTypeMappingsTests {
|
||||
|
||||
@Test
|
||||
public void forAnnotationTypeWhenHasRepeatingMetaAnnotationReturnsMapping() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
|
||||
WithRepeatedMetaAnnotations.class);
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(WithRepeatedMetaAnnotations.class);
|
||||
assertThat(mappings.size()).isEqualTo(3);
|
||||
assertThat(getAll(mappings)).flatExtracting(
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(
|
||||
WithRepeatedMetaAnnotations.class, Repeating.class,
|
||||
Repeating.class);
|
||||
WithRepeatedMetaAnnotations.class, Repeating.class, Repeating.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forAnnotationTypeWhenSelfAnnotatedReturnsMapping() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
|
||||
SelfAnnotated.class);
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(SelfAnnotated.class);
|
||||
assertThat(mappings.size()).isEqualTo(1);
|
||||
assertThat(getAll(mappings)).flatExtracting(
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(
|
||||
SelfAnnotated.class);
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(SelfAnnotated.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forAnnotationTypeWhenFormsLoopReturnsMapping() {
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(
|
||||
LoopA.class);
|
||||
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(LoopA.class);
|
||||
assertThat(mappings.size()).isEqualTo(2);
|
||||
assertThat(getAll(mappings)).flatExtracting(
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(LoopA.class,
|
||||
LoopB.class);
|
||||
AnnotationTypeMapping::getAnnotationType).containsExactly(LoopA.class, LoopB.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -540,13 +540,6 @@ public class AnnotationUtilsTests {
|
||||
assertEquals(Ordered.LOWEST_PRECEDENCE, getDefaultValue(Order.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findRepeatableAnnotationOnComposedAnnotation() {
|
||||
Repeatable repeatable = findAnnotation(MyRepeatableMeta1.class, Repeatable.class);
|
||||
assertNotNull(repeatable);
|
||||
assertEquals(MyRepeatableContainer.class, repeatable.value());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepeatableAnnotationsDeclaredOnMethod() throws Exception {
|
||||
Method method = InterfaceWithRepeated.class.getMethod("foo");
|
||||
|
||||
@@ -511,6 +511,7 @@ public class AnnotationsScannerTests {
|
||||
assertThat(result).isEqualTo("OK");
|
||||
}
|
||||
|
||||
|
||||
private Method methodFrom(Class<?> type) {
|
||||
return ReflectionUtils.findMethod(type, "method");
|
||||
}
|
||||
@@ -532,81 +533,68 @@ public class AnnotationsScannerTests {
|
||||
return result.stream();
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface TestAnnotation1 {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface TestAnnotation1 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface TestAnnotation2 {
|
||||
|
||||
@interface TestAnnotation2 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface TestAnnotation3 {
|
||||
|
||||
@interface TestAnnotation3 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface TestAnnotation4 {
|
||||
|
||||
@interface TestAnnotation4 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface TestAnnotation5 {
|
||||
|
||||
@interface TestAnnotation5 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface TestAnnotation6 {
|
||||
|
||||
@interface TestAnnotation6 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
static @interface TestInheritedAnnotation1 {
|
||||
|
||||
@interface TestInheritedAnnotation1 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
static @interface TestInheritedAnnotation2 {
|
||||
|
||||
@interface TestInheritedAnnotation2 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
static @interface TestInheritedAnnotation3 {
|
||||
|
||||
@interface TestInheritedAnnotation3 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
static @interface TestInheritedAnnotation4 {
|
||||
|
||||
@interface TestInheritedAnnotation4 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Inherited
|
||||
static @interface TestInheritedAnnotation5 {
|
||||
|
||||
@interface TestInheritedAnnotation5 {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface OnSuperClass {
|
||||
|
||||
@interface OnSuperClass {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface OnInterface {
|
||||
|
||||
@interface OnInterface {
|
||||
}
|
||||
|
||||
static class WithNoAnnotations {
|
||||
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation1
|
||||
@@ -615,7 +603,6 @@ public class AnnotationsScannerTests {
|
||||
@TestAnnotation1
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation1
|
||||
@@ -626,7 +613,6 @@ public class AnnotationsScannerTests {
|
||||
@TestAnnotation2
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation2
|
||||
@@ -637,7 +623,6 @@ public class AnnotationsScannerTests {
|
||||
@TestInheritedAnnotation2
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation1
|
||||
@@ -646,7 +631,6 @@ public class AnnotationsScannerTests {
|
||||
@TestAnnotation1
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestInheritedAnnotation2
|
||||
@@ -655,7 +639,6 @@ public class AnnotationsScannerTests {
|
||||
@TestAnnotation1
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation1
|
||||
@@ -664,17 +647,15 @@ public class AnnotationsScannerTests {
|
||||
@TestAnnotation1
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation2
|
||||
@TestInheritedAnnotation2
|
||||
static interface SingleInterface {
|
||||
interface SingleInterface {
|
||||
|
||||
@TestAnnotation2
|
||||
@TestInheritedAnnotation2
|
||||
public void method();
|
||||
|
||||
void method();
|
||||
}
|
||||
|
||||
@TestAnnotation1
|
||||
@@ -683,7 +664,6 @@ public class AnnotationsScannerTests {
|
||||
@TestAnnotation1
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation2
|
||||
@@ -694,7 +674,6 @@ public class AnnotationsScannerTests {
|
||||
@TestInheritedAnnotation2
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation3
|
||||
@@ -703,33 +682,29 @@ public class AnnotationsScannerTests {
|
||||
@TestAnnotation3
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation4
|
||||
static interface HierarchySuperSuperclassInterface {
|
||||
interface HierarchySuperSuperclassInterface {
|
||||
|
||||
@TestAnnotation4
|
||||
public void method();
|
||||
|
||||
void method();
|
||||
}
|
||||
|
||||
@TestAnnotation5
|
||||
@TestInheritedAnnotation5
|
||||
static interface HierarchyInterface extends HierarchyInterfaceInterface {
|
||||
interface HierarchyInterface extends HierarchyInterfaceInterface {
|
||||
|
||||
@TestAnnotation5
|
||||
@TestInheritedAnnotation5
|
||||
public void method();
|
||||
|
||||
void method();
|
||||
}
|
||||
|
||||
@TestAnnotation6
|
||||
static interface HierarchyInterfaceInterface {
|
||||
interface HierarchyInterfaceInterface {
|
||||
|
||||
@TestAnnotation6
|
||||
public void method();
|
||||
|
||||
void method();
|
||||
}
|
||||
|
||||
static class BridgedMethod implements BridgeMethod<String> {
|
||||
@@ -738,37 +713,32 @@ public class AnnotationsScannerTests {
|
||||
@TestAnnotation1
|
||||
public void method(String arg) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static interface BridgeMethod<T> {
|
||||
interface BridgeMethod<T> {
|
||||
|
||||
@TestAnnotation2
|
||||
void method(T arg);
|
||||
|
||||
}
|
||||
|
||||
static class Ignoreable implements IgnoreableOverrideInterface1,
|
||||
IgnoreableOverrideInterface2, Serializable {
|
||||
@SuppressWarnings("serial")
|
||||
static class Ignoreable implements IgnoreableOverrideInterface1, IgnoreableOverrideInterface2, Serializable {
|
||||
|
||||
@TestAnnotation1
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static interface IgnoreableOverrideInterface1 {
|
||||
interface IgnoreableOverrideInterface1 {
|
||||
|
||||
@Nullable
|
||||
public void method();
|
||||
|
||||
void method();
|
||||
}
|
||||
|
||||
static interface IgnoreableOverrideInterface2 {
|
||||
interface IgnoreableOverrideInterface2 {
|
||||
|
||||
@Nullable
|
||||
public void method();
|
||||
|
||||
void method();
|
||||
}
|
||||
|
||||
static abstract class MultipleMethods implements MultipleMethodsInterface {
|
||||
@@ -776,7 +746,6 @@ public class AnnotationsScannerTests {
|
||||
@TestAnnotation1
|
||||
public void method() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface MultipleMethodsInterface {
|
||||
@@ -786,23 +755,19 @@ public class AnnotationsScannerTests {
|
||||
|
||||
@TestAnnotation2
|
||||
void method1();
|
||||
|
||||
}
|
||||
|
||||
static class GenericOverride implements GenericOverrideInterface<String> {
|
||||
|
||||
@TestAnnotation1
|
||||
public void method(String argument) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static interface GenericOverrideInterface<T extends CharSequence> {
|
||||
interface GenericOverrideInterface<T extends CharSequence> {
|
||||
|
||||
@TestAnnotation2
|
||||
void method(T argument);
|
||||
|
||||
}
|
||||
|
||||
static abstract class GenericNonOverride
|
||||
@@ -810,16 +775,13 @@ public class AnnotationsScannerTests {
|
||||
|
||||
@TestAnnotation1
|
||||
public void method(StringBuilder argument) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static interface GenericNonOverrideInterface<T extends CharSequence> {
|
||||
interface GenericNonOverrideInterface<T extends CharSequence> {
|
||||
|
||||
@TestAnnotation2
|
||||
void method(T argument);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -31,8 +30,7 @@ import org.junit.Test;
|
||||
import org.springframework.core.annotation.MergedAnnotation.MapValues;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Tests for {@link MergedAnnotationCollectors}.
|
||||
@@ -93,18 +91,10 @@ public class MergedAnnotationCollectorsTests {
|
||||
assertThat(map.get("finished")).containsExactly(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public void toFinishedMultiValueMapWhenFinisherIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> stream().collect(
|
||||
MergedAnnotationCollectors.toMultiValueMap((Function) null))).withMessage(
|
||||
"Finisher must not be null");
|
||||
private Stream<MergedAnnotation<TestAnnotation>> stream() {
|
||||
return MergedAnnotations.from(WithTestAnnotations.class).stream(TestAnnotation.class);
|
||||
}
|
||||
|
||||
private Stream<MergedAnnotation<TestAnnotation>> stream() {
|
||||
return MergedAnnotations.from(WithTestAnnotations.class).stream(
|
||||
TestAnnotation.class);
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Repeatable(TestAnnotations.class)
|
||||
@@ -124,14 +114,12 @@ public class MergedAnnotationCollectorsTests {
|
||||
@interface TestAnnotations {
|
||||
|
||||
TestAnnotation[] value();
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation("a")
|
||||
@TestAnnotation(name = "b", extra = String.class)
|
||||
@TestAnnotation(name = "c", extra = Integer.class)
|
||||
static class WithTestAnnotations {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,20 +16,17 @@
|
||||
|
||||
package org.springframework.core.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* Tests for {@link MergedAnnotationPredicates}.
|
||||
@@ -54,35 +51,18 @@ public class MergedAnnotationPredicatesTests {
|
||||
MissingAnnotation.class.getName())).rejects(annotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeInStringArrayWhenStringArraysIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> MergedAnnotationPredicates.typeIn((String[]) null)).withMessage(
|
||||
"TypeNames must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeInClassArrayWhenNameMatchesAccepts() {
|
||||
MergedAnnotation<TestAnnotation> annotation = MergedAnnotations.from(
|
||||
WithTestAnnotation.class).get(TestAnnotation.class);
|
||||
assertThat(MergedAnnotationPredicates.typeIn(TestAnnotation.class)).accepts(
|
||||
annotation);
|
||||
MergedAnnotation<TestAnnotation> annotation =
|
||||
MergedAnnotations.from(WithTestAnnotation.class).get(TestAnnotation.class);
|
||||
assertThat(MergedAnnotationPredicates.typeIn(TestAnnotation.class)).accepts(annotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeInClassArrayWhenNameDoesNotMatchRejects() {
|
||||
MergedAnnotation<TestAnnotation> annotation = MergedAnnotations.from(
|
||||
WithTestAnnotation.class).get(TestAnnotation.class);
|
||||
assertThat(MergedAnnotationPredicates.typeIn(MissingAnnotation.class)).rejects(
|
||||
annotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeInClassArrayWhenClassArraysIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> MergedAnnotationPredicates.typeIn(
|
||||
(Class<Annotation>[]) null)).withMessage(
|
||||
"Types must not be null");
|
||||
MergedAnnotation<TestAnnotation> annotation =
|
||||
MergedAnnotations.from(WithTestAnnotation.class).get(TestAnnotation.class);
|
||||
assertThat(MergedAnnotationPredicates.typeIn(MissingAnnotation.class)).rejects(annotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,8 +70,7 @@ public class MergedAnnotationPredicatesTests {
|
||||
MergedAnnotation<TestAnnotation> annotation = MergedAnnotations.from(
|
||||
WithTestAnnotation.class).get(TestAnnotation.class);
|
||||
assertThat(MergedAnnotationPredicates.typeIn(
|
||||
Collections.singleton(TestAnnotation.class.getName()))).accepts(
|
||||
annotation);
|
||||
Collections.singleton(TestAnnotation.class.getName()))).accepts(annotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -107,15 +86,7 @@ public class MergedAnnotationPredicatesTests {
|
||||
MergedAnnotation<TestAnnotation> annotation = MergedAnnotations.from(
|
||||
WithTestAnnotation.class).get(TestAnnotation.class);
|
||||
assertThat(MergedAnnotationPredicates.typeIn(Arrays.asList(
|
||||
MissingAnnotation.class.getName(), MissingAnnotation.class))).rejects(
|
||||
annotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeInCollectionWhenCollectionIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> MergedAnnotationPredicates.typeIn(
|
||||
(Collection<?>) null)).withMessage("Types must not be null");
|
||||
MissingAnnotation.class.getName(), MissingAnnotation.class))).rejects(annotation);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -125,15 +96,13 @@ public class MergedAnnotationPredicatesTests {
|
||||
MergedAnnotationPredicates.firstRunOf(
|
||||
this::firstCharOfValue)).collect(Collectors.toList());
|
||||
assertThat(filtered.stream().map(
|
||||
annotation -> annotation.getString("value"))).containsExactly("a1", "a2",
|
||||
"a3");
|
||||
annotation -> annotation.getString("value"))).containsExactly("a1", "a2", "a3");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void firstRunOfWhenValueExtractorIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> MergedAnnotationPredicates.firstRunOf(null)).withMessage(
|
||||
"ValueExtractor must not be null");
|
||||
() -> MergedAnnotationPredicates.firstRunOf(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,42 +112,38 @@ public class MergedAnnotationPredicatesTests {
|
||||
MergedAnnotationPredicates.unique(
|
||||
this::firstCharOfValue)).collect(Collectors.toList());
|
||||
assertThat(filtered.stream().map(
|
||||
annotation -> annotation.getString("value"))).containsExactly("a1", "b1",
|
||||
"c1");
|
||||
annotation -> annotation.getString("value"))).containsExactly("a1", "b1", "c1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uniqueWhenKeyExtractorIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> MergedAnnotationPredicates.unique(null)).withMessage(
|
||||
"KeyExtractor must not be null");
|
||||
() -> MergedAnnotationPredicates.unique(null));
|
||||
}
|
||||
|
||||
private char firstCharOfValue(MergedAnnotation<TestAnnotation> annotation) {
|
||||
return annotation.getString("value").charAt(0);
|
||||
}
|
||||
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Repeatable(TestAnnotations.class)
|
||||
static @interface TestAnnotation {
|
||||
@interface TestAnnotation {
|
||||
|
||||
String value() default "";
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
static @interface TestAnnotations {
|
||||
@interface TestAnnotations {
|
||||
|
||||
TestAnnotation[] value();
|
||||
|
||||
}
|
||||
|
||||
static @interface MissingAnnotation {
|
||||
|
||||
@interface MissingAnnotation {
|
||||
}
|
||||
|
||||
@TestAnnotation("test")
|
||||
static class WithTestAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@TestAnnotation("a1")
|
||||
@@ -191,7 +156,6 @@ public class MergedAnnotationPredicatesTests {
|
||||
@TestAnnotation("c2")
|
||||
@TestAnnotation("c3")
|
||||
static class WithMultipleTestAnnotation {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,19 +24,16 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -74,44 +71,41 @@ public class MergedAnnotationsTests {
|
||||
|
||||
@Test
|
||||
public void streamWhenFromNonAnnotatedClass() {
|
||||
assertThat(MergedAnnotations.from(NonAnnotatedClass.class).stream(
|
||||
TransactionalComponent.class)).isEmpty();
|
||||
assertThat(MergedAnnotations.from(NonAnnotatedClass.class).
|
||||
stream(TransactionalComponent.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void streamWhenFromClassWithMetaDepth1() {
|
||||
Stream<String> names = MergedAnnotations.from(
|
||||
TransactionalComponent.class).stream().map(MergedAnnotation::getType);
|
||||
Stream<String> names = MergedAnnotations.from(TransactionalComponent.class)
|
||||
.stream().map(MergedAnnotation::getType);
|
||||
assertThat(names).containsExactly(Transactional.class.getName(),
|
||||
Component.class.getName(), Indexed.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void streamWhenFromClassWithMetaDepth2() {
|
||||
Stream<String> names = MergedAnnotations.from(
|
||||
ComposedTransactionalComponent.class).stream().map(
|
||||
MergedAnnotation::getType);
|
||||
Stream<String> names = MergedAnnotations.from(ComposedTransactionalComponent.class)
|
||||
.stream().map(MergedAnnotation::getType);
|
||||
assertThat(names).containsExactly(TransactionalComponent.class.getName(),
|
||||
Transactional.class.getName(), Component.class.getName(),
|
||||
Indexed.class.getName());
|
||||
Transactional.class.getName(), Component.class.getName(), Indexed.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPresentWhenFromNonAnnotatedClass() {
|
||||
assertThat(MergedAnnotations.from(NonAnnotatedClass.class).isPresent(
|
||||
Transactional.class)).isFalse();
|
||||
assertThat(MergedAnnotations.from(NonAnnotatedClass.class).
|
||||
isPresent(Transactional.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPresentWhenFromAnnotationClassWithMetaDepth0() {
|
||||
assertThat(MergedAnnotations.from(TransactionalComponent.class).isPresent(
|
||||
TransactionalComponent.class)).isFalse();
|
||||
assertThat(MergedAnnotations.from(TransactionalComponent.class).
|
||||
isPresent(TransactionalComponent.class)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPresentWhenFromAnnotationClassWithMetaDepth1() {
|
||||
MergedAnnotations annotations = MergedAnnotations.from(
|
||||
TransactionalComponent.class);
|
||||
MergedAnnotations annotations = MergedAnnotations.from(TransactionalComponent.class);
|
||||
assertThat(annotations.isPresent(Transactional.class)).isTrue();
|
||||
assertThat(annotations.isPresent(Component.class)).isTrue();
|
||||
}
|
||||
@@ -204,8 +198,6 @@ public class MergedAnnotationsTests {
|
||||
* type within the class hierarchy. Such undesirable behavior would cause
|
||||
* the logic in
|
||||
* {@link org.springframework.context.annotation.ProfileCondition} to fail.
|
||||
*
|
||||
* @see org.springframework.core.env.EnvironmentSystemIntegrationTests#mostSpecificDerivedClassDrivesEnvironment_withDevEnvAndDerivedDevConfigClass
|
||||
*/
|
||||
@Test
|
||||
public void collectMultiValueMapFromClassWithLocalAnnotationThatShadowsAnnotationFromSuperclass() {
|
||||
@@ -218,8 +210,6 @@ public class MergedAnnotationsTests {
|
||||
/**
|
||||
* Note: this functionality is required by
|
||||
* {@link org.springframework.context.annotation.ProfileCondition}.
|
||||
*
|
||||
* @see org.springframework.core.env.EnvironmentSystemIntegrationTests
|
||||
*/
|
||||
@Test
|
||||
public void collectMultiValueMapFromClassWithMultipleComposedAnnotations() {
|
||||
@@ -629,38 +619,26 @@ public class MergedAnnotationsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWithExhaustiveOnMethodWithSingleElementOverridingAnArrayViaConvention()
|
||||
throws Exception {
|
||||
public void getWithExhaustiveOnMethodWithSingleElementOverridingAnArrayViaConvention() throws Exception {
|
||||
testGetWithExhaustiveWebMapping(
|
||||
WebController.class.getMethod("postMappedWithPathAttribute"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWithExhaustiveOnMethodWithSingleElementOverridingAnArrayViaAliasFor()
|
||||
throws Exception {
|
||||
public void getWithExhaustiveOnMethodWithSingleElementOverridingAnArrayViaAliasFor() throws Exception {
|
||||
testGetWithExhaustiveWebMapping(
|
||||
WebController.class.getMethod("getMappedWithValueAttribute"));
|
||||
testGetWithExhaustiveWebMapping(
|
||||
WebController.class.getMethod("getMappedWithPathAttribute"));
|
||||
}
|
||||
|
||||
private void testGetWithExhaustiveWebMapping(AnnotatedElement element)
|
||||
throws ArrayComparisonFailure {
|
||||
private void testGetWithExhaustiveWebMapping(AnnotatedElement element) throws ArrayComparisonFailure {
|
||||
MergedAnnotation<?> annotation = MergedAnnotations.from(element,
|
||||
SearchStrategy.EXHAUSTIVE).get(RequestMapping.class);
|
||||
assertThat(annotation.getStringArray("value")).containsExactly("/test");
|
||||
assertThat(annotation.getStringArray("path")).containsExactly("/test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDirectWithJavaLangAnnotationType() throws Exception {
|
||||
Constructor<?> deprecatedConstructor = Date.class.getConstructor(String.class);
|
||||
MergedAnnotation<?> annotation = MergedAnnotations.from(deprecatedConstructor,
|
||||
SearchStrategy.DIRECT, RepeatableContainers.standardRepeatables(),
|
||||
AnnotationFilter.NONE).get(Deprecated.class);
|
||||
assertThat(annotation.isPresent()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDirectWithJavaxAnnotationType() throws Exception {
|
||||
assertThat(MergedAnnotations.from(ResourceHolder.class).get(
|
||||
@@ -1267,14 +1245,6 @@ public class MergedAnnotationsTests {
|
||||
Ordered.LOWEST_PRECEDENCE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepeatableOnComposedAnnotation() {
|
||||
MergedAnnotation<?> annotation = MergedAnnotations.from(MyRepeatableMeta1.class,
|
||||
SearchStrategy.EXHAUSTIVE, RepeatableContainers.none(),
|
||||
AnnotationFilter.NONE).get(Repeatable.class);
|
||||
assertThat(annotation.getClass("value")).isEqualTo(MyRepeatableContainer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepeatableDeclaredOnMethod() throws Exception {
|
||||
Method method = InterfaceWithRepeated.class.getMethod("foo");
|
||||
@@ -1286,8 +1256,7 @@ public class MergedAnnotationsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRepeatableDeclaredOnClassWithMissingAttributeAliasDeclaration()
|
||||
throws Exception {
|
||||
public void getRepeatableDeclaredOnClassWithMissingAttributeAliasDeclaration() {
|
||||
RepeatableContainers containers = RepeatableContainers.of(
|
||||
BrokenContextConfiguration.class, BrokenHierarchy.class);
|
||||
assertThatExceptionOfType(AnnotationConfigurationException.class).isThrownBy(
|
||||
|
||||
Reference in New Issue
Block a user