SPR-6230: SpEL improvements
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.EmptyStackException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -117,8 +118,10 @@ public class ExpressionStateTests extends ExpressionTestCase {
|
||||
ExpressionState state = getState();
|
||||
Assert.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);
|
||||
Assert.assertEquals(null, state.getRootContextObject().getValue());
|
||||
Assert.assertEquals(Inventor.class,state.getRootContextObject().getValue().getClass());
|
||||
// Assert.assertEquals(null, state.getRootContextObject().getValue());
|
||||
|
||||
state = new ExpressionState(new StandardEvaluationContext());
|
||||
Assert.assertEquals(TypedValue.NULL_TYPED_VALUE,state.getRootContextObject());
|
||||
@@ -133,6 +136,13 @@ public class ExpressionStateTests extends ExpressionTestCase {
|
||||
ExpressionState state = getState();
|
||||
Assert.assertEquals(state.getRootContextObject().getValue(),state.getActiveContextObject().getValue());
|
||||
|
||||
try {
|
||||
state.popActiveContextObject();
|
||||
Assert.fail("stack should be empty...");
|
||||
} catch (EmptyStackException ese) {
|
||||
// success
|
||||
}
|
||||
|
||||
state.pushActiveContextObject(new TypedValue(34));
|
||||
Assert.assertEquals(34,state.getActiveContextObject().getValue());
|
||||
|
||||
@@ -168,6 +178,17 @@ public class ExpressionStateTests extends ExpressionTestCase {
|
||||
Assert.assertNull(state.lookupLocalVariable("goo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRootObjectConstructor() {
|
||||
EvaluationContext ctx = getContext();
|
||||
// TypedValue root = ctx.getRootObject();
|
||||
// supplied should override root on context
|
||||
ExpressionState state = new ExpressionState(ctx,new TypedValue("i am a string"));
|
||||
TypedValue stateRoot = state.getRootContextObject();
|
||||
Assert.assertEquals(String.class,stateRoot.getTypeDescriptor().getType());
|
||||
Assert.assertEquals("i am a string",stateRoot.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPopulatedNestedScopesMap() {
|
||||
ExpressionState state = getState();
|
||||
@@ -257,5 +278,9 @@ public class ExpressionStateTests extends ExpressionTestCase {
|
||||
ExpressionState state = new ExpressionState(context);
|
||||
return state;
|
||||
}
|
||||
|
||||
private EvaluationContext getContext() {
|
||||
return TestScenarioCreator.getTestEvaluationContext();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.junit.Test;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.PropertyAccessor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.ast.FormatHelper;
|
||||
import org.springframework.expression.spel.support.ReflectionHelper;
|
||||
@@ -307,6 +308,82 @@ public class HelperTests extends ExpressionTestCase {
|
||||
// Assert.assertEquals(0,rpr.read(ctx,t,"field3").getValue());
|
||||
Assert.assertEquals(false,rpr.read(ctx,t,"property4").getValue());
|
||||
Assert.assertTrue(rpr.canRead(ctx,t,"property4"));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptimalReflectivePropertyResolver() throws Exception {
|
||||
ReflectivePropertyResolver rpr = new ReflectivePropertyResolver();
|
||||
Tester t = new Tester();
|
||||
t.setProperty("hello");
|
||||
EvaluationContext ctx = new StandardEvaluationContext(t);
|
||||
// Assert.assertTrue(rpr.canRead(ctx, t, "property"));
|
||||
// Assert.assertEquals("hello",rpr.read(ctx, t, "property").getValue());
|
||||
// Assert.assertEquals("hello",rpr.read(ctx, t, "property").getValue()); // cached accessor used
|
||||
|
||||
PropertyAccessor optA = rpr.createOptimalAccessor(ctx, t, "property");
|
||||
Assert.assertTrue(optA.canRead(ctx, t, "property"));
|
||||
Assert.assertFalse(optA.canRead(ctx, t, "property2"));
|
||||
try {
|
||||
optA.canWrite(ctx, t, "property");
|
||||
Assert.fail();
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
// success
|
||||
}
|
||||
try {
|
||||
optA.canWrite(ctx, t, "property2");
|
||||
Assert.fail();
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
// success
|
||||
}
|
||||
Assert.assertEquals("hello",optA.read(ctx, t, "property").getValue());
|
||||
Assert.assertEquals("hello",optA.read(ctx, t, "property").getValue()); // cached accessor used
|
||||
|
||||
try {
|
||||
optA.getSpecificTargetClasses();
|
||||
Assert.fail();
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
// success
|
||||
}
|
||||
try {
|
||||
optA.write(ctx,t,"property",null);
|
||||
Assert.fail();
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
// success
|
||||
}
|
||||
|
||||
optA = rpr.createOptimalAccessor(ctx, t, "field");
|
||||
Assert.assertTrue(optA.canRead(ctx, t, "field"));
|
||||
Assert.assertFalse(optA.canRead(ctx, t, "field2"));
|
||||
try {
|
||||
optA.canWrite(ctx, t, "field");
|
||||
Assert.fail();
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
// success
|
||||
}
|
||||
try {
|
||||
optA.canWrite(ctx, t, "field2");
|
||||
Assert.fail();
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
// success
|
||||
}
|
||||
Assert.assertEquals(3,optA.read(ctx, t, "field").getValue());
|
||||
Assert.assertEquals(3,optA.read(ctx, t, "field").getValue()); // cached accessor used
|
||||
|
||||
try {
|
||||
optA.getSpecificTargetClasses();
|
||||
Assert.fail();
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
// success
|
||||
}
|
||||
try {
|
||||
optA.write(ctx,t,"field",null);
|
||||
Assert.fail();
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
// success
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,9 +37,17 @@ public class LiteralExpressionTests {
|
||||
EvaluationContext ctx = new StandardEvaluationContext();
|
||||
checkString("somevalue", lEx.getValue(ctx));
|
||||
checkString("somevalue", lEx.getValue(ctx, String.class));
|
||||
checkString("somevalue", lEx.getValue(new Rooty()));
|
||||
checkString("somevalue", lEx.getValue(new Rooty(), String.class));
|
||||
checkString("somevalue", lEx.getValue(ctx, new Rooty()));
|
||||
checkString("somevalue", lEx.getValue(ctx, new Rooty(),String.class));
|
||||
Assert.assertEquals("somevalue", lEx.getExpressionString());
|
||||
Assert.assertFalse(lEx.isWritable(new StandardEvaluationContext()));
|
||||
Assert.assertFalse(lEx.isWritable(new Rooty()));
|
||||
Assert.assertFalse(lEx.isWritable(new StandardEvaluationContext(), new Rooty()));
|
||||
}
|
||||
|
||||
static class Rooty {}
|
||||
|
||||
@Test
|
||||
public void testSetValue() {
|
||||
@@ -52,6 +60,24 @@ public class LiteralExpressionTests {
|
||||
// success, not allowed - whilst here, check the expression value in the exception
|
||||
Assert.assertEquals(ee.getExpressionString(), "somevalue");
|
||||
}
|
||||
try {
|
||||
LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||
lEx.setValue(new Rooty(), "flibble");
|
||||
Assert.fail("Should have got an exception that the value cannot be set");
|
||||
}
|
||||
catch (EvaluationException ee) {
|
||||
// success, not allowed - whilst here, check the expression value in the exception
|
||||
Assert.assertEquals(ee.getExpressionString(), "somevalue");
|
||||
}
|
||||
try {
|
||||
LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||
lEx.setValue(new StandardEvaluationContext(), new Rooty(), "flibble");
|
||||
Assert.fail("Should have got an exception that the value cannot be set");
|
||||
}
|
||||
catch (EvaluationException ee) {
|
||||
// success, not allowed - whilst here, check the expression value in the exception
|
||||
Assert.assertEquals(ee.getExpressionString(), "somevalue");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -59,6 +85,12 @@ public class LiteralExpressionTests {
|
||||
LiteralExpression lEx = new LiteralExpression("somevalue");
|
||||
Assert.assertEquals(String.class, lEx.getValueType());
|
||||
Assert.assertEquals(String.class, lEx.getValueType(new StandardEvaluationContext()));
|
||||
Assert.assertEquals(String.class, lEx.getValueType(new Rooty()));
|
||||
Assert.assertEquals(String.class, lEx.getValueType(new StandardEvaluationContext(), new Rooty()));
|
||||
Assert.assertEquals(String.class, lEx.getValueTypeDescriptor().getType());
|
||||
Assert.assertEquals(String.class, lEx.getValueTypeDescriptor(new StandardEvaluationContext()).getType());
|
||||
Assert.assertEquals(String.class, lEx.getValueTypeDescriptor(new Rooty()).getType());
|
||||
Assert.assertEquals(String.class, lEx.getValueTypeDescriptor(new StandardEvaluationContext(), new Rooty()).getType());
|
||||
}
|
||||
|
||||
private void checkString(String expectedString, Object value) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.ParserContext;
|
||||
@@ -98,6 +99,10 @@ public class TemplateExpressionParsingTests extends ExpressionTestCase {
|
||||
expr = parser.parseExpression("abc", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
o = expr.getValue();
|
||||
Assert.assertEquals("abc", o.toString());
|
||||
|
||||
expr = parser.parseExpression("abc", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
o = expr.getValue((Object)null);
|
||||
Assert.assertEquals("abc", o.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -106,13 +111,53 @@ public class TemplateExpressionParsingTests extends ExpressionTestCase {
|
||||
Expression ex = parser.parseExpression("hello ${'world'}", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
checkString("hello world", ex.getValue());
|
||||
checkString("hello world", ex.getValue(String.class));
|
||||
checkString("hello world", ex.getValue((Object)null, String.class));
|
||||
checkString("hello world", ex.getValue(new Rooty()));
|
||||
checkString("hello world", ex.getValue(new Rooty(), String.class));
|
||||
|
||||
EvaluationContext ctx = new StandardEvaluationContext();
|
||||
checkString("hello world", ex.getValue(ctx));
|
||||
checkString("hello world", ex.getValue(ctx, String.class));
|
||||
checkString("hello world", ex.getValue(ctx, null, String.class));
|
||||
checkString("hello world", ex.getValue(ctx, new Rooty()));
|
||||
checkString("hello world", ex.getValue(ctx, new Rooty(), String.class));
|
||||
checkString("hello world", ex.getValue(ctx, new Rooty(), String.class));
|
||||
Assert.assertEquals("hello ${'world'}", ex.getExpressionString());
|
||||
Assert.assertFalse(ex.isWritable(new StandardEvaluationContext()));
|
||||
Assert.assertFalse(ex.isWritable(new Rooty()));
|
||||
Assert.assertFalse(ex.isWritable(new StandardEvaluationContext(), new Rooty()));
|
||||
|
||||
Assert.assertEquals(String.class,ex.getValueType());
|
||||
Assert.assertEquals(String.class,ex.getValueType(ctx));
|
||||
Assert.assertEquals(String.class,ex.getValueTypeDescriptor().getType());
|
||||
Assert.assertEquals(String.class,ex.getValueTypeDescriptor(ctx).getType());
|
||||
Assert.assertEquals(String.class,ex.getValueType(new Rooty()));
|
||||
Assert.assertEquals(String.class,ex.getValueType(ctx, new Rooty()));
|
||||
Assert.assertEquals(String.class,ex.getValueTypeDescriptor(new Rooty()).getType());
|
||||
Assert.assertEquals(String.class,ex.getValueTypeDescriptor(ctx, new Rooty()).getType());
|
||||
|
||||
try {
|
||||
ex.setValue(ctx, null);
|
||||
Assert.fail();
|
||||
} catch (EvaluationException ee) {
|
||||
// success
|
||||
}
|
||||
try {
|
||||
ex.setValue((Object)null, null);
|
||||
Assert.fail();
|
||||
} catch (EvaluationException ee) {
|
||||
// success
|
||||
}
|
||||
try {
|
||||
ex.setValue(ctx, null, null);
|
||||
Assert.fail();
|
||||
} catch (EvaluationException ee) {
|
||||
// success
|
||||
}
|
||||
}
|
||||
|
||||
static class Rooty {}
|
||||
|
||||
@Test
|
||||
public void testNestedExpressions() throws Exception {
|
||||
SpelExpressionParser parser = new SpelExpressionParser();
|
||||
@@ -204,6 +249,16 @@ public class TemplateExpressionParsingTests extends ExpressionTestCase {
|
||||
Assert.assertEquals("abc", tpc.getExpressionPrefix());
|
||||
Assert.assertEquals("def", tpc.getExpressionSuffix());
|
||||
Assert.assertTrue(tpc.isTemplate());
|
||||
|
||||
tpc = new TemplateParserContext();
|
||||
Assert.assertEquals("#{", tpc.getExpressionPrefix());
|
||||
Assert.assertEquals("}", tpc.getExpressionSuffix());
|
||||
Assert.assertTrue(tpc.isTemplate());
|
||||
|
||||
ParserContext pc = ParserContext.TEMPLATE_EXPRESSION;
|
||||
Assert.assertEquals("#{", pc.getExpressionPrefix());
|
||||
Assert.assertEquals("}", pc.getExpressionSuffix());
|
||||
Assert.assertTrue(pc.isTemplate());
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
Reference in New Issue
Block a user