Simplify SpEL ExpressionWithConversionTests
This commit is contained in:
parent
ac7c7ff5b2
commit
b8c2780bfe
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2024 the original author or authors.
|
* Copyright 2002-2025 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,27 +16,24 @@
|
||||||
|
|
||||||
package org.springframework.expression.spel;
|
package org.springframework.expression.spel;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.core.convert.ConversionService;
|
|
||||||
import org.springframework.core.convert.TypeDescriptor;
|
import org.springframework.core.convert.TypeDescriptor;
|
||||||
import org.springframework.core.convert.support.DefaultConversionService;
|
|
||||||
import org.springframework.expression.EvaluationException;
|
|
||||||
import org.springframework.expression.Expression;
|
import org.springframework.expression.Expression;
|
||||||
import org.springframework.expression.TypeConverter;
|
import org.springframework.expression.TypeConverter;
|
||||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||||
|
import org.springframework.expression.spel.support.StandardTypeConverter;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expression evaluation where the TypeConverter plugged in is the
|
* Expression evaluation where the TypeConverter plugged in uses the
|
||||||
* {@link org.springframework.core.convert.support.GenericConversionService}.
|
* {@link org.springframework.core.convert.support.GenericConversionService}.
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
|
|
@ -44,54 +41,43 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
*/
|
*/
|
||||||
class ExpressionWithConversionTests extends AbstractExpressionTests {
|
class ExpressionWithConversionTests extends AbstractExpressionTests {
|
||||||
|
|
||||||
private static List<String> listOfString = new ArrayList<>();
|
private static final List<String> listOfString = List.of("1", "2", "3");
|
||||||
private static TypeDescriptor typeDescriptorForListOfString = null;
|
private static final List<Integer> listOfInteger = List.of(4, 5, 6);
|
||||||
private static List<Integer> listOfInteger = new ArrayList<>();
|
|
||||||
private static TypeDescriptor typeDescriptorForListOfInteger = null;
|
|
||||||
|
|
||||||
static {
|
private static final TypeDescriptor typeDescriptorForListOfString =
|
||||||
listOfString.add("1");
|
new TypeDescriptor(ReflectionUtils.findField(ExpressionWithConversionTests.class, "listOfString"));
|
||||||
listOfString.add("2");
|
private static TypeDescriptor typeDescriptorForListOfInteger =
|
||||||
listOfString.add("3");
|
new TypeDescriptor(ReflectionUtils.findField(ExpressionWithConversionTests.class, "listOfInteger"));
|
||||||
listOfInteger.add(4);
|
|
||||||
listOfInteger.add(5);
|
|
||||||
listOfInteger.add(6);
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setUp() throws Exception {
|
|
||||||
ExpressionWithConversionTests.typeDescriptorForListOfString = new TypeDescriptor(ExpressionWithConversionTests.class.getDeclaredField("listOfString"));
|
|
||||||
ExpressionWithConversionTests.typeDescriptorForListOfInteger = new TypeDescriptor(ExpressionWithConversionTests.class.getDeclaredField("listOfInteger"));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test the service can convert what we are about to use in the expression evaluation tests.
|
* Test the service can convert what we are about to use in the expression evaluation tests.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testConversionsAvailable() {
|
void conversionsAreSupportedByStandardTypeConverter() {
|
||||||
TypeConvertorUsingConversionService tcs = new TypeConvertorUsingConversionService();
|
StandardTypeConverter typeConverter = new StandardTypeConverter();
|
||||||
|
|
||||||
// ArrayList containing List<Integer> to List<String>
|
// List<Integer> to List<String>
|
||||||
Class<?> clazz = typeDescriptorForListOfString.getElementTypeDescriptor().getType();
|
Class<?> clazz = typeDescriptorForListOfString.getElementTypeDescriptor().getType();
|
||||||
assertThat(clazz).isEqualTo(String.class);
|
assertThat(clazz).isEqualTo(String.class);
|
||||||
List<?> l = (List<?>) tcs.convertValue(listOfInteger, TypeDescriptor.forObject(listOfInteger), typeDescriptorForListOfString);
|
List<?> l = (List<?>) typeConverter.convertValue(listOfInteger, TypeDescriptor.forObject(listOfInteger), typeDescriptorForListOfString);
|
||||||
assertThat(l).isNotNull();
|
assertThat(l).isNotNull();
|
||||||
|
|
||||||
// ArrayList containing List<String> to List<Integer>
|
// List<String> to List<Integer>
|
||||||
clazz = typeDescriptorForListOfInteger.getElementTypeDescriptor().getType();
|
clazz = typeDescriptorForListOfInteger.getElementTypeDescriptor().getType();
|
||||||
assertThat(clazz).isEqualTo(Integer.class);
|
assertThat(clazz).isEqualTo(Integer.class);
|
||||||
|
|
||||||
l = (List<?>) tcs.convertValue(listOfString, TypeDescriptor.forObject(listOfString), typeDescriptorForListOfString);
|
l = (List<?>) typeConverter.convertValue(listOfString, TypeDescriptor.forObject(listOfString), typeDescriptorForListOfString);
|
||||||
assertThat(l).isNotNull();
|
assertThat(l).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testSetParameterizedList() {
|
void setParameterizedList() {
|
||||||
StandardEvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
|
StandardEvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
|
||||||
|
|
||||||
Expression e = parser.parseExpression("listOfInteger.size()");
|
Expression e = parser.parseExpression("listOfInteger.size()");
|
||||||
assertThat(e.getValue(context, Integer.class)).isZero();
|
assertThat(e.getValue(context, Integer.class)).isZero();
|
||||||
context.setTypeConverter(new TypeConvertorUsingConversionService());
|
|
||||||
// Assign a List<String> to the List<Integer> field - the component elements should be converted
|
// Assign a List<String> to the List<Integer> field - the component elements should be converted
|
||||||
parser.parseExpression("listOfInteger").setValue(context,listOfString);
|
parser.parseExpression("listOfInteger").setValue(context,listOfString);
|
||||||
// size now 3
|
// size now 3
|
||||||
|
|
@ -101,7 +87,7 @@ class ExpressionWithConversionTests extends AbstractExpressionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCoercionToCollectionOfPrimitive() throws Exception {
|
void coercionToCollectionOfPrimitive() throws Exception {
|
||||||
|
|
||||||
class TestTarget {
|
class TestTarget {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
|
@ -115,28 +101,28 @@ class ExpressionWithConversionTests extends AbstractExpressionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
|
StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
|
||||||
|
TypeConverter typeConverter = evaluationContext.getTypeConverter();
|
||||||
|
|
||||||
TypeDescriptor collectionType = new TypeDescriptor(new MethodParameter(TestTarget.class.getDeclaredMethod(
|
TypeDescriptor collectionType = new TypeDescriptor(new MethodParameter(TestTarget.class.getDeclaredMethod(
|
||||||
"sum", Collection.class), 0));
|
"sum", Collection.class), 0));
|
||||||
// The type conversion is possible
|
// The type conversion is possible
|
||||||
assertThat(evaluationContext.getTypeConverter()
|
assertThat(typeConverter.canConvert(TypeDescriptor.valueOf(String.class), collectionType)).isTrue();
|
||||||
.canConvert(TypeDescriptor.valueOf(String.class), collectionType)).isTrue();
|
|
||||||
// ... and it can be done successfully
|
// ... and it can be done successfully
|
||||||
assertThat(evaluationContext.getTypeConverter().convertValue("1,2,3,4", TypeDescriptor.valueOf(String.class), collectionType).toString()).isEqualTo("[1, 2, 3, 4]");
|
assertThat(typeConverter.convertValue("1,2,3,4", TypeDescriptor.valueOf(String.class), collectionType))
|
||||||
|
.hasToString("[1, 2, 3, 4]");
|
||||||
|
|
||||||
evaluationContext.setVariable("target", new TestTarget());
|
evaluationContext.setVariable("target", new TestTarget());
|
||||||
|
|
||||||
// OK up to here, so the evaluation should be fine...
|
// OK up to here, so the evaluation should be fine...
|
||||||
// ... but this fails
|
// ... but this fails
|
||||||
int result = (Integer) parser.parseExpression("#target.sum(#root)").getValue(evaluationContext, "1,2,3,4");
|
int result = parser.parseExpression("#target.sum(#root)").getValue(evaluationContext, "1,2,3,4", int.class);
|
||||||
assertThat(result).as("Wrong result: " + result).isEqualTo(10);
|
assertThat(result).isEqualTo(10);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testConvert() {
|
void convert() {
|
||||||
Foo root = new Foo("bar");
|
Foo root = new Foo("bar");
|
||||||
Collection<String> foos = Collections.singletonList("baz");
|
Collection<String> foos = Set.of("baz");
|
||||||
|
|
||||||
StandardEvaluationContext context = new StandardEvaluationContext(root);
|
StandardEvaluationContext context = new StandardEvaluationContext(root);
|
||||||
|
|
||||||
|
|
@ -163,26 +149,7 @@ class ExpressionWithConversionTests extends AbstractExpressionTests {
|
||||||
expression = parser.parseExpression("setFoos(getFoosAsObjects())");
|
expression = parser.parseExpression("setFoos(getFoosAsObjects())");
|
||||||
expression.getValue(context);
|
expression.getValue(context);
|
||||||
baz = root.getFoos().iterator().next();
|
baz = root.getFoos().iterator().next();
|
||||||
assertThat(baz.value).isEqualTo("baz");
|
assertThat(baz.value).isEqualTo("quux");
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Type converter that uses the core conversion service.
|
|
||||||
*/
|
|
||||||
private static class TypeConvertorUsingConversionService implements TypeConverter {
|
|
||||||
|
|
||||||
private final ConversionService service = new DefaultConversionService();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
|
||||||
return this.service.canConvert(sourceType, targetType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object convertValue(Object value, TypeDescriptor sourceType, TypeDescriptor targetType) throws EvaluationException {
|
|
||||||
return this.service.convert(value, sourceType, targetType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -205,11 +172,11 @@ class ExpressionWithConversionTests extends AbstractExpressionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<String> getFoosAsStrings() {
|
public Collection<String> getFoosAsStrings() {
|
||||||
return Collections.singletonList("baz");
|
return Set.of("baz");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<?> getFoosAsObjects() {
|
public Collection<?> getFoosAsObjects() {
|
||||||
return Collections.singletonList("baz");
|
return Set.of("quux");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue