From 2bc7a3aa0a60a8794c726b33793fb9b3d968755a Mon Sep 17 00:00:00 2001 From: Sam Brannen Date: Wed, 23 Jun 2021 14:27:51 +0200 Subject: [PATCH] Implement equals, hashCode, & toString in BeanMethod and *Metadata types Prior to this commit, ConfigurationClass implemented equals(), hashCode(), and toString(), but BeanMethod did not. This commit introduces equals(), hashCode(), and toString() implementations in BeanMethod for consistency with ConfigurationClass to make it possible to use BeanMethod instances to index additional metadata as well. In order to properly implement equals() in BeanMethod, the method argument types are required, but these are not directly available in BeanMethod. However, they are available via ASM when processing @Bean methods. This commit therefore implements equals(), hashCode(), and toString() in SimpleMethodMetadata which BeanMethod delegates to. For completeness, this commit also implements equals(), hashCode(), and toString() in StandardClassMetadata, StandardMethodMetadata, and SimpleAnnotationMetadata. Closes gh-27076 --- .../context/annotation/BeanMethod.java | 17 ++ .../ConfigurationClassAndBeanMethodTests.java | 202 ++++++++++++++++++ .../core/type/StandardClassMetadata.java | 19 +- .../core/type/StandardMethodMetadata.java | 19 +- .../SimpleAnnotationMetadata.java | 19 +- .../classreading/SimpleMethodMetadata.java | 26 ++- .../SimpleMethodMetadataReadingVisitor.java | 4 +- .../type/AbstractAnnotationMetadataTests.java | 44 +++- .../type/AbstractMethodMetadataTests.java | 68 +++++- ...AnnotationMetadataReadingVisitorTests.java | 22 +- .../MethodMetadataReadingVisitorTests.java | 24 ++- 11 files changed, 452 insertions(+), 12 deletions(-) create mode 100644 spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassAndBeanMethodTests.java diff --git a/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java b/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java index ca7d034ca6..6d3459fb08 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/BeanMethod.java @@ -19,6 +19,7 @@ package org.springframework.context.annotation; import org.springframework.beans.factory.parsing.Problem; import org.springframework.beans.factory.parsing.ProblemReporter; import org.springframework.core.type.MethodMetadata; +import org.springframework.lang.Nullable; /** * Represents a {@link Configuration @Configuration} class method annotated with @@ -26,6 +27,7 @@ import org.springframework.core.type.MethodMetadata; * * @author Chris Beams * @author Juergen Hoeller + * @author Sam Brannen * @since 3.0 * @see ConfigurationClass * @see ConfigurationClassParser @@ -52,6 +54,21 @@ final class BeanMethod extends ConfigurationMethod { } } + @Override + public boolean equals(@Nullable Object obj) { + return ((this == obj) || ((obj instanceof BeanMethod) && + this.metadata.equals(((BeanMethod) obj).metadata))); + } + + @Override + public int hashCode() { + return this.metadata.hashCode(); + } + + @Override + public String toString() { + return "BeanMethod: " + this.metadata; + } private class NonOverridableMethodError extends Problem { diff --git a/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassAndBeanMethodTests.java b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassAndBeanMethodTests.java new file mode 100644 index 0000000000..85fa32dc22 --- /dev/null +++ b/spring-context/src/test/java/org/springframework/context/annotation/ConfigurationClassAndBeanMethodTests.java @@ -0,0 +1,202 @@ +/* + * Copyright 2002-2021 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.context.annotation; + +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.parsing.FailFastProblemReporter; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.core.env.StandardEnvironment; +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.type.classreading.CachingMetadataReaderFactory; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration tests for {@link ConfigurationClassParser}, {@link ConfigurationClass}, + * and {@link BeanMethod}. + * + * @author Sam Brannen + * @since 5.3.9 + */ +class ConfigurationClassAndBeanMethodTests { + + @Test + void verifyEquals() throws Exception { + ConfigurationClass configurationClass1 = newConfigurationClass(Config1.class); + ConfigurationClass configurationClass2 = newConfigurationClass(Config1.class); + ConfigurationClass configurationClass3 = newConfigurationClass(Config2.class); + + assertThat(configurationClass1.equals(null)).isFalse(); + assertThat(configurationClass1).isNotSameAs(configurationClass2); + + assertThat(configurationClass1.equals(configurationClass1)).isTrue(); + assertThat(configurationClass2.equals(configurationClass2)).isTrue(); + assertThat(configurationClass1.equals(configurationClass2)).isTrue(); + assertThat(configurationClass2.equals(configurationClass1)).isTrue(); + + assertThat(configurationClass1.equals(configurationClass3)).isFalse(); + assertThat(configurationClass3.equals(configurationClass2)).isFalse(); + + // --------------------------------------------------------------------- + + List beanMethods1 = getBeanMethods(configurationClass1); + BeanMethod beanMethod_1_0 = beanMethods1.get(0); + BeanMethod beanMethod_1_1 = beanMethods1.get(1); + BeanMethod beanMethod_1_2 = beanMethods1.get(2); + + List beanMethods2 = getBeanMethods(configurationClass2); + BeanMethod beanMethod_2_0 = beanMethods2.get(0); + BeanMethod beanMethod_2_1 = beanMethods2.get(1); + BeanMethod beanMethod_2_2 = beanMethods2.get(2); + + List beanMethods3 = getBeanMethods(configurationClass3); + BeanMethod beanMethod_3_0 = beanMethods3.get(0); + BeanMethod beanMethod_3_1 = beanMethods3.get(1); + BeanMethod beanMethod_3_2 = beanMethods3.get(2); + + assertThat(beanMethod_1_0.equals(null)).isFalse(); + assertThat(beanMethod_1_0).isNotSameAs(beanMethod_2_0); + + assertThat(beanMethod_1_0.equals(beanMethod_1_0)).isTrue(); + assertThat(beanMethod_1_0.equals(beanMethod_2_0)).isTrue(); + assertThat(beanMethod_1_1.equals(beanMethod_2_1)).isTrue(); + assertThat(beanMethod_1_2.equals(beanMethod_2_2)).isTrue(); + + assertThat(beanMethod_1_0.getMetadata().getMethodName()).isEqualTo(beanMethod_3_0.getMetadata().getMethodName()); + assertThat(beanMethod_1_0.equals(beanMethod_3_0)).isFalse(); + assertThat(beanMethod_1_1.equals(beanMethod_3_1)).isFalse(); + assertThat(beanMethod_1_2.equals(beanMethod_3_2)).isFalse(); + } + + @Test + void verifyHashCode() throws Exception { + ConfigurationClass configurationClass1 = newConfigurationClass(Config1.class); + ConfigurationClass configurationClass2 = newConfigurationClass(Config1.class); + ConfigurationClass configurationClass3 = newConfigurationClass(Config2.class); + + assertThat(configurationClass1).hasSameHashCodeAs(configurationClass2); + assertThat(configurationClass1).doesNotHaveSameHashCodeAs(configurationClass3); + + // --------------------------------------------------------------------- + + List beanMethods1 = getBeanMethods(configurationClass1); + BeanMethod beanMethod_1_0 = beanMethods1.get(0); + BeanMethod beanMethod_1_1 = beanMethods1.get(1); + BeanMethod beanMethod_1_2 = beanMethods1.get(2); + + List beanMethods2 = getBeanMethods(configurationClass2); + BeanMethod beanMethod_2_0 = beanMethods2.get(0); + BeanMethod beanMethod_2_1 = beanMethods2.get(1); + BeanMethod beanMethod_2_2 = beanMethods2.get(2); + + List beanMethods3 = getBeanMethods(configurationClass3); + BeanMethod beanMethod_3_0 = beanMethods3.get(0); + BeanMethod beanMethod_3_1 = beanMethods3.get(1); + BeanMethod beanMethod_3_2 = beanMethods3.get(2); + + assertThat(beanMethod_1_0).hasSameHashCodeAs(beanMethod_2_0); + assertThat(beanMethod_1_1).hasSameHashCodeAs(beanMethod_2_1); + assertThat(beanMethod_1_2).hasSameHashCodeAs(beanMethod_2_2); + + assertThat(beanMethod_1_0).doesNotHaveSameHashCodeAs(beanMethod_3_0); + assertThat(beanMethod_1_1).doesNotHaveSameHashCodeAs(beanMethod_3_1); + assertThat(beanMethod_1_2).doesNotHaveSameHashCodeAs(beanMethod_3_2); + } + + @Test + void verifyToString() throws Exception { + ConfigurationClass configurationClass = newConfigurationClass(Config1.class); + assertThat(configurationClass.toString()) + .startsWith("ConfigurationClass: beanName 'Config1', class path resource"); + + List beanMethods = getBeanMethods(configurationClass); + String prefix = "BeanMethod: " + Config1.class.getName(); + assertThat(beanMethods.get(0).toString()).isEqualTo(prefix + ".bean0()"); + assertThat(beanMethods.get(1).toString()).isEqualTo(prefix + ".bean1(java.lang.String)"); + assertThat(beanMethods.get(2).toString()).isEqualTo(prefix + ".bean2(java.lang.String,java.lang.Integer)"); + } + + + private static ConfigurationClass newConfigurationClass(Class clazz) throws Exception { + ConfigurationClassParser parser = newParser(); + parser.parse(clazz.getName(), clazz.getSimpleName()); + assertThat(parser.getConfigurationClasses()).hasSize(1); + return parser.getConfigurationClasses().iterator().next(); + } + + private static ConfigurationClassParser newParser() { + return new ConfigurationClassParser( + new CachingMetadataReaderFactory(), + new FailFastProblemReporter(), + new StandardEnvironment(), + new DefaultResourceLoader(), + new AnnotationBeanNameGenerator(), + new DefaultListableBeanFactory()); + } + + private static List getBeanMethods(ConfigurationClass configurationClass) { + List beanMethods = configurationClass.getBeanMethods().stream() + .sorted(Comparator.comparing(beanMethod -> beanMethod.getMetadata().getMethodName())) + .collect(Collectors.toList()); + assertThat(beanMethods).hasSize(3); + return beanMethods; + } + + static class Config1 { + + @Bean + String bean0() { + return ""; + } + + @Bean + String bean1(String text) { + return ""; + } + + @Bean + String bean2(String text, Integer num) { + return ""; + } + + } + + static class Config2 { + + @Bean + String bean0() { + return ""; + } + + @Bean + String bean1(String text) { + return ""; + } + + @Bean + String bean2(String text, Integer num) { + return ""; + } + + } + +} diff --git a/spring-core/src/main/java/org/springframework/core/type/StandardClassMetadata.java b/spring-core/src/main/java/org/springframework/core/type/StandardClassMetadata.java index ae9c2961e6..7543563381 100644 --- a/spring-core/src/main/java/org/springframework/core/type/StandardClassMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/StandardClassMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 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. @@ -28,6 +28,7 @@ import org.springframework.util.StringUtils; * to introspect a given {@code Class}. * * @author Juergen Hoeller + * @author Sam Brannen * @since 2.5 */ public class StandardClassMetadata implements ClassMetadata { @@ -119,4 +120,20 @@ public class StandardClassMetadata implements ClassMetadata { return StringUtils.toStringArray(memberClassNames); } + @Override + public boolean equals(@Nullable Object obj) { + return ((this == obj) || ((obj instanceof StandardClassMetadata) && + getIntrospectedClass().equals(((StandardClassMetadata) obj).getIntrospectedClass()))); + } + + @Override + public int hashCode() { + return getIntrospectedClass().hashCode(); + } + + @Override + public String toString() { + return getClassName(); + } + } diff --git a/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java b/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java index 9678dc4603..53c69376d8 100644 --- a/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/StandardMethodMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 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. @@ -36,6 +36,7 @@ import org.springframework.util.MultiValueMap; * @author Mark Pollack * @author Chris Beams * @author Phillip Webb + * @author Sam Brannen * @since 3.0 */ public class StandardMethodMetadata implements MethodMetadata { @@ -150,4 +151,20 @@ public class StandardMethodMetadata implements MethodMetadata { annotationName, classValuesAsString, false); } + @Override + public boolean equals(@Nullable Object obj) { + return ((this == obj) || ((obj instanceof StandardMethodMetadata) && + this.introspectedMethod.equals(((StandardMethodMetadata) obj).introspectedMethod))); + } + + @Override + public int hashCode() { + return this.introspectedMethod.hashCode(); + } + + @Override + public String toString() { + return this.introspectedMethod.toString(); + } + } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadata.java b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadata.java index 1f4c0ba5c9..5f1ebf4bb5 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleAnnotationMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -31,6 +31,7 @@ import org.springframework.lang.Nullable; * {@link SimpleAnnotationMetadataReadingVisitor}. * * @author Phillip Webb + * @author Sam Brannen * @since 5.2 */ final class SimpleAnnotationMetadata implements AnnotationMetadata { @@ -156,4 +157,20 @@ final class SimpleAnnotationMetadata implements AnnotationMetadata { return this.annotations; } + @Override + public boolean equals(@Nullable Object obj) { + return ((this == obj) || ((obj instanceof SimpleAnnotationMetadata) && + this.className.equals(((SimpleAnnotationMetadata) obj).className))); + } + + @Override + public int hashCode() { + return this.className.hashCode(); + } + + @Override + public String toString() { + return this.className; + } + } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadata.java b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadata.java index a3f2ce644f..98fcbe759a 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadata.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadata.java @@ -19,11 +19,13 @@ package org.springframework.core.type.classreading; import org.springframework.asm.Opcodes; import org.springframework.core.annotation.MergedAnnotations; import org.springframework.core.type.MethodMetadata; +import org.springframework.lang.Nullable; /** * {@link MethodMetadata} created from a {@link SimpleMethodMetadataReadingVisitor}. * * @author Phillip Webb + * @author Sam Brannen * @since 5.2 */ final class SimpleMethodMetadata implements MethodMetadata { @@ -36,16 +38,20 @@ final class SimpleMethodMetadata implements MethodMetadata { private final String returnTypeName; + // The source implements equals(), hashCode(), and toString() for the underlying method. + private final Object source; + private final MergedAnnotations annotations; - public SimpleMethodMetadata(String methodName, int access, String declaringClassName, - String returnTypeName, MergedAnnotations annotations) { + SimpleMethodMetadata(String methodName, int access, String declaringClassName, + String returnTypeName, Object source, MergedAnnotations annotations) { this.methodName = methodName; this.access = access; this.declaringClassName = declaringClassName; this.returnTypeName = returnTypeName; + this.source = source; this.annotations = annotations; } @@ -94,4 +100,20 @@ final class SimpleMethodMetadata implements MethodMetadata { return this.annotations; } + @Override + public boolean equals(@Nullable Object obj) { + return ((this == obj) || ((obj instanceof SimpleMethodMetadata) && + this.source.equals(((SimpleMethodMetadata) obj).source))); + } + + @Override + public int hashCode() { + return this.source.hashCode(); + } + + @Override + public String toString() { + return this.source.toString(); + } + } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadataReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadataReadingVisitor.java index c9bd5f0258..9bc09afcd7 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadataReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/SimpleMethodMetadataReadingVisitor.java @@ -81,8 +81,8 @@ final class SimpleMethodMetadataReadingVisitor extends MethodVisitor { if (!this.annotations.isEmpty()) { String returnTypeName = Type.getReturnType(this.descriptor).getClassName(); MergedAnnotations annotations = MergedAnnotations.of(this.annotations); - SimpleMethodMetadata metadata = new SimpleMethodMetadata(this.methodName, - this.access, this.declaringClassName, returnTypeName, annotations); + SimpleMethodMetadata metadata = new SimpleMethodMetadata(this.methodName, this.access, + this.declaringClassName, returnTypeName, getSource(), annotations); this.consumer.accept(metadata); } } diff --git a/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java index 583787b9db..66c21ae9f2 100644 --- a/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 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. @@ -33,9 +33,51 @@ import static org.assertj.core.api.Assertions.entry; * Base class for {@link AnnotationMetadata} tests. * * @author Phillip Webb + * @author Sam Brannen */ public abstract class AbstractAnnotationMetadataTests { + @Test + public void verifyEquals() throws Exception { + AnnotationMetadata testClass1 = get(TestClass.class); + AnnotationMetadata testClass2 = get(TestClass.class); + AnnotationMetadata testMemberClass1 = get(TestMemberClass.class); + AnnotationMetadata testMemberClass2 = get(TestMemberClass.class); + + assertThat(testClass1.equals(null)).isFalse(); + + assertThat(testClass1.equals(testClass1)).isTrue(); + assertThat(testClass2.equals(testClass2)).isTrue(); + assertThat(testClass1.equals(testClass2)).isTrue(); + assertThat(testClass2.equals(testClass1)).isTrue(); + + assertThat(testMemberClass1.equals(testMemberClass1)).isTrue(); + assertThat(testMemberClass2.equals(testMemberClass2)).isTrue(); + assertThat(testMemberClass1.equals(testMemberClass2)).isTrue(); + assertThat(testMemberClass2.equals(testMemberClass1)).isTrue(); + + assertThat(testClass1.equals(testMemberClass1)).isFalse(); + assertThat(testMemberClass1.equals(testClass1)).isFalse(); + } + + @Test + public void verifyHashCode() throws Exception { + AnnotationMetadata testClass1 = get(TestClass.class); + AnnotationMetadata testClass2 = get(TestClass.class); + AnnotationMetadata testMemberClass1 = get(TestMemberClass.class); + AnnotationMetadata testMemberClass2 = get(TestMemberClass.class); + + assertThat(testClass1).hasSameHashCodeAs(testClass2); + assertThat(testMemberClass1).hasSameHashCodeAs(testMemberClass2); + + assertThat(testClass1).doesNotHaveSameHashCodeAs(testMemberClass1); + } + + @Test + public void verifyToString() throws Exception { + assertThat(get(TestClass.class).toString()).isEqualTo(TestClass.class.getName()); + } + @Test public void getClassNameReturnsClassName() { assertThat(get(TestClass.class).getClassName()).isEqualTo(TestClass.class.getName()); diff --git a/spring-core/src/test/java/org/springframework/core/type/AbstractMethodMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/AbstractMethodMetadataTests.java index 07d48e4796..14d4ef1a2f 100644 --- a/spring-core/src/test/java/org/springframework/core/type/AbstractMethodMetadataTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/AbstractMethodMetadataTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 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. @@ -37,6 +37,54 @@ import static org.assertj.core.api.Assertions.entry; */ public abstract class AbstractMethodMetadataTests { + @Test + public void verifyEquals() throws Exception { + MethodMetadata withMethod1 = getTagged(WithMethod.class); + MethodMetadata withMethod2 = getTagged(WithMethod.class); + MethodMetadata withMethodWithTwoArguments1 = getTagged(WithMethodWithTwoArguments.class); + MethodMetadata withMethodWithTwoArguments2 = getTagged(WithMethodWithTwoArguments.class); + + assertThat(withMethod1.equals(null)).isFalse(); + + assertThat(withMethod1.equals(withMethod1)).isTrue(); + assertThat(withMethod2.equals(withMethod2)).isTrue(); + assertThat(withMethod1.equals(withMethod2)).isTrue(); + assertThat(withMethod2.equals(withMethod1)).isTrue(); + + assertThat(withMethodWithTwoArguments1.equals(withMethodWithTwoArguments1)).isTrue(); + assertThat(withMethodWithTwoArguments2.equals(withMethodWithTwoArguments2)).isTrue(); + assertThat(withMethodWithTwoArguments1.equals(withMethodWithTwoArguments2)).isTrue(); + assertThat(withMethodWithTwoArguments2.equals(withMethodWithTwoArguments1)).isTrue(); + + assertThat(withMethod1.equals(withMethodWithTwoArguments1)).isFalse(); + assertThat(withMethodWithTwoArguments1.equals(withMethod1)).isFalse(); + } + + @Test + public void verifyHashCode() throws Exception { + MethodMetadata withMethod1 = getTagged(WithMethod.class); + MethodMetadata withMethod2 = getTagged(WithMethod.class); + MethodMetadata withMethodWithTwoArguments1 = getTagged(WithMethodWithTwoArguments.class); + MethodMetadata withMethodWithTwoArguments2 = getTagged(WithMethodWithTwoArguments.class); + + assertThat(withMethod1).hasSameHashCodeAs(withMethod2); + assertThat(withMethodWithTwoArguments1).hasSameHashCodeAs(withMethodWithTwoArguments2); + + assertThat(withMethod1).doesNotHaveSameHashCodeAs(withMethodWithTwoArguments1); + } + + @Test + public void verifyToString() throws Exception { + assertThat(getTagged(WithMethod.class).toString()) + .endsWith(WithMethod.class.getName() + ".test()"); + + assertThat(getTagged(WithMethodWithOneArgument.class).toString()) + .endsWith(WithMethodWithOneArgument.class.getName() + ".test(java.lang.String)"); + + assertThat(getTagged(WithMethodWithTwoArguments.class).toString()) + .endsWith(WithMethodWithTwoArguments.class.getName() + ".test(java.lang.String,java.lang.Integer)"); + } + @Test public void getMethodNameReturnsMethodName() { assertThat(getTagged(WithMethod.class).getMethodName()).isEqualTo("test"); @@ -171,6 +219,24 @@ public abstract class AbstractMethodMetadataTests { } + public static class WithMethodWithOneArgument { + + @Tag + public String test(String text) { + return ""; + } + + } + + public static class WithMethodWithTwoArguments { + + @Tag + public String test(String text, Integer num) { + return ""; + } + + } + public abstract static class WithAbstractMethod { @Tag diff --git a/spring-core/src/test/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitorTests.java b/spring-core/src/test/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitorTests.java index 54672cfd4e..844f56b86d 100644 --- a/spring-core/src/test/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitorTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/classreading/AnnotationMetadataReadingVisitorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 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. @@ -19,6 +19,7 @@ package org.springframework.core.type.classreading; import java.io.BufferedInputStream; import java.io.InputStream; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.asm.ClassReader; @@ -35,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; * Tests for {@link AnnotationMetadataReadingVisitor}. * * @author Phillip Webb + * @author Sam Brannen */ @SuppressWarnings("deprecation") class AnnotationMetadataReadingVisitorTests extends AbstractAnnotationMetadataTests { @@ -62,6 +64,24 @@ class AnnotationMetadataReadingVisitorTests extends AbstractAnnotationMetadataTe } } + @Test + @Disabled("equals() not implemented in deprecated AnnotationMetadataReadingVisitor") + @Override + public void verifyEquals() throws Exception { + } + + @Test + @Disabled("hashCode() not implemented in deprecated AnnotationMetadataReadingVisitor") + @Override + public void verifyHashCode() throws Exception { + } + + @Test + @Disabled("toString() not implemented in deprecated AnnotationMetadataReadingVisitor") + @Override + public void verifyToString() { + } + @Override @Test public void getAnnotationsReturnsDirectAnnotations() { diff --git a/spring-core/src/test/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitorTests.java b/spring-core/src/test/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitorTests.java index 0ed4ed6d2e..d303b031bf 100644 --- a/spring-core/src/test/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitorTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/classreading/MethodMetadataReadingVisitorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2021 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. @@ -19,6 +19,7 @@ package org.springframework.core.type.classreading; import java.io.BufferedInputStream; import java.io.InputStream; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.asm.ClassReader; @@ -35,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; * Tests for {@link MethodMetadataReadingVisitor}. * * @author Phillip Webb + * @author Sam Brannen */ @SuppressWarnings("deprecation") class MethodMetadataReadingVisitorTests extends AbstractMethodMetadataTests { @@ -62,8 +64,26 @@ class MethodMetadataReadingVisitorTests extends AbstractMethodMetadataTests { } } - @Override @Test + @Disabled("equals() not implemented in deprecated MethodMetadataReadingVisitor") + @Override + public void verifyEquals() throws Exception { + } + + @Test + @Disabled("hashCode() not implemented in deprecated MethodMetadataReadingVisitor") + @Override + public void verifyHashCode() throws Exception { + } + + @Test + @Disabled("toString() not implemented in deprecated MethodMetadataReadingVisitor") + @Override + public void verifyToString() { + } + + @Test + @Override public void getAnnotationsReturnsDirectAnnotations() { assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy( super::getAnnotationsReturnsDirectAnnotations);