优化代码,修复不准确的注释,完善测试用例

This commit is contained in:
huangchengxing
2022-07-13 22:34:13 +08:00
parent 17b48024ad
commit eae76eb275
14 changed files with 743 additions and 54 deletions

View File

@@ -0,0 +1,99 @@
package cn.hutool.core.annotation;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReflectUtil;
import org.junit.Assert;
import org.junit.Test;
import java.lang.annotation.*;
import java.lang.reflect.Method;
public class AbstractAnnotationAttributeWrapperTest {
@Test
public void workTest() {
Annotation annotation = ClassForTest1.class.getAnnotation(AnnotationForTest1.class);
Method valueMethod = ReflectUtil.getMethod(AnnotationForTest1.class, "value1");
CacheableAnnotationAttribute valueAttribute = new CacheableAnnotationAttribute(annotation, valueMethod);
Method nameMethod = ReflectUtil.getMethod(AnnotationForTest1.class, "name1");
CacheableAnnotationAttribute nameAttribute = new CacheableAnnotationAttribute(annotation, nameMethod);
TestAnnotationAttributeWrapper nameWrapper = new TestAnnotationAttributeWrapper(nameAttribute, valueAttribute);
// 注解属性
Assert.assertEquals(annotation, nameWrapper.getAnnotation());
Assert.assertEquals(annotation.annotationType(), nameWrapper.getAnnotationType());
Assert.assertEquals(nameAttribute, nameWrapper.getOriginal());
Assert.assertEquals(valueAttribute, nameWrapper.getLinked());
// 方法属性
Assert.assertEquals(nameMethod.getName(), nameWrapper.getAttributeName());
Assert.assertEquals(nameMethod.getReturnType(), nameWrapper.getAttributeType());
Assert.assertTrue(nameWrapper.isWrapped());
Assert.assertEquals("value1", nameWrapper.getValue());
}
@Test
public void multiWrapperTest() {
// 包装第一层: name1 + value1
Annotation annotation1 = ClassForTest1.class.getAnnotation(AnnotationForTest1.class);
Method value1Method = ReflectUtil.getMethod(AnnotationForTest1.class, "value1");
CacheableAnnotationAttribute value1Attribute = new CacheableAnnotationAttribute(annotation1, value1Method);
Method name1Method = ReflectUtil.getMethod(AnnotationForTest1.class, "name1");
CacheableAnnotationAttribute name1Attribute = new CacheableAnnotationAttribute(annotation1, name1Method);
TestAnnotationAttributeWrapper wrapper1 = new TestAnnotationAttributeWrapper(name1Attribute, value1Attribute);
Assert.assertEquals(name1Attribute, wrapper1.getNonWrappedOriginal());
Assert.assertEquals(CollUtil.newArrayList(name1Attribute, value1Attribute), wrapper1.getAllLinkedNonWrappedAttributes());
// 包装第二层:( name1 + value1 ) + value2
Annotation annotation2 = ClassForTest1.class.getAnnotation(AnnotationForTest2.class);
Method value2Method = ReflectUtil.getMethod(AnnotationForTest2.class, "value2");
CacheableAnnotationAttribute value2Attribute = new CacheableAnnotationAttribute(annotation2, value2Method);
TestAnnotationAttributeWrapper wrapper2 = new TestAnnotationAttributeWrapper(wrapper1, value2Attribute);
Assert.assertEquals(name1Attribute, wrapper2.getNonWrappedOriginal());
Assert.assertEquals(CollUtil.newArrayList(name1Attribute, value1Attribute, value2Attribute), wrapper2.getAllLinkedNonWrappedAttributes());
// 包装第二层value3 + ( ( name1 + value1 ) + value2 )
Annotation annotation3 = ClassForTest1.class.getAnnotation(AnnotationForTest3.class);
Method value3Method = ReflectUtil.getMethod(AnnotationForTest3.class, "value3");
CacheableAnnotationAttribute value3Attribute = new CacheableAnnotationAttribute(annotation3, value3Method);
TestAnnotationAttributeWrapper wrapper3 = new TestAnnotationAttributeWrapper(value3Attribute, wrapper2);
Assert.assertEquals(value3Attribute, wrapper3.getNonWrappedOriginal());
Assert.assertEquals(CollUtil.newArrayList(value3Attribute, name1Attribute, value1Attribute, value2Attribute), wrapper3.getAllLinkedNonWrappedAttributes());
}
static class TestAnnotationAttributeWrapper extends AbstractAnnotationAttributeWrapper {
protected TestAnnotationAttributeWrapper(AnnotationAttribute original, AnnotationAttribute linked) {
super(original, linked);
}
@Override
public Object getValue() {
return linked.getValue();
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@interface AnnotationForTest1 {
String value1() default "";
String name1() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@interface AnnotationForTest2 {
String value2() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@interface AnnotationForTest3 {
String value3() default "";
}
@AnnotationForTest1(name1 = "name1", value1 = "value1")
@AnnotationForTest2(value2 = "value2")
@AnnotationForTest3(value3 = "value3")
static class ClassForTest1 {}
}

View File

@@ -0,0 +1,76 @@
package cn.hutool.core.annotation;
import cn.hutool.core.util.ReflectUtil;
import org.junit.Assert;
import org.junit.Test;
import java.lang.annotation.*;
import java.lang.reflect.Method;
public class AliasedAnnotationAttributeTest {
@Test
public void baseInfoTest() {
// 组合属性
final Annotation annotation = ClassForTest1.class.getAnnotation(AnnotationForTest.class);
final Method valueMethod = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute valueAttribute = new CacheableAnnotationAttribute(annotation, valueMethod);
final Method nameMethod = ReflectUtil.getMethod(AnnotationForTest.class, "name");
final CacheableAnnotationAttribute nameAttribute = new CacheableAnnotationAttribute(annotation, nameMethod);
final AliasedAnnotationAttribute annotationAttribute = new AliasedAnnotationAttribute(valueAttribute, nameAttribute);
// 注解属性
Assert.assertEquals(annotation, annotationAttribute.getAnnotation());
Assert.assertEquals(annotation.annotationType(), annotationAttribute.getAnnotationType());
// 方法属性
Assert.assertEquals(valueMethod.getName(), annotationAttribute.getAttributeName());
Assert.assertEquals(nameMethod.getReturnType(), annotationAttribute.getAttributeType());
}
@Test
public void workWhenValueDefaultTest() {
// 组合属性
final Annotation annotation = ClassForTest1.class.getAnnotation(AnnotationForTest.class);
final Method valueMethod = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute valueAttribute = new CacheableAnnotationAttribute(annotation, valueMethod);
final Method nameMethod = ReflectUtil.getMethod(AnnotationForTest.class, "name");
final CacheableAnnotationAttribute nameAttribute = new CacheableAnnotationAttribute(annotation, nameMethod);
final AliasedAnnotationAttribute annotationAttribute = new AliasedAnnotationAttribute(valueAttribute, nameAttribute);
// 值处理
Assert.assertEquals("name", annotationAttribute.getValue());
Assert.assertFalse(annotationAttribute.isValueEquivalentToDefaultValue());
Assert.assertTrue(annotationAttribute.isWrapped());
}
@Test
public void workWhenValueNonDefaultTest() {
// 组合属性
final Annotation annotation = ClassForTest2.class.getAnnotation(AnnotationForTest.class);
final Method valueMethod = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute valueAttribute = new CacheableAnnotationAttribute(annotation, valueMethod);
final Method nameMethod = ReflectUtil.getMethod(AnnotationForTest.class, "name");
final CacheableAnnotationAttribute nameAttribute = new CacheableAnnotationAttribute(annotation, nameMethod);
final AliasedAnnotationAttribute annotationAttribute = new AliasedAnnotationAttribute(valueAttribute, nameAttribute);
// 值处理
Assert.assertEquals("value", annotationAttribute.getValue());
Assert.assertFalse(annotationAttribute.isValueEquivalentToDefaultValue());
Assert.assertTrue(annotationAttribute.isWrapped());
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@interface AnnotationForTest {
String value() default "";
String name() default "";
}
@AnnotationForTest(name = "name", value = "value")
static class ClassForTest1 {}
@AnnotationForTest(value = "value")
static class ClassForTest2 {}
}

View File

@@ -0,0 +1,61 @@
package cn.hutool.core.annotation;
import cn.hutool.core.util.ReflectUtil;
import org.junit.Assert;
import org.junit.Test;
import java.lang.annotation.*;
import java.lang.reflect.Method;
public class CacheableAnnotationAttributeTest {
@Test
public void baseInfoTest() {
final Annotation annotation = ClassForTest1.class.getAnnotation(AnnotationForTest.class);
final Method attribute = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute annotationAttribute = new CacheableAnnotationAttribute(annotation, attribute);
// 注解属性
Assert.assertEquals(annotation, annotationAttribute.getAnnotation());
Assert.assertEquals(annotation.annotationType(), annotationAttribute.getAnnotationType());
// 方法属性
Assert.assertEquals(attribute.getName(), annotationAttribute.getAttributeName());
Assert.assertEquals(attribute.getReturnType(), annotationAttribute.getAttributeType());
}
@Test
public void workWhenValueDefaultTest() {
final Annotation annotation = ClassForTest1.class.getAnnotation(AnnotationForTest.class);
final Method attribute = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute annotationAttribute = new CacheableAnnotationAttribute(annotation, attribute);
// 值处理
Assert.assertEquals("", annotationAttribute.getValue());
Assert.assertTrue(annotationAttribute.isValueEquivalentToDefaultValue());
Assert.assertFalse(annotationAttribute.isWrapped());
}
@Test
public void workWhenValueNonDefaultTest() {
final Annotation annotation = ClassForTest2.class.getAnnotation(AnnotationForTest.class);
final Method attribute = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute annotationAttribute = new CacheableAnnotationAttribute(annotation, attribute);
// 值处理
Assert.assertEquals("test", annotationAttribute.getValue());
Assert.assertFalse(annotationAttribute.isValueEquivalentToDefaultValue());
Assert.assertFalse(annotationAttribute.isWrapped());
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@interface AnnotationForTest {
String value() default "";
}
@AnnotationForTest("")
static class ClassForTest1 {}
@AnnotationForTest("test")
static class ClassForTest2 {}
}

View File

@@ -0,0 +1,76 @@
package cn.hutool.core.annotation;
import cn.hutool.core.util.ReflectUtil;
import org.junit.Assert;
import org.junit.Test;
import java.lang.annotation.*;
import java.lang.reflect.Method;
public class ForceAliasedAnnotationAttributeTest {
@Test
public void baseInfoTest() {
// 组合属性
final Annotation annotation = ClassForTest1.class.getAnnotation(AnnotationForTest.class);
final Method valueMethod = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute valueAttribute = new CacheableAnnotationAttribute(annotation, valueMethod);
final Method nameMethod = ReflectUtil.getMethod(AnnotationForTest.class, "name");
final CacheableAnnotationAttribute nameAttribute = new CacheableAnnotationAttribute(annotation, nameMethod);
final ForceAliasedAnnotationAttribute valueAnnotationAttribute = new ForceAliasedAnnotationAttribute(valueAttribute, nameAttribute);
// 注解属性
Assert.assertEquals(annotation, valueAnnotationAttribute.getAnnotation());
Assert.assertEquals(annotation.annotationType(), valueAnnotationAttribute.getAnnotationType());
// 方法属性
Assert.assertEquals(valueMethod.getName(), valueAnnotationAttribute.getAttributeName());
Assert.assertEquals(valueMethod.getReturnType(), valueAnnotationAttribute.getAttributeType());
}
@Test
public void workWhenValueDefaultTest() {
// 组合属性
final Annotation annotation = ClassForTest1.class.getAnnotation(AnnotationForTest.class);
final Method valueMethod = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute valueAttribute = new CacheableAnnotationAttribute(annotation, valueMethod);
final Method nameMethod = ReflectUtil.getMethod(AnnotationForTest.class, "name");
final CacheableAnnotationAttribute nameAttribute = new CacheableAnnotationAttribute(annotation, nameMethod);
final AliasedAnnotationAttribute valueAnnotationAttribute = new AliasedAnnotationAttribute(valueAttribute, nameAttribute);
// 值处理
Assert.assertEquals("name", valueAnnotationAttribute.getValue());
Assert.assertFalse(valueAnnotationAttribute.isValueEquivalentToDefaultValue());
Assert.assertTrue(valueAnnotationAttribute.isWrapped());
}
@Test
public void workWhenValueNonDefaultTest() {
// 组合属性
final Annotation annotation = ClassForTest2.class.getAnnotation(AnnotationForTest.class);
final Method valueMethod = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute valueAttribute = new CacheableAnnotationAttribute(annotation, valueMethod);
final Method nameMethod = ReflectUtil.getMethod(AnnotationForTest.class, "name");
final CacheableAnnotationAttribute nameAttribute = new CacheableAnnotationAttribute(annotation, nameMethod);
final ForceAliasedAnnotationAttribute valueAnnotationAttribute = new ForceAliasedAnnotationAttribute(valueAttribute, nameAttribute);
// 值处理
Assert.assertEquals("", valueAnnotationAttribute.getValue());
Assert.assertTrue(valueAnnotationAttribute.isValueEquivalentToDefaultValue());
Assert.assertTrue(valueAnnotationAttribute.isWrapped());
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@interface AnnotationForTest {
String value() default "";
String name() default "";
}
@AnnotationForTest(name = "name", value = "value")
static class ClassForTest1 {}
@AnnotationForTest(value = "value")
static class ClassForTest2 {}
}

View File

@@ -0,0 +1,76 @@
package cn.hutool.core.annotation;
import cn.hutool.core.util.ReflectUtil;
import org.junit.Assert;
import org.junit.Test;
import java.lang.annotation.*;
import java.lang.reflect.Method;
public class MirroredAnnotationAttributeTest {
@Test
public void baseInfoTest() {
// 组合属性
final Annotation annotation = ClassForTest1.class.getAnnotation(AnnotationForTest.class);
final Method valueMethod = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute valueAttribute = new CacheableAnnotationAttribute(annotation, valueMethod);
final Method nameMethod = ReflectUtil.getMethod(AnnotationForTest.class, "name");
final CacheableAnnotationAttribute nameAttribute = new CacheableAnnotationAttribute(annotation, nameMethod);
final MirroredAnnotationAttribute nameAnnotationAttribute = new MirroredAnnotationAttribute(nameAttribute, valueAttribute);
// 注解属性
Assert.assertEquals(annotation, nameAnnotationAttribute.getAnnotation());
Assert.assertEquals(annotation.annotationType(), nameAnnotationAttribute.getAnnotationType());
// 方法属性
Assert.assertEquals(nameMethod.getName(), nameAnnotationAttribute.getAttributeName());
Assert.assertEquals(nameMethod.getReturnType(), nameAnnotationAttribute.getAttributeType());
}
@Test
public void workWhenValueDefaultTest() {
// 组合属性
final Annotation annotation = ClassForTest2.class.getAnnotation(AnnotationForTest.class);
final Method valueMethod = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute valueAttribute = new CacheableAnnotationAttribute(annotation, valueMethod);
final Method nameMethod = ReflectUtil.getMethod(AnnotationForTest.class, "name");
final CacheableAnnotationAttribute nameAttribute = new CacheableAnnotationAttribute(annotation, nameMethod);
final MirroredAnnotationAttribute nameAnnotationAttribute = new MirroredAnnotationAttribute(nameAttribute, valueAttribute);
// 值处理
Assert.assertEquals("", nameAnnotationAttribute.getValue());
Assert.assertTrue(nameAnnotationAttribute.isValueEquivalentToDefaultValue());
Assert.assertTrue(nameAnnotationAttribute.isWrapped());
}
@Test
public void workWhenValueNonDefaultTest() {
// 组合属性
final Annotation annotation = ClassForTest1.class.getAnnotation(AnnotationForTest.class);
final Method valueMethod = ReflectUtil.getMethod(AnnotationForTest.class, "value");
final CacheableAnnotationAttribute valueAttribute = new CacheableAnnotationAttribute(annotation, valueMethod);
final Method nameMethod = ReflectUtil.getMethod(AnnotationForTest.class, "name");
final CacheableAnnotationAttribute nameAttribute = new CacheableAnnotationAttribute(annotation, nameMethod);
final MirroredAnnotationAttribute nameAnnotationAttribute = new MirroredAnnotationAttribute(nameAttribute, valueAttribute);
// 值处理
Assert.assertEquals("name", nameAnnotationAttribute.getValue());
Assert.assertFalse(nameAnnotationAttribute.isValueEquivalentToDefaultValue());
Assert.assertTrue(nameAnnotationAttribute.isWrapped());
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@interface AnnotationForTest {
String value() default "";
String name() default "";
}
@AnnotationForTest(value = "name")
static class ClassForTest1 {}
@AnnotationForTest
static class ClassForTest2 {}
}

View File

@@ -0,0 +1,146 @@
package cn.hutool.core.annotation;
import org.junit.Assert;
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.function.UnaryOperator;
public class SynthesizedAnnotationSelectorTest {
@Test
public void nearestAndOldestPriorityTest() {
final SynthesizedAnnotationSelector selector = SynthesizedAnnotationSelector.NEAREST_AND_OLDEST_PRIORITY;
TestSynthesizedAnnotation annotation1 = new TestSynthesizedAnnotation(0, 0);
TestSynthesizedAnnotation annotation2 = new TestSynthesizedAnnotation(0, 0);
Assert.assertEquals(annotation1, selector.choose(annotation1, annotation2));
annotation1 = new TestSynthesizedAnnotation(0, 1);
annotation2 = new TestSynthesizedAnnotation(0, 0);
Assert.assertEquals(annotation1, selector.choose(annotation1, annotation2));
annotation1 = new TestSynthesizedAnnotation(1, 0);
annotation2 = new TestSynthesizedAnnotation(0, 0);
Assert.assertEquals(annotation2, selector.choose(annotation1, annotation2));
}
@Test
public void nearestAndNewestPriorityTest() {
final SynthesizedAnnotationSelector selector = SynthesizedAnnotationSelector.NEAREST_AND_NEWEST_PRIORITY;
TestSynthesizedAnnotation annotation1 = new TestSynthesizedAnnotation(0, 0);
TestSynthesizedAnnotation annotation2 = new TestSynthesizedAnnotation(0, 0);
Assert.assertEquals(annotation2, selector.choose(annotation1, annotation2));
annotation1 = new TestSynthesizedAnnotation(0, 1);
annotation2 = new TestSynthesizedAnnotation(0, 0);
Assert.assertEquals(annotation2, selector.choose(annotation1, annotation2));
annotation1 = new TestSynthesizedAnnotation(0, 0);
annotation2 = new TestSynthesizedAnnotation(1, 0);
Assert.assertEquals(annotation1, selector.choose(annotation1, annotation2));
}
@Test
public void farthestAndOldestPriorityTest() {
final SynthesizedAnnotationSelector selector = SynthesizedAnnotationSelector.FARTHEST_AND_OLDEST_PRIORITY;
TestSynthesizedAnnotation annotation1 = new TestSynthesizedAnnotation(0, 0);
TestSynthesizedAnnotation annotation2 = new TestSynthesizedAnnotation(0, 0);
Assert.assertEquals(annotation1, selector.choose(annotation1, annotation2));
annotation1 = new TestSynthesizedAnnotation(0, 1);
annotation2 = new TestSynthesizedAnnotation(0, 0);
Assert.assertEquals(annotation1, selector.choose(annotation1, annotation2));
annotation1 = new TestSynthesizedAnnotation(0, 0);
annotation2 = new TestSynthesizedAnnotation(1, 0);
Assert.assertEquals(annotation2, selector.choose(annotation1, annotation2));
}
@Test
public void farthestAndNewestPriorityTest() {
final SynthesizedAnnotationSelector selector = SynthesizedAnnotationSelector.FARTHEST_AND_NEWEST_PRIORITY;
TestSynthesizedAnnotation annotation1 = new TestSynthesizedAnnotation(0, 0);
TestSynthesizedAnnotation annotation2 = new TestSynthesizedAnnotation(0, 0);
Assert.assertEquals(annotation2, selector.choose(annotation1, annotation2));
annotation1 = new TestSynthesizedAnnotation(0, 1);
annotation2 = new TestSynthesizedAnnotation(0, 0);
Assert.assertEquals(annotation2, selector.choose(annotation1, annotation2));
annotation1 = new TestSynthesizedAnnotation(1, 0);
annotation2 = new TestSynthesizedAnnotation(0, 0);
Assert.assertEquals(annotation1, selector.choose(annotation1, annotation2));
}
static class TestSynthesizedAnnotation implements SynthesizedAnnotation {
private final int verticalDistance;
private final int horizontalDistance;
public TestSynthesizedAnnotation(int verticalDistance, int horizontalDistance) {
this.verticalDistance = verticalDistance;
this.horizontalDistance = horizontalDistance;
}
@Override
public SyntheticAnnotation getOwner() {
return null;
}
@Override
public Object getRoot() {
return null;
}
@Override
public Annotation getAnnotation() {
return null;
}
@Override
public int getVerticalDistance() {
return this.verticalDistance;
}
@Override
public int getHorizontalDistance() {
return this.horizontalDistance;
}
@Override
public boolean hasAttribute(String attributeName, Class<?> returnType) {
return false;
}
@Override
public Map<String, AnnotationAttribute> getAttributes() {
return null;
}
@Override
public void setAttribute(String attributeName, AnnotationAttribute attribute) {
}
@Override
public void replaceAttribute(String attributeName, UnaryOperator<AnnotationAttribute> operator) {
}
@Override
public Object getAttributeValue(String attributeName) {
return null;
}
@Override
public Class<? extends Annotation> annotationType() {
return null;
}
}
}

View File

@@ -4,11 +4,9 @@ import cn.hutool.core.util.ReflectUtil;
import org.junit.Assert;
import org.junit.Test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* 合成注解{@link SyntheticMetaAnnotation}的测试用例
@@ -18,8 +16,38 @@ import java.lang.reflect.Method;
public class SyntheticMetaAnnotationTest {
@Test
public void testSynthesisAnnotation() {
ChildAnnotation rootAnnotation = AnnotatedClass.class.getAnnotation(ChildAnnotation.class);
public void baseSynthesisAnnotationWorkTest() {
// AnnotatedClass -> @ChildAnnotation -> @ParentAnnotation -> @GrandParentAnnotation
// -> @GrandParentAnnotation
final GrandParentAnnotation grandParentAnnotation = ChildAnnotation.class.getAnnotation(GrandParentAnnotation.class);
final ParentAnnotation parentAnnotation = ChildAnnotation.class.getAnnotation(ParentAnnotation.class);
final ChildAnnotation childAnnotation = AnnotatedClass.class.getAnnotation(ChildAnnotation.class);
final SyntheticMetaAnnotation syntheticMetaAnnotation = new SyntheticMetaAnnotation(childAnnotation);
// Annotation & AnnotatedElement
Assert.assertEquals(SyntheticMetaAnnotation.class, syntheticMetaAnnotation.annotationType());
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(GrandParentAnnotation.class));
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(ParentAnnotation.class));
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(ChildAnnotation.class));
Assert.assertEquals(grandParentAnnotation, syntheticMetaAnnotation.getAnnotation(GrandParentAnnotation.class));
Assert.assertEquals(parentAnnotation, syntheticMetaAnnotation.getAnnotation(ParentAnnotation.class));
Assert.assertEquals(childAnnotation, syntheticMetaAnnotation.getAnnotation(ChildAnnotation.class));
Assert.assertEquals(
Arrays.asList(childAnnotation, grandParentAnnotation, parentAnnotation),
Arrays.asList(syntheticMetaAnnotation.getAnnotations())
);
Assert.assertArrayEquals(new Annotation[]{ childAnnotation }, syntheticMetaAnnotation.getDeclaredAnnotations());
// 扩展方法
Assert.assertNotNull(syntheticMetaAnnotation.getSynthesizedAnnotation(GrandParentAnnotation.class));
Assert.assertNotNull(syntheticMetaAnnotation.getSynthesizedAnnotation(ParentAnnotation.class));
Assert.assertNotNull(syntheticMetaAnnotation.getSynthesizedAnnotation(ChildAnnotation.class));
Assert.assertEquals(3, syntheticMetaAnnotation.getAllSyntheticAnnotations().size());
}
@Test
public void synthesisAnnotationAttributeTest() {
final ChildAnnotation rootAnnotation = AnnotatedClass.class.getAnnotation(ChildAnnotation.class);
SyntheticMetaAnnotation syntheticMetaAnnotation = new SyntheticMetaAnnotation(rootAnnotation);
Assert.assertEquals(syntheticMetaAnnotation.getSource(), rootAnnotation);
Assert.assertEquals(syntheticMetaAnnotation.annotationType(), SyntheticMetaAnnotation.class);
@@ -32,7 +60,7 @@ public class SyntheticMetaAnnotationTest {
Assert.assertEquals("Child's Parent!", syntheticMetaAnnotation.getAttribute("parentValue", String.class));
Assert.assertEquals("Child's GrandParent!", syntheticMetaAnnotation.getAttribute("grandParentValue", String.class));
ChildAnnotation childAnnotation = syntheticMetaAnnotation.syntheticAnnotation(ChildAnnotation.class);
final ChildAnnotation childAnnotation = syntheticMetaAnnotation.syntheticAnnotation(ChildAnnotation.class);
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(ChildAnnotation.class));
Assert.assertNotNull(childAnnotation);
Assert.assertEquals("Child!", childAnnotation.childValue());
@@ -40,14 +68,14 @@ public class SyntheticMetaAnnotationTest {
Assert.assertEquals(childAnnotation.grandParentType(), Integer.class);
Assert.assertThrows(IllegalArgumentException.class, () -> new SyntheticMetaAnnotation(childAnnotation));
ParentAnnotation parentAnnotation = syntheticMetaAnnotation.syntheticAnnotation(ParentAnnotation.class);
final ParentAnnotation parentAnnotation = syntheticMetaAnnotation.syntheticAnnotation(ParentAnnotation.class);
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(ParentAnnotation.class));
Assert.assertNotNull(parentAnnotation);
Assert.assertEquals("Child's Parent!", parentAnnotation.parentValue());
Assert.assertEquals("java.lang.Void", parentAnnotation.grandParentType());
Assert.assertThrows(IllegalArgumentException.class, () -> new SyntheticMetaAnnotation(parentAnnotation));
GrandParentAnnotation grandParentAnnotation = syntheticMetaAnnotation.syntheticAnnotation(GrandParentAnnotation.class);
final GrandParentAnnotation grandParentAnnotation = syntheticMetaAnnotation.syntheticAnnotation(GrandParentAnnotation.class);
Assert.assertTrue(syntheticMetaAnnotation.isAnnotationPresent(GrandParentAnnotation.class));
Assert.assertNotNull(grandParentAnnotation);
Assert.assertEquals("Child's GrandParent!", grandParentAnnotation.grandParentValue());
@@ -57,9 +85,9 @@ public class SyntheticMetaAnnotationTest {
@Test
public void linkTest() {
Method method = ReflectUtil.getMethod(AnnotationForLinkTest.class, "value");
SyntheticAnnotation syntheticAnnotation = new SyntheticMetaAnnotation(method.getAnnotation(AliasFor.class));
Link link = syntheticAnnotation.syntheticAnnotation(Link.class);
final Method method = ReflectUtil.getMethod(AnnotationForLinkTest.class, "value");
final SyntheticAnnotation syntheticAnnotation = new SyntheticMetaAnnotation(method.getAnnotation(AliasFor.class));
final Link link = syntheticAnnotation.syntheticAnnotation(Link.class);
Assert.assertEquals(AnnotationForLinkTest.class, link.annotation());
Assert.assertEquals("name", link.attribute());
}
@@ -82,7 +110,7 @@ public class SyntheticMetaAnnotationTest {
synthetic = new SyntheticMetaAnnotation(annotation);
syntheticAnnotation = synthetic.syntheticAnnotation(AnnotationForMirrorTest.class);
AnnotationForMirrorTest finalSyntheticAnnotation = syntheticAnnotation;
Assert.assertThrows(IllegalArgumentException.class, () -> finalSyntheticAnnotation.name());
Assert.assertThrows(IllegalArgumentException.class, finalSyntheticAnnotation::name);
}
@Test
@@ -132,18 +160,30 @@ public class SyntheticMetaAnnotationTest {
@Test
public void multiAliasForTest() {
AnnotationForMultiAliasForTest annotation = ClassForMultiAliasForTest.class.getAnnotation(AnnotationForMultiAliasForTest.class);
SyntheticAnnotation synthetic = new SyntheticMetaAnnotation(annotation);
final AnnotationForMultiAliasForTest annotation = ClassForMultiAliasForTest.class.getAnnotation(AnnotationForMultiAliasForTest.class);
final SyntheticAnnotation synthetic = new SyntheticMetaAnnotation(annotation);
MetaAnnotationForMultiAliasForTest1 metaAnnotation1 = synthetic.syntheticAnnotation(MetaAnnotationForMultiAliasForTest1.class);
final MetaAnnotationForMultiAliasForTest1 metaAnnotation1 = synthetic.syntheticAnnotation(MetaAnnotationForMultiAliasForTest1.class);
Assert.assertEquals("test", metaAnnotation1.name());
Assert.assertEquals("test", metaAnnotation1.value1());
MetaAnnotationForMultiAliasForTest2 metaAnnotation2 = synthetic.syntheticAnnotation(MetaAnnotationForMultiAliasForTest2.class);
final MetaAnnotationForMultiAliasForTest2 metaAnnotation2 = synthetic.syntheticAnnotation(MetaAnnotationForMultiAliasForTest2.class);
Assert.assertEquals("test", metaAnnotation2.value2());
AnnotationForMultiAliasForTest childAnnotation = synthetic.syntheticAnnotation(AnnotationForMultiAliasForTest.class);
final AnnotationForMultiAliasForTest childAnnotation = synthetic.syntheticAnnotation(AnnotationForMultiAliasForTest.class);
Assert.assertEquals("test", childAnnotation.value3());
}
@Test
public void implicitAliasTest() {
final AnnotationForImplicitAliasTest annotation = ClassForImplicitAliasTest.class.getAnnotation(AnnotationForImplicitAliasTest.class);
final SyntheticAnnotation synthetic = new SyntheticMetaAnnotation(annotation);
final MetaAnnotationForImplicitAliasTest metaAnnotation = synthetic.syntheticAnnotation(MetaAnnotationForImplicitAliasTest.class);
Assert.assertEquals("Meta", metaAnnotation.name());
Assert.assertEquals("Foo", metaAnnotation.value());
final AnnotationForImplicitAliasTest childAnnotation = synthetic.syntheticAnnotation(AnnotationForImplicitAliasTest.class);
Assert.assertEquals("Foo", childAnnotation.value());
}
// 注解结构如下:
// AnnotatedClass -> @ChildAnnotation -> @ParentAnnotation -> @GrandParentAnnotation
// -> @GrandParentAnnotation
@@ -284,4 +324,21 @@ public class SyntheticMetaAnnotationTest {
@AnnotationForMultiAliasForTest(value3 = "test")
static class ClassForMultiAliasForTest{}
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@interface MetaAnnotationForImplicitAliasTest {
@MirrorFor(attribute = "value")
String name() default "";
@MirrorFor(attribute = "name")
String value() default "";
}
@MetaAnnotationForImplicitAliasTest("Meta")
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE })
@interface AnnotationForImplicitAliasTest {
String value() default "";
}
@AnnotationForImplicitAliasTest("Foo")
static class ClassForImplicitAliasTest {}
}