diff --git a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java index ffa0da8694..1c7c6d44ef 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java +++ b/spring-core/src/main/java/org/springframework/core/convert/TypeDescriptor.java @@ -522,7 +522,7 @@ public class TypeDescriptor implements Serializable { /** * Create a new type descriptor for an object. *
Use this factory method to introspect a source object before asking the - * conversion system to convert it to some another type. + * conversion system to convert it to some other type. *
If the provided object is {@code null}, returns {@code null}, else calls
* {@link #valueOf(Class)} to build a TypeDescriptor from the object's class.
* @param source the source object
diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java
index 74fad1177a..4c82d36e64 100644
--- a/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java
+++ b/spring-expression/src/test/java/org/springframework/expression/spel/support/ReflectionHelperTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2023 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.
@@ -21,6 +21,7 @@ import java.io.PrintStream;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
@@ -44,11 +45,12 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
* Tests for reflection helper code.
*
* @author Andy Clement
+ * @author Sam Brannen
*/
-public class ReflectionHelperTests extends AbstractExpressionTests {
+class ReflectionHelperTests extends AbstractExpressionTests {
@Test
- public void testUtilities() throws ParseException {
+ void utilities() throws ParseException {
SpelExpression expr = (SpelExpression)parser.parseExpression("3+4+5+6+7-2");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
@@ -74,12 +76,12 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
// CompoundExpression value:2
// IntLiteral value:2
// ===> Expression '3+4+5+6+7-2' - AST end
- assertThat(s.contains("===> Expression '3+4+5+6+7-2' - AST start")).isTrue();
- assertThat(s.contains(" OpPlus value:((((3 + 4) + 5) + 6) + 7) #children:2")).isTrue();
+ assertThat(s).contains("===> Expression '3+4+5+6+7-2' - AST start");
+ assertThat(s).contains(" OpPlus value:((((3 + 4) + 5) + 6) + 7) #children:2");
}
@Test
- public void testTypedValue() {
+ void typedValue() {
TypedValue tv1 = new TypedValue("hello");
TypedValue tv2 = new TypedValue("hello");
TypedValue tv3 = new TypedValue("bye");
@@ -91,13 +93,13 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
assertThat(tv3).isNotEqualTo(tv2);
assertThat(tv1).isNotEqualTo(tv3);
assertThat(tv2).isNotEqualTo(tv3);
- assertThat(tv2.hashCode()).isEqualTo(tv1.hashCode());
- assertThat(tv3.hashCode()).isNotEqualTo(tv1.hashCode());
- assertThat(tv3.hashCode()).isNotEqualTo(tv2.hashCode());
+ assertThat(tv2).hasSameHashCodeAs(tv1);
+ assertThat(tv3).doesNotHaveSameHashCodeAs(tv1);
+ assertThat(tv3).doesNotHaveSameHashCodeAs(tv2);
}
@Test
- public void testReflectionHelperCompareArguments_ExactMatching() {
+ void reflectionHelperCompareArguments_ExactMatching() {
StandardTypeConverter tc = new StandardTypeConverter();
// Calling foo(String) with (String) is exact match
@@ -108,7 +110,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
}
@Test
- public void testReflectionHelperCompareArguments_CloseMatching() {
+ void reflectionHelperCompareArguments_CloseMatching() {
StandardTypeConverter tc = new StandardTypeConverter();
// Calling foo(List) with (ArrayList) is close match (no conversion required)
@@ -122,7 +124,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
}
@Test
- public void testReflectionHelperCompareArguments_RequiresConversionMatching() {
+ void reflectionHelperCompareArguments_RequiresConversionMatching() {
StandardTypeConverter tc = new StandardTypeConverter();
// Calling foo(String,int) with (String,Integer) requires boxing conversion of argument one
@@ -139,7 +141,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
}
@Test
- public void testReflectionHelperCompareArguments_NotAMatch() {
+ void reflectionHelperCompareArguments_NotAMatch() {
StandardTypeConverter typeConverter = new StandardTypeConverter();
// Passing (Super,String) on call to foo(Sub,String) is not a match
@@ -147,7 +149,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
}
@Test
- public void testReflectionHelperCompareArguments_Varargs_ExactMatching() {
+ void reflectionHelperCompareArguments_Varargs_ExactMatching() {
StandardTypeConverter tc = new StandardTypeConverter();
// Passing (String[]) on call to (String[]) is exact match
@@ -198,7 +200,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
}
@Test
- public void testConvertArguments() throws Exception {
+ void convertArguments() throws Exception {
StandardTypeConverter tc = new StandardTypeConverter();
Method oneArg = TestInterface.class.getMethod("oneArg", String.class);
Method twoArg = TestInterface.class.getMethod("twoArg", String.class, String[].class);
@@ -225,7 +227,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
}
@Test
- public void testConvertArguments2() throws Exception {
+ void convertArguments2() throws Exception {
StandardTypeConverter tc = new StandardTypeConverter();
Method oneArg = TestInterface.class.getMethod("oneArg", String.class);
Method twoArg = TestInterface.class.getMethod("twoArg", String.class, String[].class);
@@ -252,7 +254,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
}
@Test
- public void testSetupArguments() {
+ void setupArguments() {
Object[] newArray = ReflectionHelper.setupArgumentsForVarargsInvocation(
new Class>[] {String[].class}, "a", "b", "c");
@@ -260,14 +262,11 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
Object firstParam = newArray[0];
assertThat(firstParam.getClass().getComponentType()).isEqualTo(String.class);
Object[] firstParamArray = (Object[]) firstParam;
- assertThat(firstParamArray).hasSize(3);
- assertThat(firstParamArray[0]).isEqualTo("a");
- assertThat(firstParamArray[1]).isEqualTo("b");
- assertThat(firstParamArray[2]).isEqualTo("c");
+ assertThat(firstParamArray).containsExactly("a", "b", "c");
}
@Test
- public void testReflectivePropertyAccessor() throws Exception {
+ void reflectivePropertyAccessor() throws Exception {
ReflectivePropertyAccessor rpa = new ReflectivePropertyAccessor();
Tester t = new Tester();
t.setProperty("hello");
@@ -328,7 +327,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
}
@Test
- public void testOptimalReflectivePropertyAccessor() throws Exception {
+ void optimalReflectivePropertyAccessor() throws Exception {
ReflectivePropertyAccessor reflective = new ReflectivePropertyAccessor();
Tester tester = new Tester();
tester.setProperty("hello");
@@ -374,19 +373,28 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
MethodResolver resolver = new ReflectiveMethodResolver();
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
+ // Nonexistent method
MethodExecutor bogus = resolver.resolve(evaluationContext, proxy, "bogus", List.of());
assertThat(bogus).as("MethodExecutor for bogus()").isNull();
+
+ // Method in interface
+ MethodExecutor run = resolver.resolve(evaluationContext, proxy, "run", List.of());
+ assertThat(run).as("MethodExecutor for run()").isNotNull();
+
+ // Methods in Object
MethodExecutor toString = resolver.resolve(evaluationContext, proxy, "toString", List.of());
assertThat(toString).as("MethodExecutor for toString()").isNotNull();
MethodExecutor hashCode = resolver.resolve(evaluationContext, proxy, "hashCode", List.of());
assertThat(hashCode).as("MethodExecutor for hashCode()").isNotNull();
+ MethodExecutor equals = resolver.resolve(evaluationContext, proxy, "equals", typeDescriptors(Object.class));
+ assertThat(equals).as("MethodExecutor for equals()").isNotNull();
}
/**
* Used to validate the match returned from a compareArguments call.
*/
private void checkMatch(Class>[] inputTypes, Class>[] expectedTypes, StandardTypeConverter typeConverter, ArgumentsMatchKind expectedMatchKind) {
- ReflectionHelper.ArgumentsMatchInfo matchInfo = ReflectionHelper.compareArguments(getTypeDescriptors(expectedTypes), getTypeDescriptors(inputTypes), typeConverter);
+ ReflectionHelper.ArgumentsMatchInfo matchInfo = ReflectionHelper.compareArguments(typeDescriptors(expectedTypes), typeDescriptors(inputTypes), typeConverter);
if (expectedMatchKind == null) {
assertThat(matchInfo).as("Did not expect them to match in any way").isNull();
}
@@ -408,47 +416,42 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
/**
* Used to validate the match returned from a compareArguments call.
*/
- private void checkMatch2(Class>[] inputTypes, Class>[] expectedTypes, StandardTypeConverter typeConverter, ArgumentsMatchKind expectedMatchKind) {
- ReflectionHelper.ArgumentsMatchInfo matchInfo = ReflectionHelper.compareArgumentsVarargs(getTypeDescriptors(expectedTypes), getTypeDescriptors(inputTypes), typeConverter);
+ private static void checkMatch2(Class>[] inputTypes, Class>[] expectedTypes,
+ StandardTypeConverter typeConverter, ArgumentsMatchKind expectedMatchKind) {
+
+ ReflectionHelper.ArgumentsMatchInfo matchInfo =
+ ReflectionHelper.compareArgumentsVarargs(typeDescriptors(expectedTypes), typeDescriptors(inputTypes), typeConverter);
if (expectedMatchKind == null) {
assertThat(matchInfo).as("Did not expect them to match in any way: " + matchInfo).isNull();
}
else {
assertThat(matchInfo).as("Should not be a null match").isNotNull();
- }
-
- if (expectedMatchKind == ArgumentsMatchKind.EXACT) {
- assertThat(matchInfo.isExactMatch()).isTrue();
- }
- else if (expectedMatchKind == ArgumentsMatchKind.CLOSE) {
- assertThat(matchInfo.isCloseMatch()).isTrue();
- }
- else if (expectedMatchKind == ArgumentsMatchKind.REQUIRES_CONVERSION) {
- assertThat(matchInfo.isMatchRequiringConversion()).as("expected to be a match requiring conversion, but was " + matchInfo).isTrue();
+ switch (expectedMatchKind) {
+ case EXACT -> assertThat(matchInfo.isExactMatch()).isTrue();
+ case CLOSE -> assertThat(matchInfo.isCloseMatch()).isTrue();
+ case REQUIRES_CONVERSION -> assertThat(matchInfo.isMatchRequiringConversion())
+ .as("expected to be a match requiring conversion, but was " + matchInfo).isTrue();
+ }
}
}
- private void checkArguments(Object[] args, Object... expected) {
+ private static void checkArguments(Object[] args, Object... expected) {
assertThat(args).hasSize(expected.length);
for (int i = 0; i < expected.length; i++) {
- checkArgument(expected[i],args[i]);
+ checkArgument(expected[i], args[i]);
}
}
- private void checkArgument(Object expected, Object actual) {
+ private static void checkArgument(Object expected, Object actual) {
assertThat(actual).isEqualTo(expected);
}
- private List