Test status quo for canRead() and read() in SpEL MapAccessor
See gh-35534
This commit is contained in:
parent
20aac6dd8d
commit
27b2243b43
|
@ -22,71 +22,108 @@ import java.util.Map;
|
|||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.spel.standard.SpelCompiler;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Tests for {@link MapAccessor}.
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Sam Brannen
|
||||
*/
|
||||
class MapAccessorTests {
|
||||
|
||||
private final StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
|
||||
|
||||
@Test
|
||||
void compilationSupport() {
|
||||
Map<String, Object> testMap = getSimpleTestMap();
|
||||
StandardEvaluationContext sec = new StandardEvaluationContext();
|
||||
sec.addPropertyAccessor(new MapAccessor());
|
||||
SpelExpressionParser sep = new SpelExpressionParser();
|
||||
context.addPropertyAccessor(new MapAccessor());
|
||||
|
||||
var parser = new SpelExpressionParser();
|
||||
var testMap = getSimpleTestMap();
|
||||
var nestedMap = getNestedTestMap();
|
||||
|
||||
// basic
|
||||
Expression ex = sep.parseExpression("foo");
|
||||
assertThat(ex.getValue(sec, testMap)).isEqualTo("bar");
|
||||
assertThat(SpelCompiler.compile(ex)).isTrue();
|
||||
assertThat(ex.getValue(sec, testMap)).isEqualTo("bar");
|
||||
var expression = parser.parseExpression("foo");
|
||||
assertThat(expression.getValue(context, testMap)).isEqualTo("bar");
|
||||
assertThat(SpelCompiler.compile(expression)).isTrue();
|
||||
assertThat(expression.getValue(context, testMap)).isEqualTo("bar");
|
||||
|
||||
// compound expression
|
||||
ex = sep.parseExpression("foo.toUpperCase()");
|
||||
assertThat(ex.getValue(sec, testMap)).isEqualTo("BAR");
|
||||
assertThat(SpelCompiler.compile(ex)).isTrue();
|
||||
assertThat(ex.getValue(sec, testMap)).isEqualTo("BAR");
|
||||
expression = parser.parseExpression("foo.toUpperCase()");
|
||||
assertThat(expression.getValue(context, testMap)).isEqualTo("BAR");
|
||||
assertThat(SpelCompiler.compile(expression)).isTrue();
|
||||
assertThat(expression.getValue(context, testMap)).isEqualTo("BAR");
|
||||
|
||||
// nested map
|
||||
Map<String, Map<String, Object>> nestedMap = getNestedTestMap();
|
||||
ex = sep.parseExpression("aaa.foo.toUpperCase()");
|
||||
assertThat(ex.getValue(sec, nestedMap)).isEqualTo("BAR");
|
||||
assertThat(SpelCompiler.compile(ex)).isTrue();
|
||||
assertThat(ex.getValue(sec, nestedMap)).isEqualTo("BAR");
|
||||
expression = parser.parseExpression("aaa.foo.toUpperCase()");
|
||||
assertThat(expression.getValue(context, nestedMap)).isEqualTo("BAR");
|
||||
assertThat(SpelCompiler.compile(expression)).isTrue();
|
||||
assertThat(expression.getValue(context, nestedMap)).isEqualTo("BAR");
|
||||
|
||||
// avoiding inserting checkcast because first part of expression returns a Map
|
||||
ex = sep.parseExpression("getMap().foo");
|
||||
expression = parser.parseExpression("getMap().foo");
|
||||
MapGetter mapGetter = new MapGetter();
|
||||
assertThat(ex.getValue(sec, mapGetter)).isEqualTo("bar");
|
||||
assertThat(SpelCompiler.compile(ex)).isTrue();
|
||||
assertThat(ex.getValue(sec, mapGetter)).isEqualTo("bar");
|
||||
assertThat(expression.getValue(context, mapGetter)).isEqualTo("bar");
|
||||
assertThat(SpelCompiler.compile(expression)).isTrue();
|
||||
assertThat(expression.getValue(context, mapGetter)).isEqualTo("bar");
|
||||
|
||||
// basic isWritable
|
||||
ex = sep.parseExpression("foo");
|
||||
assertThat(ex.isWritable(sec, testMap)).isTrue();
|
||||
expression = parser.parseExpression("foo");
|
||||
assertThat(expression.isWritable(context, testMap)).isTrue();
|
||||
|
||||
// basic write
|
||||
ex = sep.parseExpression("foo2");
|
||||
ex.setValue(sec, testMap, "bar2");
|
||||
assertThat(ex.getValue(sec, testMap)).isEqualTo("bar2");
|
||||
assertThat(SpelCompiler.compile(ex)).isTrue();
|
||||
assertThat(ex.getValue(sec, testMap)).isEqualTo("bar2");
|
||||
expression = parser.parseExpression("foo2");
|
||||
expression.setValue(context, testMap, "bar2");
|
||||
assertThat(expression.getValue(context, testMap)).isEqualTo("bar2");
|
||||
assertThat(SpelCompiler.compile(expression)).isTrue();
|
||||
assertThat(expression.getValue(context, testMap)).isEqualTo("bar2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void canWrite() throws Exception {
|
||||
StandardEvaluationContext context = new StandardEvaluationContext();
|
||||
Map<String, Object> testMap = getSimpleTestMap();
|
||||
void canReadForNonMap() throws AccessException {
|
||||
var mapAccessor = new MapAccessor();
|
||||
|
||||
assertThat(mapAccessor.canRead(context, new Object(), "foo")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void canReadAndReadForExistingKeys() throws AccessException {
|
||||
var mapAccessor = new MapAccessor();
|
||||
var map = new HashMap<>();
|
||||
map.put("foo", null);
|
||||
map.put("bar", "baz");
|
||||
|
||||
assertThat(mapAccessor.canRead(context, map, "foo")).isTrue();
|
||||
assertThat(mapAccessor.canRead(context, map, "bar")).isTrue();
|
||||
|
||||
assertThat(mapAccessor.read(context, map, "foo").getValue()).isNull();
|
||||
assertThat(mapAccessor.read(context, map, "bar").getValue()).isEqualTo("baz");
|
||||
}
|
||||
|
||||
@Test
|
||||
void canReadAndReadForNonexistentKeys() throws AccessException {
|
||||
var mapAccessor = new MapAccessor();
|
||||
var map = Map.of();
|
||||
|
||||
assertThat(mapAccessor.canRead(context, map, "XXX")).isFalse();
|
||||
|
||||
assertThatExceptionOfType(AccessException.class)
|
||||
.isThrownBy(() -> mapAccessor.read(context, map, "XXX").getValue())
|
||||
.withMessage("Map does not contain a value for key 'XXX'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void canWrite() throws AccessException {
|
||||
var mapAccessor = new MapAccessor();
|
||||
var testMap = getSimpleTestMap();
|
||||
|
||||
MapAccessor mapAccessor = new MapAccessor();
|
||||
assertThat(mapAccessor.canWrite(context, new Object(), "foo")).isFalse();
|
||||
assertThat(mapAccessor.canWrite(context, testMap, "foo")).isTrue();
|
||||
// Cannot actually write to an immutable Map, but MapAccessor cannot easily check for that.
|
||||
|
@ -99,18 +136,17 @@ class MapAccessorTests {
|
|||
|
||||
@Test
|
||||
void isWritable() {
|
||||
Map<String, Object> testMap = getSimpleTestMap();
|
||||
StandardEvaluationContext sec = new StandardEvaluationContext();
|
||||
SpelExpressionParser sep = new SpelExpressionParser();
|
||||
Expression ex = sep.parseExpression("foo");
|
||||
var testMap = getSimpleTestMap();
|
||||
var parser = new SpelExpressionParser();
|
||||
var expression = parser.parseExpression("foo");
|
||||
|
||||
assertThat(ex.isWritable(sec, testMap)).isFalse();
|
||||
assertThat(expression.isWritable(context, testMap)).isFalse();
|
||||
|
||||
sec.setPropertyAccessors(List.of(new MapAccessor(true)));
|
||||
assertThat(ex.isWritable(sec, testMap)).isTrue();
|
||||
context.setPropertyAccessors(List.of(new MapAccessor(true)));
|
||||
assertThat(expression.isWritable(context, testMap)).isTrue();
|
||||
|
||||
sec.setPropertyAccessors(List.of(new MapAccessor(false)));
|
||||
assertThat(ex.isWritable(sec, testMap)).isFalse();
|
||||
context.setPropertyAccessors(List.of(new MapAccessor(false)));
|
||||
assertThat(expression.isWritable(context, testMap)).isFalse();
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,16 +163,16 @@ class MapAccessorTests {
|
|||
}
|
||||
}
|
||||
|
||||
private static Map<String,Object> getSimpleTestMap() {
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
map.put("foo","bar");
|
||||
private static Map<String, Object> getSimpleTestMap() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("foo", "bar");
|
||||
return map;
|
||||
}
|
||||
|
||||
private static Map<String,Map<String,Object>> getNestedTestMap() {
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
map.put("foo","bar");
|
||||
Map<String,Map<String,Object>> map2 = new HashMap<>();
|
||||
private static Map<String, Map<String, Object>> getNestedTestMap() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("foo", "bar");
|
||||
Map<String, Map<String, Object>> map2 = new HashMap<>();
|
||||
map2.put("aaa", map);
|
||||
return map2;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue