Merge branch '5.3.x'
This commit is contained in:
commit
86387db045
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2022 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.
|
||||||
|
|
@ -52,22 +52,22 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
public class PropertyAccessTests extends AbstractExpressionTests {
|
public class PropertyAccessTests extends AbstractExpressionTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleAccess01() {
|
void simpleAccess01() {
|
||||||
evaluate("name", "Nikola Tesla", String.class);
|
evaluate("name", "Nikola Tesla", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleAccess02() {
|
void simpleAccess02() {
|
||||||
evaluate("placeOfBirth.city", "SmilJan", String.class);
|
evaluate("placeOfBirth.city", "SmilJan", String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSimpleAccess03() {
|
void simpleAccess03() {
|
||||||
evaluate("stringArrayOfThreeItems.length", "3", Integer.class);
|
evaluate("stringArrayOfThreeItems.length", "3", Integer.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNonExistentPropertiesAndMethods() {
|
void nonExistentPropertiesAndMethods() {
|
||||||
// madeup does not exist as a property
|
// madeup does not exist as a property
|
||||||
evaluateAndCheckError("madeup", SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE, 0);
|
evaluateAndCheckError("madeup", SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE, 0);
|
||||||
|
|
||||||
|
|
@ -80,21 +80,21 @@ public class PropertyAccessTests extends AbstractExpressionTests {
|
||||||
* supplied resolver might be able to - so null shouldn't crash the reflection resolver.
|
* supplied resolver might be able to - so null shouldn't crash the reflection resolver.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAccessingOnNullObject() {
|
void accessingOnNullObject() {
|
||||||
SpelExpression expr = (SpelExpression) parser.parseExpression("madeup");
|
SpelExpression expr = (SpelExpression) parser.parseExpression("madeup");
|
||||||
EvaluationContext context = new StandardEvaluationContext(null);
|
EvaluationContext context = new StandardEvaluationContext(null);
|
||||||
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() ->
|
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||||
expr.getValue(context))
|
.isThrownBy(() -> expr.getValue(context))
|
||||||
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL));
|
.extracting(SpelEvaluationException::getMessageCode).isEqualTo(SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL);
|
||||||
assertThat(expr.isWritable(context)).isFalse();
|
assertThat(expr.isWritable(context)).isFalse();
|
||||||
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() ->
|
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||||
expr.setValue(context, "abc"))
|
.isThrownBy(() -> expr.setValue(context, "abc"))
|
||||||
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL));
|
.extracting(SpelEvaluationException::getMessageCode).isEqualTo(SpelMessage.PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
// Adding a new property accessor just for a particular type
|
// Adding a new property accessor just for a particular type
|
||||||
public void testAddingSpecificPropertyAccessor() {
|
void addingSpecificPropertyAccessor() {
|
||||||
SpelExpressionParser parser = new SpelExpressionParser();
|
SpelExpressionParser parser = new SpelExpressionParser();
|
||||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||||
|
|
||||||
|
|
@ -125,35 +125,34 @@ public class PropertyAccessTests extends AbstractExpressionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAddingRemovingAccessors() {
|
void addingAndRemovingAccessors() {
|
||||||
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
StandardEvaluationContext ctx = new StandardEvaluationContext();
|
||||||
|
|
||||||
// reflective property accessor is the only one by default
|
// reflective property accessor is the only one by default
|
||||||
List<PropertyAccessor> propertyAccessors = ctx.getPropertyAccessors();
|
assertThat(ctx.getPropertyAccessors()).hasSize(1);
|
||||||
assertThat(propertyAccessors.size()).isEqualTo(1);
|
|
||||||
|
|
||||||
StringyPropertyAccessor spa = new StringyPropertyAccessor();
|
StringyPropertyAccessor spa = new StringyPropertyAccessor();
|
||||||
ctx.addPropertyAccessor(spa);
|
ctx.addPropertyAccessor(spa);
|
||||||
assertThat(ctx.getPropertyAccessors().size()).isEqualTo(2);
|
assertThat(ctx.getPropertyAccessors()).hasSize(2);
|
||||||
|
|
||||||
List<PropertyAccessor> copy = new ArrayList<>(ctx.getPropertyAccessors());
|
List<PropertyAccessor> copy = new ArrayList<>(ctx.getPropertyAccessors());
|
||||||
assertThat(ctx.removePropertyAccessor(spa)).isTrue();
|
assertThat(ctx.removePropertyAccessor(spa)).isTrue();
|
||||||
assertThat(ctx.removePropertyAccessor(spa)).isFalse();
|
assertThat(ctx.removePropertyAccessor(spa)).isFalse();
|
||||||
assertThat(ctx.getPropertyAccessors().size()).isEqualTo(1);
|
assertThat(ctx.getPropertyAccessors()).hasSize(1);
|
||||||
|
|
||||||
ctx.setPropertyAccessors(copy);
|
ctx.setPropertyAccessors(copy);
|
||||||
assertThat(ctx.getPropertyAccessors().size()).isEqualTo(2);
|
assertThat(ctx.getPropertyAccessors()).hasSize(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAccessingPropertyOfClass() {
|
void accessingPropertyOfClass() {
|
||||||
Expression expression = parser.parseExpression("name");
|
Expression expression = parser.parseExpression("name");
|
||||||
Object value = expression.getValue(new StandardEvaluationContext(String.class));
|
Object value = expression.getValue(new StandardEvaluationContext(String.class));
|
||||||
assertThat(value).isEqualTo("java.lang.String");
|
assertThat(value).isEqualTo("java.lang.String");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldAlwaysUsePropertyAccessorFromEvaluationContext() {
|
void shouldAlwaysUsePropertyAccessorFromEvaluationContext() {
|
||||||
SpelExpressionParser parser = new SpelExpressionParser();
|
SpelExpressionParser parser = new SpelExpressionParser();
|
||||||
Expression expression = parser.parseExpression("name");
|
Expression expression = parser.parseExpression("name");
|
||||||
|
|
||||||
|
|
@ -167,19 +166,19 @@ public class PropertyAccessTests extends AbstractExpressionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void standardGetClassAccess() {
|
void standardGetClassAccess() {
|
||||||
assertThat(parser.parseExpression("'a'.class.name").getValue()).isEqualTo(String.class.getName());
|
assertThat(parser.parseExpression("'a'.class.name").getValue()).isEqualTo(String.class.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void noGetClassAccess() {
|
void noGetClassAccess() {
|
||||||
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
|
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
|
||||||
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() ->
|
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() ->
|
||||||
parser.parseExpression("'a'.class.name").getValue(context));
|
parser.parseExpression("'a'.class.name").getValue(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void propertyReadOnly() {
|
void propertyReadOnly() {
|
||||||
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
|
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
|
||||||
|
|
||||||
Expression expr = parser.parseExpression("name");
|
Expression expr = parser.parseExpression("name");
|
||||||
|
|
@ -193,7 +192,7 @@ public class PropertyAccessTests extends AbstractExpressionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void propertyReadOnlyWithRecordStyle() {
|
void propertyReadOnlyWithRecordStyle() {
|
||||||
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
|
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
|
||||||
|
|
||||||
Expression expr = parser.parseExpression("name");
|
Expression expr = parser.parseExpression("name");
|
||||||
|
|
@ -207,7 +206,7 @@ public class PropertyAccessTests extends AbstractExpressionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void propertyReadWrite() {
|
void propertyReadWrite() {
|
||||||
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
|
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
|
||||||
|
|
||||||
Expression expr = parser.parseExpression("name");
|
Expression expr = parser.parseExpression("name");
|
||||||
|
|
@ -226,27 +225,27 @@ public class PropertyAccessTests extends AbstractExpressionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void propertyReadWriteWithRootObject() {
|
void propertyReadWriteWithRootObject() {
|
||||||
Person target = new Person("p1");
|
Person rootObject = new Person("p1");
|
||||||
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().withRootObject(target).build();
|
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().withRootObject(rootObject).build();
|
||||||
assertThat(context.getRootObject().getValue()).isSameAs(target);
|
assertThat(context.getRootObject().getValue()).isSameAs(rootObject);
|
||||||
|
|
||||||
Expression expr = parser.parseExpression("name");
|
Expression expr = parser.parseExpression("name");
|
||||||
assertThat(expr.getValue(context, target)).isEqualTo("p1");
|
assertThat(expr.getValue(context)).isEqualTo("p1");
|
||||||
target.setName("p2");
|
rootObject.setName("p2");
|
||||||
assertThat(expr.getValue(context, target)).isEqualTo("p2");
|
assertThat(expr.getValue(context)).isEqualTo("p2");
|
||||||
|
|
||||||
parser.parseExpression("name='p3'").getValue(context, target);
|
parser.parseExpression("name='p3'").getValue(context, rootObject);
|
||||||
assertThat(target.getName()).isEqualTo("p3");
|
assertThat(rootObject.getName()).isEqualTo("p3");
|
||||||
assertThat(expr.getValue(context, target)).isEqualTo("p3");
|
assertThat(expr.getValue(context)).isEqualTo("p3");
|
||||||
|
|
||||||
expr.setValue(context, target, "p4");
|
expr.setValue(context, "p4");
|
||||||
assertThat(target.getName()).isEqualTo("p4");
|
assertThat(rootObject.getName()).isEqualTo("p4");
|
||||||
assertThat(expr.getValue(context, target)).isEqualTo("p4");
|
assertThat(expr.getValue(context)).isEqualTo("p4");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void propertyAccessWithoutMethodResolver() {
|
void propertyAccessWithoutMethodResolver() {
|
||||||
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
|
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
|
||||||
Person target = new Person("p1");
|
Person target = new Person("p1");
|
||||||
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() ->
|
assertThatExceptionOfType(SpelEvaluationException.class).isThrownBy(() ->
|
||||||
|
|
@ -254,20 +253,20 @@ public class PropertyAccessTests extends AbstractExpressionTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void propertyAccessWithInstanceMethodResolver() {
|
void propertyAccessWithInstanceMethodResolver() {
|
||||||
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().withInstanceMethods().build();
|
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().withInstanceMethods().build();
|
||||||
Person target = new Person("p1");
|
Person target = new Person("p1");
|
||||||
assertThat(parser.parseExpression("name.substring(1)").getValue(context, target)).isEqualTo("1");
|
assertThat(parser.parseExpression("name.substring(1)").getValue(context, target)).isEqualTo("1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void propertyAccessWithInstanceMethodResolverAndTypedRootObject() {
|
void propertyAccessWithInstanceMethodResolverAndTypedRootObject() {
|
||||||
Person target = new Person("p1");
|
Person rootObject = new Person("p1");
|
||||||
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().
|
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().
|
||||||
withInstanceMethods().withTypedRootObject(target, TypeDescriptor.valueOf(Object.class)).build();
|
withInstanceMethods().withTypedRootObject(rootObject, TypeDescriptor.valueOf(Object.class)).build();
|
||||||
|
|
||||||
assertThat(parser.parseExpression("name.substring(1)").getValue(context, target)).isEqualTo("1");
|
assertThat(parser.parseExpression("name.substring(1)").getValue(context)).isEqualTo("1");
|
||||||
assertThat(context.getRootObject().getValue()).isSameAs(target);
|
assertThat(context.getRootObject().getValue()).isSameAs(rootObject);
|
||||||
assertThat(context.getRootObject().getTypeDescriptor().getType()).isSameAs(Object.class);
|
assertThat(context.getRootObject().getTypeDescriptor().getType()).isSameAs(Object.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,7 +276,7 @@ public class PropertyAccessTests extends AbstractExpressionTests {
|
||||||
Expression expression = parser.parseExpression("stringArrayOfThreeItems[3]");
|
Expression expression = parser.parseExpression("stringArrayOfThreeItems[3]");
|
||||||
assertThatExceptionOfType(SpelEvaluationException.class)
|
assertThatExceptionOfType(SpelEvaluationException.class)
|
||||||
.isThrownBy(() -> expression.getValue(context, new Inventor()))
|
.isThrownBy(() -> expression.getValue(context, new Inventor()))
|
||||||
.satisfies(ex -> assertThat(ex.getMessageCode()).isEqualTo(SpelMessage.ARRAY_INDEX_OUT_OF_BOUNDS));
|
.extracting(SpelEvaluationException::getMessageCode).isEqualTo(SpelMessage.ARRAY_INDEX_OUT_OF_BOUNDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -335,7 +334,7 @@ public class PropertyAccessTests extends AbstractExpressionTests {
|
||||||
|
|
||||||
private final Map<String, Object> values;
|
private final Map<String, Object> values;
|
||||||
|
|
||||||
public ConfigurablePropertyAccessor(Map<String, Object> values) {
|
ConfigurablePropertyAccessor(Map<String, Object> values) {
|
||||||
this.values = values;
|
this.values = values;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue