Improve tests for indexing and collection selection/projection in SpEL
This commit is contained in:
parent
3ecbc4de13
commit
9a38355896
|
|
@ -30,7 +30,6 @@ import java.util.Map;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
|
@ -38,6 +37,9 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
|||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.springframework.expression.spel.SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE;
|
||||
import static org.springframework.expression.spel.SpelMessage.UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
class IndexingTests {
|
||||
|
|
@ -50,16 +52,14 @@ class IndexingTests {
|
|||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.HashMap<?, ?>");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.util.HashMap<?, ?>", FieldAnnotation.class.getName());
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
assertThat(expression.getValue(this, Map.class)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property['foo']");
|
||||
assertThat(expression.getValue(this)).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@FieldAnnotation
|
||||
public Object property;
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void indexIntoGenericPropertyContainingMapObject() {
|
||||
|
|
@ -72,14 +72,323 @@ class IndexingTests {
|
|||
context.addPropertyAccessor(new MapAccessor());
|
||||
context.setRootObject(property);
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(context).toString()).isEqualTo("java.util.HashMap<?, ?>");
|
||||
assertThat(expression.getValueTypeDescriptor(context)).asString()
|
||||
.isEqualTo("java.util.HashMap<?, ?>");
|
||||
assertThat(expression.getValue(context)).isEqualTo(map);
|
||||
assertThat(expression.getValue(context, Map.class)).isEqualTo(map);
|
||||
expression = parser.parseExpression("property['foo']");
|
||||
assertThat(expression.getValue(context)).isEqualTo("bar");
|
||||
}
|
||||
|
||||
public static class MapAccessor implements PropertyAccessor {
|
||||
@Test
|
||||
void setGenericPropertyContainingMap() {
|
||||
Map<String, String> property = new HashMap<>();
|
||||
property.put("foo", "bar");
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.util.HashMap<?, ?>", FieldAnnotation.class.getName());
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property['foo']");
|
||||
assertThat(expression.getValue(this)).isEqualTo("bar");
|
||||
expression.setValue(this, "baz");
|
||||
assertThat(expression.getValue(this)).isEqualTo("baz");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setPropertyContainingMap() {
|
||||
Map<Integer, Integer> property = new HashMap<>();
|
||||
property.put(9, 3);
|
||||
this.parameterizedMap = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("parameterizedMap");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("java.util.HashMap<java.lang.Integer, java.lang.Integer>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("parameterizedMap['9']");
|
||||
assertThat(expression.getValue(this)).isEqualTo(3);
|
||||
expression.setValue(this, "37");
|
||||
assertThat(expression.getValue(this)).isEqualTo(37);
|
||||
}
|
||||
|
||||
@Test
|
||||
void setPropertyContainingMapAutoGrow() {
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, false));
|
||||
Expression expression = parser.parseExpression("parameterizedMap");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("java.util.Map<java.lang.Integer, java.lang.Integer>");
|
||||
assertThat(expression.getValue(this)).isNull();
|
||||
expression = parser.parseExpression("parameterizedMap['9']");
|
||||
assertThat(expression.getValue(this)).isNull();
|
||||
expression.setValue(this, "37");
|
||||
assertThat(expression.getValue(this)).isEqualTo(37);
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingList() {
|
||||
List<String> property = new ArrayList<>();
|
||||
property.add("bar");
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.util.ArrayList<?>", FieldAnnotation.class.getName());
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property[0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setGenericPropertyContainingList() {
|
||||
List<Integer> property = new ArrayList<>();
|
||||
property.add(3);
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.util.ArrayList<?>", FieldAnnotation.class.getName());
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property[0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo(3);
|
||||
expression.setValue(this, "4");
|
||||
assertThat(expression.getValue(this)).isEqualTo("4");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setGenericPropertyContainingListAutogrow() {
|
||||
List<Integer> property = new ArrayList<>();
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.util.ArrayList<?>", FieldAnnotation.class.getName());
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
|
||||
Expression indexExpression = parser.parseExpression("property[0]");
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
.isThrownBy(() -> indexExpression.getValue(this))
|
||||
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void autoGrowListOfElementsWithoutDefaultConstructor() {
|
||||
this.decimals = new ArrayList<>();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
parser.parseExpression("decimals[0]").setValue(this, "123.4");
|
||||
assertThat(decimals).containsExactly(BigDecimal.valueOf(123.4));
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoPropertyContainingListContainingNullElement() {
|
||||
this.decimals = new ArrayList<>();
|
||||
this.decimals.add(null);
|
||||
this.decimals.add(BigDecimal.ONE);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
parser.parseExpression("decimals[0]").setValue(this, "9876.5");
|
||||
assertThat(decimals).containsExactly(BigDecimal.valueOf(9876.5), BigDecimal.ONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoPropertyContainingList() {
|
||||
List<Integer> property = new ArrayList<>();
|
||||
property.add(3);
|
||||
this.parameterizedList = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("parameterizedList");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("java.util.ArrayList<java.lang.Integer>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("parameterizedList[0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoPropertyContainingListOfList() {
|
||||
List<List<Integer>> property = new ArrayList<>();
|
||||
property.add(Arrays.asList(3));
|
||||
this.parameterizedListOfList = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("parameterizedListOfList[0]");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("java.util.Arrays$ArrayList<java.lang.Integer>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property.get(0));
|
||||
expression = parser.parseExpression("parameterizedListOfList[0][0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void setPropertyContainingList() {
|
||||
List<Integer> property = new ArrayList<>();
|
||||
property.add(3);
|
||||
this.parameterizedList = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("parameterizedList");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("java.util.ArrayList<java.lang.Integer>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("parameterizedList[0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo(3);
|
||||
expression.setValue(this, "4");
|
||||
assertThat(expression.getValue(this)).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingNullList() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.lang.Object", FieldAnnotation.class.getName());
|
||||
assertThat(expression.getValue(this)).isNull();
|
||||
|
||||
Expression indexExpression = parser.parseExpression("property[0]");
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
.isThrownBy(() -> indexExpression.getValue(this))
|
||||
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(INDEXING_NOT_SUPPORTED_FOR_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingGrowingList() {
|
||||
List<String> property = new ArrayList<>();
|
||||
this.property = property;
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.util.ArrayList<?>", FieldAnnotation.class.getName());
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
|
||||
Expression indexExpression = parser.parseExpression("property[0]");
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
.isThrownBy(() -> indexExpression.getValue(this))
|
||||
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingGrowingList2() {
|
||||
List<String> property2 = new ArrayList<>();
|
||||
this.property2 = property2;
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
Expression expression = parser.parseExpression("property2");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString().isEqualTo("java.util.ArrayList<?>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property2);
|
||||
|
||||
Expression indexExpression = parser.parseExpression("property2[0]");
|
||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||
.isThrownBy(() -> indexExpression.getValue(this))
|
||||
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE));
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingArray() {
|
||||
String[] property = new String[] { "bar" };
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.lang.String[]", FieldAnnotation.class.getName());
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property[0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyList() {
|
||||
listOfScalarNotGeneric = new ArrayList();
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listOfScalarNotGeneric");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString().isEqualTo("java.util.ArrayList<?>");
|
||||
assertThat(expression.getValue(this, String.class)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void resolveCollectionElementType() {
|
||||
listNotGeneric = new ArrayList(2);
|
||||
listNotGeneric.add(5);
|
||||
listNotGeneric.add(6);
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listNotGeneric");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.util.ArrayList<?>", FieldAnnotation.class.getName());
|
||||
assertThat(expression.getValue(this, String.class)).isEqualTo("5,6");
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveCollectionElementTypeNull() {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listNotGeneric");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.util.List<?>", FieldAnnotation.class.getName());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
void resolveMapKeyValueTypes() {
|
||||
mapNotGeneric = new HashMap();
|
||||
mapNotGeneric.put("baseAmount", 3.11);
|
||||
mapNotGeneric.put("bonusAmount", 7.17);
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("mapNotGeneric");
|
||||
assertThat(expression.getValueTypeDescriptor(this)).asString()
|
||||
.isEqualTo("@%s java.util.HashMap<?, ?>", FieldAnnotation.class.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void testListOfScalar() {
|
||||
listOfScalarNotGeneric = new ArrayList(1);
|
||||
listOfScalarNotGeneric.add("5");
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listOfScalarNotGeneric[0]");
|
||||
assertThat(expression.getValue(this, Integer.class)).isEqualTo(Integer.valueOf(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void testListsOfMap() {
|
||||
listOfMapsNotGeneric = new ArrayList();
|
||||
Map map = new HashMap();
|
||||
map.put("fruit", "apple");
|
||||
listOfMapsNotGeneric.add(map);
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listOfMapsNotGeneric[0]['fruit']");
|
||||
assertThat(expression.getValue(this, String.class)).isEqualTo("apple");
|
||||
}
|
||||
|
||||
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface FieldAnnotation {
|
||||
}
|
||||
|
||||
@FieldAnnotation
|
||||
public Object property;
|
||||
|
||||
public List property2;
|
||||
|
||||
public Map<Integer, Integer> parameterizedMap;
|
||||
|
||||
public List<BigDecimal> decimals;
|
||||
|
||||
public List<Integer> parameterizedList;
|
||||
|
||||
public List<List<Integer>> parameterizedListOfList;
|
||||
|
||||
@FieldAnnotation
|
||||
public List listNotGeneric;
|
||||
|
||||
@FieldAnnotation
|
||||
public Map mapNotGeneric;
|
||||
|
||||
public List listOfScalarNotGeneric;
|
||||
|
||||
public List listOfMapsNotGeneric;
|
||||
|
||||
|
||||
private static class MapAccessor implements PropertyAccessor {
|
||||
|
||||
@Override
|
||||
public boolean canRead(EvaluationContext context, Object target, String name) {
|
||||
|
|
@ -109,302 +418,4 @@ class IndexingTests {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
void setGenericPropertyContainingMap() {
|
||||
Map<String, String> property = new HashMap<>();
|
||||
property.put("foo", "bar");
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.HashMap<?, ?>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property['foo']");
|
||||
assertThat(expression.getValue(this)).isEqualTo("bar");
|
||||
expression.setValue(this, "baz");
|
||||
assertThat(expression.getValue(this)).isEqualTo("baz");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setPropertyContainingMap() {
|
||||
Map<Integer, Integer> property = new HashMap<>();
|
||||
property.put(9, 3);
|
||||
this.parameterizedMap = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("parameterizedMap");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("java.util.HashMap<java.lang.Integer, java.lang.Integer>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("parameterizedMap['9']");
|
||||
assertThat(expression.getValue(this)).isEqualTo(3);
|
||||
expression.setValue(this, "37");
|
||||
assertThat(expression.getValue(this)).isEqualTo(37);
|
||||
}
|
||||
|
||||
public Map<Integer, Integer> parameterizedMap;
|
||||
|
||||
@Test
|
||||
void setPropertyContainingMapAutoGrow() {
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, false));
|
||||
Expression expression = parser.parseExpression("parameterizedMap");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("java.util.Map<java.lang.Integer, java.lang.Integer>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("parameterizedMap['9']");
|
||||
assertThat(expression.getValue(this)).isNull();
|
||||
expression.setValue(this, "37");
|
||||
assertThat(expression.getValue(this)).isEqualTo(37);
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingList() {
|
||||
List<String> property = new ArrayList<>();
|
||||
property.add("bar");
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property[0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setGenericPropertyContainingList() {
|
||||
List<Integer> property = new ArrayList<>();
|
||||
property.add(3);
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property[0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo(3);
|
||||
expression.setValue(this, "4");
|
||||
assertThat(expression.getValue(this)).isEqualTo("4");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setGenericPropertyContainingListAutogrow() {
|
||||
List<Integer> property = new ArrayList<>();
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property[0]");
|
||||
try {
|
||||
expression.setValue(this, "4");
|
||||
}
|
||||
catch (EvaluationException ex) {
|
||||
assertThat(ex.getMessage()).startsWith("EL1053E");
|
||||
}
|
||||
}
|
||||
|
||||
public List<BigDecimal> decimals;
|
||||
|
||||
@Test
|
||||
void autoGrowListOfElementsWithoutDefaultConstructor() {
|
||||
this.decimals = new ArrayList<>();
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
parser.parseExpression("decimals[0]").setValue(this, "123.4");
|
||||
assertThat(decimals).containsExactly(BigDecimal.valueOf(123.4));
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoPropertyContainingListContainingNullElement() {
|
||||
this.decimals = new ArrayList<>();
|
||||
this.decimals.add(null);
|
||||
this.decimals.add(BigDecimal.ONE);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
parser.parseExpression("decimals[0]").setValue(this, "9876.5");
|
||||
assertThat(decimals).containsExactly(BigDecimal.valueOf(9876.5), BigDecimal.ONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoPropertyContainingList() {
|
||||
List<Integer> property = new ArrayList<>();
|
||||
property.add(3);
|
||||
this.parameterizedList = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("parameterizedList");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("java.util.ArrayList<java.lang.Integer>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("parameterizedList[0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo(3);
|
||||
}
|
||||
|
||||
public List<Integer> parameterizedList;
|
||||
|
||||
@Test
|
||||
void indexIntoPropertyContainingListOfList() {
|
||||
List<List<Integer>> property = new ArrayList<>();
|
||||
property.add(Arrays.asList(3));
|
||||
this.parameterizedListOfList = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("parameterizedListOfList[0]");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("java.util.Arrays$ArrayList<java.lang.Integer>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property.get(0));
|
||||
expression = parser.parseExpression("parameterizedListOfList[0][0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo(3);
|
||||
}
|
||||
|
||||
public List<List<Integer>> parameterizedListOfList;
|
||||
|
||||
@Test
|
||||
void setPropertyContainingList() {
|
||||
List<Integer> property = new ArrayList<>();
|
||||
property.add(3);
|
||||
this.parameterizedList = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("parameterizedList");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("java.util.ArrayList<java.lang.Integer>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("parameterizedList[0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo(3);
|
||||
expression.setValue(this, "4");
|
||||
assertThat(expression.getValue(this)).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingNullList() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.lang.Object");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property[0]");
|
||||
try {
|
||||
assertThat(expression.getValue(this)).isEqualTo("bar");
|
||||
}
|
||||
catch (EvaluationException ex) {
|
||||
assertThat(ex.getMessage()).startsWith("EL1027E");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingGrowingList() {
|
||||
List<String> property = new ArrayList<>();
|
||||
this.property = property;
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property[0]");
|
||||
try {
|
||||
assertThat(expression.getValue(this)).isEqualTo("bar");
|
||||
}
|
||||
catch (EvaluationException ex) {
|
||||
assertThat(ex.getMessage()).startsWith("EL1053E");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingGrowingList2() {
|
||||
List<String> property2 = new ArrayList<>();
|
||||
this.property2 = property2;
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(true, true);
|
||||
SpelExpressionParser parser = new SpelExpressionParser(configuration);
|
||||
Expression expression = parser.parseExpression("property2");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("java.util.ArrayList<?>");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property2);
|
||||
expression = parser.parseExpression("property2[0]");
|
||||
try {
|
||||
assertThat(expression.getValue(this)).isEqualTo("bar");
|
||||
}
|
||||
catch (EvaluationException ex) {
|
||||
assertThat(ex.getMessage()).startsWith("EL1053E");
|
||||
}
|
||||
}
|
||||
|
||||
public List property2;
|
||||
|
||||
@Test
|
||||
void indexIntoGenericPropertyContainingArray() {
|
||||
String[] property = new String[] { "bar" };
|
||||
this.property = property;
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("property");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.lang.String[]");
|
||||
assertThat(expression.getValue(this)).isEqualTo(property);
|
||||
expression = parser.parseExpression("property[0]");
|
||||
assertThat(expression.getValue(this)).isEqualTo("bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyList() {
|
||||
listOfScalarNotGeneric = new ArrayList();
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listOfScalarNotGeneric");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("java.util.ArrayList<?>");
|
||||
assertThat(expression.getValue(this, String.class)).isEmpty();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
void resolveCollectionElementType() {
|
||||
listNotGeneric = new ArrayList(2);
|
||||
listNotGeneric.add(5);
|
||||
listNotGeneric.add(6);
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listNotGeneric");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.ArrayList<?>");
|
||||
assertThat(expression.getValue(this, String.class)).isEqualTo("5,6");
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveCollectionElementTypeNull() {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listNotGeneric");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.List<?>");
|
||||
}
|
||||
|
||||
@FieldAnnotation
|
||||
public List listNotGeneric;
|
||||
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface FieldAnnotation {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
void resolveMapKeyValueTypes() {
|
||||
mapNotGeneric = new HashMap();
|
||||
mapNotGeneric.put("baseAmount", 3.11);
|
||||
mapNotGeneric.put("bonusAmount", 7.17);
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("mapNotGeneric");
|
||||
assertThat(expression.getValueTypeDescriptor(this).toString()).isEqualTo("@org.springframework.expression.spel.IndexingTests$FieldAnnotation java.util.HashMap<?, ?>");
|
||||
}
|
||||
|
||||
@FieldAnnotation
|
||||
public Map mapNotGeneric;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
void testListOfScalar() {
|
||||
listOfScalarNotGeneric = new ArrayList(1);
|
||||
listOfScalarNotGeneric.add("5");
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listOfScalarNotGeneric[0]");
|
||||
assertThat(expression.getValue(this, Integer.class)).isEqualTo(Integer.valueOf(5));
|
||||
}
|
||||
|
||||
public List listOfScalarNotGeneric;
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
void testListsOfMap() {
|
||||
listOfMapsNotGeneric = new ArrayList();
|
||||
Map map = new HashMap();
|
||||
map.put("fruit", "apple");
|
||||
listOfMapsNotGeneric.add(map);
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
Expression expression = parser.parseExpression("listOfMapsNotGeneric[0]['fruit']");
|
||||
assertThat(expression.getValue(this, String.class)).isEqualTo("apple");
|
||||
}
|
||||
|
||||
public List listOfMapsNotGeneric;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,18 +17,22 @@
|
|||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ExpressionParser;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.standard.SpelExpression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
|
@ -36,6 +40,7 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
|
|||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.InstanceOfAssertFactories.INTEGER;
|
||||
import static org.assertj.core.api.InstanceOfAssertFactories.LIST;
|
||||
import static org.assertj.core.api.InstanceOfAssertFactories.array;
|
||||
import static org.springframework.expression.spel.SpelMessage.INVALID_TYPE_FOR_SELECTION;
|
||||
import static org.springframework.expression.spel.SpelMessage.PROJECTION_NOT_SUPPORTED_ON_TYPE;
|
||||
import static org.springframework.expression.spel.SpelMessage.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN;
|
||||
|
|
@ -46,241 +51,244 @@ import static org.springframework.expression.spel.SpelMessage.RESULT_OF_SELECTIO
|
|||
* @author Juergen Hoeller
|
||||
* @author Andy Clement
|
||||
*/
|
||||
class SelectionAndProjectionTests extends AbstractExpressionTests {
|
||||
class SelectionAndProjectionTests {
|
||||
|
||||
@Nested
|
||||
class SelectionTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void selectionOnUnsupportedType() {
|
||||
evaluateAndCheckError("'abc'.?[#this < 5]", INVALID_TYPE_FOR_SELECTION);
|
||||
evaluateAndCheckError("null.?[#this < 5]", INVALID_TYPE_FOR_SELECTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionWithNonBooleanSelectionCriteria() {
|
||||
evaluateAndCheckError("mapOfNumbersUpToTen.?['hello']", RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
|
||||
evaluateAndCheckError("mapOfNumbersUpToTen.keySet().?['hello']", RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionWithSafeNavigation() {
|
||||
evaluate("null?.?[true]", null, null);
|
||||
evaluate("{1,2,3}?.?[true]", List.of(1, 2, 3), ArrayList.class);
|
||||
evaluate("{1,2,3,4,5,6}?.?[#this between {2, 4}]", List.of(2, 3, 4), ArrayList.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionAST() {
|
||||
// select first
|
||||
SpelExpression expr = (SpelExpression) parser.parseExpression("'abc'.^[true]");
|
||||
assertThat(expr.toStringAST()).isEqualTo("'abc'.^[true]");
|
||||
|
||||
// select all
|
||||
expr = (SpelExpression) parser.parseExpression("'abc'.?[true]");
|
||||
assertThat(expr.toStringAST()).isEqualTo("'abc'.?[true]");
|
||||
|
||||
// select last
|
||||
expr = (SpelExpression) parser.parseExpression("'abc'.$[true]");
|
||||
assertThat(expr.toStringAST()).isEqualTo("'abc'.$[true]");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectionWithList() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ListTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(0, 1, 2, 3, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectFirstItemInList() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.^[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ListTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectLastItemInList() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.$[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ListTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionWithSetAndRegex() {
|
||||
evaluate("testMap.keySet().?[#this matches '.*o.*']", "[monday]", ArrayList.class);
|
||||
evaluate("testMap.keySet().?[#this matches '.*r.*'].contains('saturday')", "true", Boolean.class);
|
||||
evaluate("testMap.keySet().?[#this matches '.*r.*'].size()", "3", Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectionWithSet() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new SetTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(0, 1, 2, 3, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectFirstItemInSet() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.^[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new SetTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectLastItemInSet() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.$[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new SetTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isEqualTo(4);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"#root.?[#this < 3]", "?[#this < 3]"})
|
||||
void selectionWithIterable(String expressionString) {
|
||||
Expression expression = new SpelExpressionParser().parseRaw(expressionString);
|
||||
EvaluationContext context = new StandardEvaluationContext(new IterableTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(1, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionWithArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
Object value = expression.getValue(context);
|
||||
assertThat(value).asInstanceOf(array(Integer[].class)).containsExactly(0, 1, 2, 3, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectFirstItemInArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.^[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectLastItemInArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.$[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionWithPrimitiveArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("ints.?[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
Object value = expression.getValue(context);
|
||||
assertThat(value).asInstanceOf(array(Integer[].class)).containsExactly(0, 1, 2, 3, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectFirstItemInPrimitiveArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("ints.^[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectLastItemInPrimitiveArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("ints.$[#this < 5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectionWithMap() {
|
||||
EvaluationContext context = new StandardEvaluationContext(new MapTestBean());
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
Expression exp = parser.parseExpression("colors.?[key.startsWith('b')]");
|
||||
Map<String, String> colorsMap = (Map<String, String>) exp.getValue(context);
|
||||
assertThat(colorsMap).containsOnlyKeys("beige", "blue", "brown");
|
||||
|
||||
exp = parser.parseExpression("colors.?[key.startsWith('X')]");
|
||||
|
||||
colorsMap = (Map<String, String>) exp.getValue(context);
|
||||
assertThat(colorsMap).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectFirstItemInMap() {
|
||||
EvaluationContext context = new StandardEvaluationContext(new MapTestBean());
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
Expression exp = parser.parseExpression("colors.^[key.startsWith('b')]");
|
||||
Map<String, String> colorsMap = (Map<String, String>) exp.getValue(context);
|
||||
assertThat(colorsMap).containsOnlyKeys("beige");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectLastItemInMap() {
|
||||
EvaluationContext context = new StandardEvaluationContext(new MapTestBean());
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
Expression exp = parser.parseExpression("colors.$[key.startsWith('b')]");
|
||||
Map<String, String> colorsMap = (Map<String, String>) exp.getValue(context);
|
||||
assertThat(colorsMap).containsOnlyKeys("brown");
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionOnUnsupportedType() {
|
||||
evaluateAndCheckError("'abc'.?[#this<5]", INVALID_TYPE_FOR_SELECTION);
|
||||
evaluateAndCheckError("null.?[#this<5]", INVALID_TYPE_FOR_SELECTION);
|
||||
}
|
||||
|
||||
@Test
|
||||
void projectionOnUnsupportedType() {
|
||||
evaluateAndCheckError("'abc'.![true]", PROJECTION_NOT_SUPPORTED_ON_TYPE);
|
||||
evaluateAndCheckError("null.![true]", PROJECTION_NOT_SUPPORTED_ON_TYPE);
|
||||
}
|
||||
@Nested
|
||||
class ProjectionTests extends AbstractExpressionTests {
|
||||
|
||||
@Test
|
||||
void selectionOnNullWithSafeNavigation() {
|
||||
evaluate("null?.?[#this<5]", null, null);
|
||||
}
|
||||
@Test
|
||||
void projectionOnUnsupportedType() {
|
||||
evaluateAndCheckError("'abc'.![true]", PROJECTION_NOT_SUPPORTED_ON_TYPE);
|
||||
evaluateAndCheckError("null.![true]", PROJECTION_NOT_SUPPORTED_ON_TYPE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void projectionOnNullWithSafeNavigation() {
|
||||
evaluate("null?.![true]", null, null);
|
||||
}
|
||||
@Test
|
||||
void projectionWithSafeNavigation() {
|
||||
evaluate("null?.![#this]", null, null);
|
||||
evaluate("{1,2,3}?.![#this % 2]", List.of(1, 0, 1), ArrayList.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionWithNonBooleanSelectionCriteria() {
|
||||
evaluateAndCheckError("mapOfNumbersUpToTen.?['hello']", RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
|
||||
evaluateAndCheckError("mapOfNumbersUpToTen.keySet().?['hello']", RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
|
||||
}
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void projectionWithList() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("#testList.![wrapper.value]");
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("testList", IntegerTestBean.createList());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(5, 6, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionAST() {
|
||||
// select first
|
||||
SpelExpression expr = (SpelExpression) parser.parseExpression("'abc'.^[true]");
|
||||
assertThat(expr.toStringAST()).isEqualTo("'abc'.^[true]");
|
||||
|
||||
// select all
|
||||
expr = (SpelExpression) parser.parseExpression("'abc'.?[true]");
|
||||
assertThat(expr.toStringAST()).isEqualTo("'abc'.?[true]");
|
||||
|
||||
// select last
|
||||
expr = (SpelExpression) parser.parseExpression("'abc'.$[true]");
|
||||
assertThat(expr.toStringAST()).isEqualTo("'abc'.$[true]");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectionWithList() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ListTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(0, 1, 2, 3, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectFirstItemInList() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.^[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ListTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectLastItemInList() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.$[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ListTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionWithSetAndRegex() {
|
||||
evaluate("testMap.keySet().?[#this matches '.*o.*']", "[monday]", ArrayList.class);
|
||||
evaluate("testMap.keySet().?[#this matches '.*r.*'].contains('saturday')", "true", Boolean.class);
|
||||
evaluate("testMap.keySet().?[#this matches '.*r.*'].size()", "3", Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectionWithSet() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new SetTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(0, 1, 2, 3, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectFirstItemInSet() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.^[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new SetTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectLastItemInSet() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.$[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new SetTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectionWithIterable() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new IterableTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(0, 1, 2, 3, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionWithArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.?[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
Object value = expression.getValue(context);
|
||||
assertThat(value.getClass().isArray()).isTrue();
|
||||
TypedValue typedValue = new TypedValue(value);
|
||||
assertThat(typedValue.getTypeDescriptor().getElementTypeDescriptor().getType()).isEqualTo(Integer.class);
|
||||
assertThat((Integer[]) value).containsExactly(0, 1, 2, 3, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectFirstItemInArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.^[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectLastItemInArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("integers.$[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectionWithPrimitiveArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("ints.?[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
Object value = expression.getValue(context);
|
||||
assertThat(value.getClass().isArray()).isTrue();
|
||||
TypedValue typedValue = new TypedValue(value);
|
||||
assertThat(typedValue.getTypeDescriptor().getElementTypeDescriptor().getType()).isEqualTo(Integer.class);
|
||||
assertThat((Integer[]) value).containsExactly(0, 1, 2, 3, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectFirstItemInPrimitiveArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("ints.^[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectLastItemInPrimitiveArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("ints.$[#this<5]");
|
||||
EvaluationContext context = new StandardEvaluationContext(new ArrayTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(INTEGER).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectionWithMap() {
|
||||
EvaluationContext context = new StandardEvaluationContext(new MapTestBean());
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
Expression exp = parser.parseExpression("colors.?[key.startsWith('b')]");
|
||||
Map<String, String> colorsMap = (Map<String, String>) exp.getValue(context);
|
||||
assertThat(colorsMap).containsOnlyKeys("beige", "blue", "brown");
|
||||
|
||||
exp = parser.parseExpression("colors.?[key.startsWith('X')]");
|
||||
|
||||
colorsMap = (Map<String, String>) exp.getValue(context);
|
||||
assertThat(colorsMap).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectFirstItemInMap() {
|
||||
EvaluationContext context = new StandardEvaluationContext(new MapTestBean());
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
Expression exp = parser.parseExpression("colors.^[key.startsWith('b')]");
|
||||
Map<String, String> colorsMap = (Map<String, String>) exp.getValue(context);
|
||||
assertThat(colorsMap).containsOnlyKeys("beige");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void selectLastItemInMap() {
|
||||
EvaluationContext context = new StandardEvaluationContext(new MapTestBean());
|
||||
ExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
Expression exp = parser.parseExpression("colors.$[key.startsWith('b')]");
|
||||
Map<String, String> colorsMap = (Map<String, String>) exp.getValue(context);
|
||||
assertThat(colorsMap).containsOnlyKeys("brown");
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void projectionWithList() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("#testList.![wrapper.value]");
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("testList", IntegerTestBean.createList());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(5, 6, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
void projectionWithMap() {
|
||||
evaluate("mapOfNumbersUpToTen.![key > 5 ? value : null]",
|
||||
@Test
|
||||
void projectionWithMap() {
|
||||
evaluate("mapOfNumbersUpToTen.![key > 5 ? value : null]",
|
||||
"[null, null, null, null, null, six, seven, eight, nine, ten]", ArrayList.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void projectionWithSet() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("#testList.![wrapper.value]");
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("testList", IntegerTestBean.createSet());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(5, 6, 7);
|
||||
}
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void projectionWithSet() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("#testSet.![wrapper.value]");
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("testSet", IntegerTestBean.createSet());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(5, 6, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
void projectionWithIterable() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("#testList.![wrapper.value]");
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("testList", IntegerTestBean.createIterable());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(5, 6, 7);
|
||||
}
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"#root.![#this * 2]", "![#this * 2]"})
|
||||
void projectionWithIterable(String expressionString) {
|
||||
Expression expression = new SpelExpressionParser().parseRaw(expressionString);
|
||||
EvaluationContext context = new StandardEvaluationContext(new IterableTestBean());
|
||||
assertThat(expression.getValue(context)).asInstanceOf(LIST).containsExactly(2, 4, 6, 8, 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
void projectionWithArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("#testArray.![wrapper.value]");
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("testArray", IntegerTestBean.createArray());
|
||||
Object value = expression.getValue(context);
|
||||
assertThat(value).asInstanceOf(array(Number[].class)).containsExactly(5, 5.9f, 7);
|
||||
}
|
||||
|
||||
@Test
|
||||
void projectionWithArray() {
|
||||
Expression expression = new SpelExpressionParser().parseRaw("#testArray.![wrapper.value]");
|
||||
EvaluationContext context = new StandardEvaluationContext();
|
||||
context.setVariable("testArray", IntegerTestBean.createArray());
|
||||
Object value = expression.getValue(context);
|
||||
assertThat(value.getClass().isArray()).isTrue();
|
||||
TypedValue typedValue = new TypedValue(value);
|
||||
assertThat(typedValue.getTypeDescriptor().getElementTypeDescriptor().getType()).isEqualTo(Number.class);
|
||||
assertThat((Number[]) value).containsExactly(5, 5.9f, 7);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -288,7 +296,7 @@ class SelectionAndProjectionTests extends AbstractExpressionTests {
|
|||
|
||||
private final List<Integer> integers = new ArrayList<>();
|
||||
|
||||
ListTestBean() {
|
||||
{
|
||||
for (int i = 0; i < 10; i++) {
|
||||
integers.add(i);
|
||||
}
|
||||
|
|
@ -304,7 +312,7 @@ class SelectionAndProjectionTests extends AbstractExpressionTests {
|
|||
|
||||
private final Set<Integer> integers = new LinkedHashSet<>();
|
||||
|
||||
SetTestBean() {
|
||||
{
|
||||
for (int i = 0; i < 10; i++) {
|
||||
integers.add(i);
|
||||
}
|
||||
|
|
@ -316,18 +324,13 @@ class SelectionAndProjectionTests extends AbstractExpressionTests {
|
|||
}
|
||||
|
||||
|
||||
static class IterableTestBean {
|
||||
static class IterableTestBean implements Iterable<Integer> {
|
||||
|
||||
private final Set<Integer> integers = new LinkedHashSet<>();
|
||||
private final Collection<Integer> integers = List.of(1, 2, 3, 4, 5);
|
||||
|
||||
IterableTestBean() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
integers.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
public Iterable<Integer> getIntegers() {
|
||||
return integers;
|
||||
@Override
|
||||
public Iterator<Integer> iterator() {
|
||||
return integers.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -338,7 +341,7 @@ class SelectionAndProjectionTests extends AbstractExpressionTests {
|
|||
|
||||
private final Integer[] integers = new Integer[10];
|
||||
|
||||
ArrayTestBean() {
|
||||
{
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ints[i] = i;
|
||||
integers[i] = i;
|
||||
|
|
@ -359,8 +362,7 @@ class SelectionAndProjectionTests extends AbstractExpressionTests {
|
|||
|
||||
private final Map<String, String> colors = new TreeMap<>();
|
||||
|
||||
MapTestBean() {
|
||||
// colors.put("black", "schwarz");
|
||||
{
|
||||
colors.put("red", "rot");
|
||||
colors.put("brown", "braun");
|
||||
colors.put("blue", "blau");
|
||||
|
|
@ -376,13 +378,13 @@ class SelectionAndProjectionTests extends AbstractExpressionTests {
|
|||
|
||||
static class IntegerTestBean {
|
||||
|
||||
private final IntegerWrapper wrapper;
|
||||
private final NumberWrapper wrapper;
|
||||
|
||||
IntegerTestBean(Number value) {
|
||||
this.wrapper = new IntegerWrapper(value);
|
||||
this.wrapper = new NumberWrapper(value);
|
||||
}
|
||||
|
||||
public IntegerWrapper getWrapper() {
|
||||
public NumberWrapper getWrapper() {
|
||||
return this.wrapper;
|
||||
}
|
||||
|
||||
|
|
@ -402,11 +404,6 @@ class SelectionAndProjectionTests extends AbstractExpressionTests {
|
|||
return set;
|
||||
}
|
||||
|
||||
static Iterable<IntegerTestBean> createIterable() {
|
||||
final Set<IntegerTestBean> set = createSet();
|
||||
return set;
|
||||
}
|
||||
|
||||
static IntegerTestBean[] createArray() {
|
||||
IntegerTestBean[] array = new IntegerTestBean[3];
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
|
@ -422,17 +419,7 @@ class SelectionAndProjectionTests extends AbstractExpressionTests {
|
|||
}
|
||||
|
||||
|
||||
static class IntegerWrapper {
|
||||
|
||||
private final Number value;
|
||||
|
||||
IntegerWrapper(Number value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Number getValue() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
record NumberWrapper(Number value) {
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue