Merge branch '5.3.x'

This commit is contained in:
Sam Brannen 2022-01-08 17:07:34 +01:00
commit 86387db045
1 changed files with 48 additions and 49 deletions

View File

@ -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;
} }