|
|
|
|
@@ -1,5 +1,5 @@
|
|
|
|
|
/*
|
|
|
|
|
* Copyright 2002-2016 the original author or authors.
|
|
|
|
|
* Copyright 2002-2018 the original author or authors.
|
|
|
|
|
*
|
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
|
@@ -16,7 +16,6 @@
|
|
|
|
|
|
|
|
|
|
package org.springframework.expression.spel;
|
|
|
|
|
|
|
|
|
|
import java.util.EmptyStackException;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
|
|
@@ -36,6 +35,7 @@ import static org.junit.Assert.*;
|
|
|
|
|
* Tests for the expression state object - some features are not yet exploited in the language (eg nested scopes)
|
|
|
|
|
*
|
|
|
|
|
* @author Andy Clement
|
|
|
|
|
* @author Juergen Hoeller
|
|
|
|
|
*/
|
|
|
|
|
public class ExpressionStateTests extends AbstractExpressionTests {
|
|
|
|
|
|
|
|
|
|
@@ -43,7 +43,7 @@ public class ExpressionStateTests extends AbstractExpressionTests {
|
|
|
|
|
public void testConstruction() {
|
|
|
|
|
EvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
|
|
|
|
|
ExpressionState state = new ExpressionState(context);
|
|
|
|
|
assertEquals(context,state.getEvaluationContext());
|
|
|
|
|
assertEquals(context, state.getEvaluationContext());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Local variables are in variable scopes which come and go during evaluation. Normal variables are
|
|
|
|
|
@@ -58,107 +58,107 @@ public class ExpressionStateTests extends AbstractExpressionTests {
|
|
|
|
|
|
|
|
|
|
state.setLocalVariable("foo",34);
|
|
|
|
|
value = state.lookupLocalVariable("foo");
|
|
|
|
|
assertEquals(34,value);
|
|
|
|
|
assertEquals(34, value);
|
|
|
|
|
|
|
|
|
|
state.setLocalVariable("foo",null);
|
|
|
|
|
state.setLocalVariable("foo", null);
|
|
|
|
|
value = state.lookupLocalVariable("foo");
|
|
|
|
|
assertEquals(null,value);
|
|
|
|
|
assertEquals(null, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testVariables() {
|
|
|
|
|
ExpressionState state = getState();
|
|
|
|
|
TypedValue typedValue = state.lookupVariable("foo");
|
|
|
|
|
assertEquals(TypedValue.NULL,typedValue);
|
|
|
|
|
assertEquals(TypedValue.NULL, typedValue);
|
|
|
|
|
|
|
|
|
|
state.setVariable("foo",34);
|
|
|
|
|
typedValue = state.lookupVariable("foo");
|
|
|
|
|
assertEquals(34,typedValue.getValue());
|
|
|
|
|
assertEquals(Integer.class,typedValue.getTypeDescriptor().getType());
|
|
|
|
|
assertEquals(34, typedValue.getValue());
|
|
|
|
|
assertEquals(Integer.class, typedValue.getTypeDescriptor().getType());
|
|
|
|
|
|
|
|
|
|
state.setVariable("foo","abc");
|
|
|
|
|
typedValue = state.lookupVariable("foo");
|
|
|
|
|
assertEquals("abc",typedValue.getValue());
|
|
|
|
|
assertEquals(String.class,typedValue.getTypeDescriptor().getType());
|
|
|
|
|
assertEquals("abc", typedValue.getValue());
|
|
|
|
|
assertEquals(String.class, typedValue.getTypeDescriptor().getType());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testNoVariableInteference() {
|
|
|
|
|
ExpressionState state = getState();
|
|
|
|
|
TypedValue typedValue = state.lookupVariable("foo");
|
|
|
|
|
assertEquals(TypedValue.NULL,typedValue);
|
|
|
|
|
assertEquals(TypedValue.NULL, typedValue);
|
|
|
|
|
|
|
|
|
|
state.setLocalVariable("foo",34);
|
|
|
|
|
typedValue = state.lookupVariable("foo");
|
|
|
|
|
assertEquals(TypedValue.NULL,typedValue);
|
|
|
|
|
assertEquals(TypedValue.NULL, typedValue);
|
|
|
|
|
|
|
|
|
|
state.setVariable("goo","hello");
|
|
|
|
|
state.setVariable("goo", "hello");
|
|
|
|
|
assertNull(state.lookupLocalVariable("goo"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testLocalVariableNestedScopes() {
|
|
|
|
|
ExpressionState state = getState();
|
|
|
|
|
assertEquals(null,state.lookupLocalVariable("foo"));
|
|
|
|
|
assertEquals(null, state.lookupLocalVariable("foo"));
|
|
|
|
|
|
|
|
|
|
state.setLocalVariable("foo",12);
|
|
|
|
|
assertEquals(12,state.lookupLocalVariable("foo"));
|
|
|
|
|
assertEquals(12, state.lookupLocalVariable("foo"));
|
|
|
|
|
|
|
|
|
|
state.enterScope(null);
|
|
|
|
|
assertEquals(12,state.lookupLocalVariable("foo")); // found in upper scope
|
|
|
|
|
assertEquals(12, state.lookupLocalVariable("foo")); // found in upper scope
|
|
|
|
|
|
|
|
|
|
state.setLocalVariable("foo","abc");
|
|
|
|
|
assertEquals("abc",state.lookupLocalVariable("foo")); // found in nested scope
|
|
|
|
|
assertEquals("abc", state.lookupLocalVariable("foo")); // found in nested scope
|
|
|
|
|
|
|
|
|
|
state.exitScope();
|
|
|
|
|
assertEquals(12,state.lookupLocalVariable("foo")); // found in nested scope
|
|
|
|
|
assertEquals(12, state.lookupLocalVariable("foo")); // found in nested scope
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testRootContextObject() {
|
|
|
|
|
ExpressionState state = getState();
|
|
|
|
|
assertEquals(Inventor.class,state.getRootContextObject().getValue().getClass());
|
|
|
|
|
assertEquals(Inventor.class, state.getRootContextObject().getValue().getClass());
|
|
|
|
|
|
|
|
|
|
// although the root object is being set on the evaluation context, the value in the 'state' remains what it was when constructed
|
|
|
|
|
((StandardEvaluationContext) state.getEvaluationContext()).setRootObject(null);
|
|
|
|
|
assertEquals(Inventor.class,state.getRootContextObject().getValue().getClass());
|
|
|
|
|
assertEquals(Inventor.class, state.getRootContextObject().getValue().getClass());
|
|
|
|
|
// assertEquals(null, state.getRootContextObject().getValue());
|
|
|
|
|
|
|
|
|
|
state = new ExpressionState(new StandardEvaluationContext());
|
|
|
|
|
assertEquals(TypedValue.NULL,state.getRootContextObject());
|
|
|
|
|
assertEquals(TypedValue.NULL, state.getRootContextObject());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
((StandardEvaluationContext)state.getEvaluationContext()).setRootObject(null);
|
|
|
|
|
assertEquals(null,state.getRootContextObject().getValue());
|
|
|
|
|
((StandardEvaluationContext) state.getEvaluationContext()).setRootObject(null);
|
|
|
|
|
assertEquals(null, state.getRootContextObject().getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testActiveContextObject() {
|
|
|
|
|
ExpressionState state = getState();
|
|
|
|
|
assertEquals(state.getRootContextObject().getValue(),state.getActiveContextObject().getValue());
|
|
|
|
|
assertEquals(state.getRootContextObject().getValue(), state.getActiveContextObject().getValue());
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
state.popActiveContextObject();
|
|
|
|
|
fail("stack should be empty...");
|
|
|
|
|
}
|
|
|
|
|
catch (EmptyStackException ese) {
|
|
|
|
|
catch (IllegalStateException ese) {
|
|
|
|
|
// success
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state.pushActiveContextObject(new TypedValue(34));
|
|
|
|
|
assertEquals(34,state.getActiveContextObject().getValue());
|
|
|
|
|
assertEquals(34, state.getActiveContextObject().getValue());
|
|
|
|
|
|
|
|
|
|
state.pushActiveContextObject(new TypedValue("hello"));
|
|
|
|
|
assertEquals("hello",state.getActiveContextObject().getValue());
|
|
|
|
|
assertEquals("hello", state.getActiveContextObject().getValue());
|
|
|
|
|
|
|
|
|
|
state.popActiveContextObject();
|
|
|
|
|
assertEquals(34,state.getActiveContextObject().getValue());
|
|
|
|
|
assertEquals(34, state.getActiveContextObject().getValue());
|
|
|
|
|
|
|
|
|
|
state.popActiveContextObject();
|
|
|
|
|
assertEquals(state.getRootContextObject().getValue(),state.getActiveContextObject().getValue());
|
|
|
|
|
assertEquals(state.getRootContextObject().getValue(), state.getActiveContextObject().getValue());
|
|
|
|
|
|
|
|
|
|
state = new ExpressionState(new StandardEvaluationContext());
|
|
|
|
|
assertEquals(TypedValue.NULL,state.getActiveContextObject());
|
|
|
|
|
assertEquals(TypedValue.NULL, state.getActiveContextObject());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -167,14 +167,14 @@ public class ExpressionStateTests extends AbstractExpressionTests {
|
|
|
|
|
assertNull(state.lookupLocalVariable("foo"));
|
|
|
|
|
|
|
|
|
|
state.enterScope("foo",34);
|
|
|
|
|
assertEquals(34,state.lookupLocalVariable("foo"));
|
|
|
|
|
assertEquals(34, state.lookupLocalVariable("foo"));
|
|
|
|
|
|
|
|
|
|
state.enterScope(null);
|
|
|
|
|
state.setLocalVariable("foo",12);
|
|
|
|
|
assertEquals(12,state.lookupLocalVariable("foo"));
|
|
|
|
|
state.setLocalVariable("foo", 12);
|
|
|
|
|
assertEquals(12, state.lookupLocalVariable("foo"));
|
|
|
|
|
|
|
|
|
|
state.exitScope();
|
|
|
|
|
assertEquals(34,state.lookupLocalVariable("foo"));
|
|
|
|
|
assertEquals(34, state.lookupLocalVariable("foo"));
|
|
|
|
|
|
|
|
|
|
state.exitScope();
|
|
|
|
|
assertNull(state.lookupLocalVariable("goo"));
|
|
|
|
|
@@ -187,8 +187,8 @@ public class ExpressionStateTests extends AbstractExpressionTests {
|
|
|
|
|
// supplied should override root on context
|
|
|
|
|
ExpressionState state = new ExpressionState(ctx,new TypedValue("i am a string"));
|
|
|
|
|
TypedValue stateRoot = state.getRootContextObject();
|
|
|
|
|
assertEquals(String.class,stateRoot.getTypeDescriptor().getType());
|
|
|
|
|
assertEquals("i am a string",stateRoot.getValue());
|
|
|
|
|
assertEquals(String.class, stateRoot.getTypeDescriptor().getType());
|
|
|
|
|
assertEquals("i am a string", stateRoot.getValue());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
@@ -198,17 +198,17 @@ public class ExpressionStateTests extends AbstractExpressionTests {
|
|
|
|
|
assertNull(state.lookupLocalVariable("goo"));
|
|
|
|
|
|
|
|
|
|
Map<String,Object> m = new HashMap<>();
|
|
|
|
|
m.put("foo",34);
|
|
|
|
|
m.put("goo","abc");
|
|
|
|
|
m.put("foo", 34);
|
|
|
|
|
m.put("goo", "abc");
|
|
|
|
|
|
|
|
|
|
state.enterScope(m);
|
|
|
|
|
assertEquals(34,state.lookupLocalVariable("foo"));
|
|
|
|
|
assertEquals("abc",state.lookupLocalVariable("goo"));
|
|
|
|
|
assertEquals(34, state.lookupLocalVariable("foo"));
|
|
|
|
|
assertEquals("abc", state.lookupLocalVariable("goo"));
|
|
|
|
|
|
|
|
|
|
state.enterScope(null);
|
|
|
|
|
state.setLocalVariable("foo",12);
|
|
|
|
|
assertEquals(12,state.lookupLocalVariable("foo"));
|
|
|
|
|
assertEquals("abc",state.lookupLocalVariable("goo"));
|
|
|
|
|
assertEquals(12, state.lookupLocalVariable("foo"));
|
|
|
|
|
assertEquals("abc", state.lookupLocalVariable("goo"));
|
|
|
|
|
|
|
|
|
|
state.exitScope();
|
|
|
|
|
state.exitScope();
|
|
|
|
|
@@ -217,7 +217,7 @@ public class ExpressionStateTests extends AbstractExpressionTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testOperators() throws Exception {
|
|
|
|
|
public void testOperators() {
|
|
|
|
|
ExpressionState state = getState();
|
|
|
|
|
try {
|
|
|
|
|
state.operate(Operation.ADD,1,2);
|
|
|
|
|
@@ -225,7 +225,7 @@ public class ExpressionStateTests extends AbstractExpressionTests {
|
|
|
|
|
}
|
|
|
|
|
catch (EvaluationException ee) {
|
|
|
|
|
SpelEvaluationException sEx = (SpelEvaluationException)ee;
|
|
|
|
|
assertEquals(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES,sEx.getMessageCode());
|
|
|
|
|
assertEquals(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES, sEx.getMessageCode());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
@@ -234,28 +234,28 @@ public class ExpressionStateTests extends AbstractExpressionTests {
|
|
|
|
|
}
|
|
|
|
|
catch (EvaluationException ee) {
|
|
|
|
|
SpelEvaluationException sEx = (SpelEvaluationException)ee;
|
|
|
|
|
assertEquals(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES,sEx.getMessageCode());
|
|
|
|
|
assertEquals(SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES, sEx.getMessageCode());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testComparator() {
|
|
|
|
|
ExpressionState state = getState();
|
|
|
|
|
assertEquals(state.getEvaluationContext().getTypeComparator(),state.getTypeComparator());
|
|
|
|
|
assertEquals(state.getEvaluationContext().getTypeComparator(), state.getTypeComparator());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testTypeLocator() throws EvaluationException {
|
|
|
|
|
ExpressionState state = getState();
|
|
|
|
|
assertNotNull(state.getEvaluationContext().getTypeLocator());
|
|
|
|
|
assertEquals(Integer.class,state.findType("java.lang.Integer"));
|
|
|
|
|
assertEquals(Integer.class, state.findType("java.lang.Integer"));
|
|
|
|
|
try {
|
|
|
|
|
state.findType("someMadeUpName");
|
|
|
|
|
fail("Should have failed to find it");
|
|
|
|
|
}
|
|
|
|
|
catch (EvaluationException ee) {
|
|
|
|
|
SpelEvaluationException sEx = (SpelEvaluationException)ee;
|
|
|
|
|
assertEquals(SpelMessage.TYPE_NOT_FOUND,sEx.getMessageCode());
|
|
|
|
|
assertEquals(SpelMessage.TYPE_NOT_FOUND, sEx.getMessageCode());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -263,16 +263,16 @@ public class ExpressionStateTests extends AbstractExpressionTests {
|
|
|
|
|
public void testTypeConversion() throws EvaluationException {
|
|
|
|
|
ExpressionState state = getState();
|
|
|
|
|
String s = (String) state.convertValue(34, TypeDescriptor.valueOf(String.class));
|
|
|
|
|
assertEquals("34",s);
|
|
|
|
|
assertEquals("34", s);
|
|
|
|
|
|
|
|
|
|
s = (String)state.convertValue(new TypedValue(34), TypeDescriptor.valueOf(String.class));
|
|
|
|
|
assertEquals("34",s);
|
|
|
|
|
assertEquals("34", s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testPropertyAccessors() {
|
|
|
|
|
ExpressionState state = getState();
|
|
|
|
|
assertEquals(state.getEvaluationContext().getPropertyAccessors(),state.getPropertyAccessors());
|
|
|
|
|
assertEquals(state.getEvaluationContext().getPropertyAccessors(), state.getPropertyAccessors());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|