more tests, minor fixes. some findbugs issues addressed.
This commit is contained in:
parent
a9f4eeeabf
commit
00cecd0dd0
|
|
@ -29,6 +29,8 @@ public class TypedValue {
|
|||
|
||||
private Object value;
|
||||
private TypeDescriptor typeDescriptor;
|
||||
|
||||
public static final TypedValue NULL_TYPED_VALUE = new TypedValue(null, TypeDescriptor.NULL_TYPE_DESCRIPTOR);
|
||||
|
||||
/**
|
||||
* Create a TypedValue for a simple object. The type descriptor is inferred
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -52,9 +52,10 @@ public class ExpressionState {
|
|||
this.relatedContext = context;
|
||||
createVariableScope();
|
||||
}
|
||||
|
||||
|
||||
// create an empty top level VariableScope
|
||||
private void createVariableScope() {
|
||||
this.variableScopes.add(new VariableScope()); // create an empty top level VariableScope
|
||||
this.variableScopes.add(new VariableScope());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -64,9 +65,10 @@ public class ExpressionState {
|
|||
if (this.contextObjects.isEmpty()) {
|
||||
TypedValue rootObject = this.relatedContext.getRootObject();
|
||||
if (rootObject == null) {
|
||||
return new TypedValue(rootObject,TypeDescriptor.NULL_TYPE_DESCRIPTOR);
|
||||
return TypedValue.NULL_TYPED_VALUE;
|
||||
} else {
|
||||
return rootObject;
|
||||
}
|
||||
return rootObject;
|
||||
}
|
||||
return this.contextObjects.peek();
|
||||
}
|
||||
|
|
@ -80,7 +82,12 @@ public class ExpressionState {
|
|||
}
|
||||
|
||||
public TypedValue getRootContextObject() {
|
||||
return this.relatedContext.getRootObject();
|
||||
TypedValue root = this.relatedContext.getRootObject();
|
||||
if (root == null) {
|
||||
return TypedValue.NULL_TYPED_VALUE;
|
||||
} else {
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
||||
public void setVariable(String name, Object value) {
|
||||
|
|
@ -89,7 +96,11 @@ public class ExpressionState {
|
|||
|
||||
public TypedValue lookupVariable(String name) {
|
||||
Object value = this.relatedContext.lookupVariable(name);
|
||||
return new TypedValue(value,TypeDescriptor.forObject(value));
|
||||
if (value==null) {
|
||||
return TypedValue.NULL_TYPED_VALUE;
|
||||
} else {
|
||||
return new TypedValue(value,TypeDescriptor.forObject(value));
|
||||
}
|
||||
}
|
||||
|
||||
public TypeComparator getTypeComparator() {
|
||||
|
|
@ -108,13 +119,10 @@ public class ExpressionState {
|
|||
return this.relatedContext.getTypeConverter().convertValue(value.getValue(), targetTypeDescriptor);
|
||||
}
|
||||
|
||||
// public <T> T convertValue(TypedValue value, Class<T> targetType) throws EvaluationException {
|
||||
// return this.relatedContext.getTypeConverter().convertValue(value, targetType);
|
||||
// }
|
||||
|
||||
/**
|
||||
/*
|
||||
* A new scope is entered when a function is invoked
|
||||
*/
|
||||
|
||||
public void enterScope(Map<String, Object> argMap) {
|
||||
this.variableScopes.push(new VariableScope(argMap));
|
||||
}
|
||||
|
|
@ -167,7 +175,6 @@ public class ExpressionState {
|
|||
* A new scope is entered when a function is called and it is used to hold the parameters to the function call. If the names
|
||||
* of the parameters clash with those in a higher level scope, those in the higher level scope will not be accessible whilst
|
||||
* the function is executing. When the function returns the scope is exited.
|
||||
*
|
||||
*/
|
||||
private static class VariableScope {
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.expression.spel.ast;
|
||||
|
||||
import org.antlr.runtime.Token;
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.TypedValue;
|
||||
|
||||
/**
|
||||
|
|
@ -26,20 +25,18 @@ import org.springframework.expression.TypedValue;
|
|||
*/
|
||||
public class NullLiteral extends Literal {
|
||||
|
||||
private static final TypedValue NULL_TYPED_VALUE = new TypedValue(null,TypeDescriptor.NULL_TYPE_DESCRIPTOR);
|
||||
|
||||
public NullLiteral(Token payload) {
|
||||
super(payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedValue getLiteralValue() {
|
||||
return NULL_TYPED_VALUE;
|
||||
return TypedValue.NULL_TYPED_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return null;
|
||||
return "null";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class Projection extends SpelNodeImpl {
|
|||
TypedValue op = state.getActiveContextObject();
|
||||
|
||||
Object operand = op.getValue();
|
||||
TypeDescriptor operandTypeDescriptor = op.getTypeDescriptor();
|
||||
// TypeDescriptor operandTypeDescriptor = op.getTypeDescriptor();
|
||||
|
||||
// When the input is a map, we push a special context object on the stack
|
||||
// before calling the specified operation. This special context object
|
||||
|
|
@ -58,9 +58,10 @@ public class Projection extends SpelNodeImpl {
|
|||
if (operand instanceof Map) {
|
||||
Map<?, ?> mapdata = (Map<?, ?>) operand;
|
||||
List<Object> result = new ArrayList<Object>();
|
||||
for (Object k : mapdata.keySet()) {
|
||||
mapdata.entrySet();
|
||||
for (Map.Entry entry : mapdata.entrySet()) {
|
||||
try {
|
||||
state.pushActiveContextObject(new TypedValue(new KeyValuePair(k, mapdata.get(k)),TypeDescriptor.valueOf(KeyValuePair.class)));
|
||||
state.pushActiveContextObject(new TypedValue(new KeyValuePair(entry.getKey(), entry.getValue()),TypeDescriptor.valueOf(KeyValuePair.class)));
|
||||
result.add(getChild(0).getValueInternal(state).getValue());
|
||||
} finally {
|
||||
state.popActiveContextObject();
|
||||
|
|
|
|||
|
|
@ -63,10 +63,10 @@ public class Selection extends SpelNodeImpl {
|
|||
// TODO don't lose generic info for the new map
|
||||
Map<Object,Object> result = new HashMap<Object,Object>();
|
||||
Object lastKey = null;
|
||||
for (Object k : mapdata.keySet()) {
|
||||
for (Map.Entry entry : mapdata.entrySet()) {
|
||||
try {
|
||||
lastKey = k;
|
||||
KeyValuePair kvp = new KeyValuePair(k,mapdata.get(k));
|
||||
lastKey = entry.getKey();
|
||||
KeyValuePair kvp = new KeyValuePair(entry.getKey(),entry.getValue());
|
||||
TypedValue kvpair = new TypedValue(kvp,TypeDescriptor.valueOf(KeyValuePair.class));
|
||||
state.pushActiveContextObject(kvpair);
|
||||
Object o = selectionCriteria.getValueInternal(state).getValue();
|
||||
|
|
@ -90,9 +90,9 @@ public class Selection extends SpelNodeImpl {
|
|||
return new TypedValue(null,TypeDescriptor.NULL_TYPE_DESCRIPTOR);
|
||||
}
|
||||
if (variant == LAST) {
|
||||
Object lastValue = result.get(lastKey);
|
||||
Map resultMap = new HashMap();
|
||||
resultMap.put(lastKey,result.get(lastKey));
|
||||
Object lastValue = result.get(lastKey);
|
||||
resultMap.put(lastKey,lastValue);
|
||||
return new TypedValue(resultMap,TypeDescriptor.valueOf(Map.class));
|
||||
}
|
||||
return new TypedValue(result,op.getTypeDescriptor());
|
||||
|
|
|
|||
|
|
@ -57,8 +57,7 @@ class ReflectiveConstructorExecutor implements ConstructorExecutor {
|
|||
c.setAccessible(true);
|
||||
}
|
||||
return new TypedValue(c.newInstance(arguments),TypeDescriptor.valueOf(c.getClass()));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
} catch (Exception ex) {
|
||||
throw new AccessException("Problem invoking constructor: " + c, ex);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -333,6 +333,9 @@ public class ReflectivePropertyResolver implements PropertyAccessor {
|
|||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof CacheKey)) {
|
||||
return false;
|
||||
}
|
||||
CacheKey otherKey = (CacheKey) other;
|
||||
return (this.clazz.equals(otherKey.clazz) && this.name.equals(otherKey.name));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,8 @@ public class StandardTypeComparator implements TypeComparator {
|
|||
// If one is null, check if the other is
|
||||
if (left == null) {
|
||||
return right == null ? 0 : 1;
|
||||
}
|
||||
else if (right == null) {
|
||||
return left == null ? 0 : -1;
|
||||
} else if (right == null) {
|
||||
return -1; // left cannot be null
|
||||
}
|
||||
|
||||
// Basic number comparisons
|
||||
|
|
|
|||
|
|
@ -23,57 +23,8 @@ package org.springframework.expression.spel;
|
|||
*/
|
||||
public class ConstructorInvocationTests extends ExpressionTestCase {
|
||||
|
||||
// Some tests commented out as language support has been removed for now
|
||||
|
||||
// public void testPrimitiveTypeArrayConstructors() {
|
||||
// evaluate("new int[]{1,2,3,4}.count()", 4, Integer.class);
|
||||
// evaluate("new boolean[]{true,false,true}.count()", 3, Integer.class);
|
||||
// evaluate("new char[]{'a','b','c'}.count()", 3, Integer.class);
|
||||
// evaluate("new long[]{1,2,3,4,5}.count()", 5, Integer.class);
|
||||
// evaluate("new short[]{2,3,4,5,6}.count()", 5, Integer.class);
|
||||
// evaluate("new double[]{1d,2d,3d,4d}.count()", 4, Integer.class);
|
||||
// evaluate("new float[]{1f,2f,3f,4f}.count()", 4, Integer.class);
|
||||
// evaluate("new byte[]{1,2,3,4}.count()", 4, Integer.class);
|
||||
// }
|
||||
|
||||
// public void testPrimitiveTypeArrayConstructorsElements() {
|
||||
// evaluate("new int[]{1,2,3,4}[0]", 1, Integer.class);
|
||||
// evaluate("new boolean[]{true,false,true}[0]", true, Boolean.class);
|
||||
// evaluate("new char[]{'a','b','c'}[0]", 'a', Character.class);
|
||||
// evaluate("new long[]{1,2,3,4,5}[0]", 1L, Long.class);
|
||||
// evaluate("new short[]{2,3,4,5,6}[0]", (short) 2, Short.class);
|
||||
// evaluate("new double[]{1d,2d,3d,4d}[0]", (double) 1, Double.class);
|
||||
// evaluate("new float[]{1f,2f,3f,4f}[0]", (float) 1, Float.class);
|
||||
// evaluate("new byte[]{1,2,3,4}[0]", (byte) 1, Byte.class);
|
||||
// }
|
||||
|
||||
// public void testErrorCases() {
|
||||
// evaluateAndCheckError("new char[7]{'a','c','d','e'}", SpelMessages.INITIALIZER_LENGTH_INCORRECT);
|
||||
// evaluateAndCheckError("new char[3]{'a','c','d','e'}", SpelMessages.INITIALIZER_LENGTH_INCORRECT);
|
||||
// evaluateAndCheckError("new char[2]{'hello','world'}", SpelMessages.TYPE_CONVERSION_ERROR);
|
||||
// evaluateAndCheckError("new String('a','c','d')", SpelMessages.CONSTRUCTOR_NOT_FOUND);
|
||||
// }
|
||||
|
||||
// public void testTypeArrayConstructors() {
|
||||
// evaluate("new String[]{'a','b','c','d'}[1]", "b", String.class);
|
||||
// evaluateAndCheckError("new String[]{'a','b','c','d'}.size()", SpelMessages.METHOD_NOT_FOUND, 30, "size()",
|
||||
// "java.lang.String[]");
|
||||
// evaluateAndCheckError("new String[]{'a','b','c','d'}.juggernaut", SpelMessages.PROPERTY_OR_FIELD_NOT_FOUND, 30,
|
||||
// "juggernaut", "java.lang.String[]");
|
||||
// evaluate("new String[]{'a','b','c','d'}.length", 4, Integer.class);
|
||||
// }
|
||||
|
||||
// public void testMultiDimensionalArrays() {
|
||||
// evaluate(
|
||||
// "new String[3,4]",
|
||||
// "[Ljava.lang.String;[3]{java.lang.String[4]{null,null,null,null},java.lang.String[4]{null,null,null,null},java.lang.String[4]{null,null,null,null}}"
|
||||
// ,
|
||||
// new String[3][4].getClass());
|
||||
// }
|
||||
|
||||
public void testTypeConstructors() {
|
||||
evaluate("new String('hello world')", "hello world", String.class);
|
||||
// evaluate("new String(new char[]{'h','e','l','l','o'})", "hello", String.class);
|
||||
}
|
||||
|
||||
public void testNonExistentType() {
|
||||
|
|
|
|||
|
|
@ -43,5 +43,55 @@ public class DefaultComparatorUnitTests extends TestCase {
|
|||
assertTrue(comparator.compare(1.0f, 1) == 0);
|
||||
assertTrue(comparator.compare(2.0f, 1) > 0);
|
||||
|
||||
assertTrue(comparator.compare(1L, 2) < 0);
|
||||
assertTrue(comparator.compare(1L, 1) == 0);
|
||||
assertTrue(comparator.compare(2L, 1) > 0);
|
||||
|
||||
assertTrue(comparator.compare(1, 2L) < 0);
|
||||
assertTrue(comparator.compare(1, 1L) == 0);
|
||||
assertTrue(comparator.compare(2, 1L) > 0);
|
||||
|
||||
assertTrue(comparator.compare(1L, 2L) < 0);
|
||||
assertTrue(comparator.compare(1L, 1L) == 0);
|
||||
assertTrue(comparator.compare(2L, 1L) > 0);
|
||||
}
|
||||
|
||||
public void testNulls() throws EvaluationException {
|
||||
TypeComparator comparator = new StandardTypeComparator();
|
||||
assertTrue(comparator.compare(null,"abc")>0);
|
||||
assertTrue(comparator.compare(null,null)==0);
|
||||
assertTrue(comparator.compare("abc",null)<0);
|
||||
}
|
||||
|
||||
public void testObjects() throws EvaluationException {
|
||||
TypeComparator comparator = new StandardTypeComparator();
|
||||
assertTrue(comparator.compare("a","a")==0);
|
||||
assertTrue(comparator.compare("a","b")<0);
|
||||
assertTrue(comparator.compare("b","a")>0);
|
||||
|
||||
try {
|
||||
comparator.compare("a",3);
|
||||
fail("Should have failed");
|
||||
} catch (EvaluationException ee) {
|
||||
SpelException sEx = (SpelException)ee;
|
||||
assertEquals(SpelMessages.NOT_COMPARABLE,sEx.getMessageUnformatted());
|
||||
}
|
||||
try {
|
||||
comparator.compare(2,"b");
|
||||
fail("Should have failed");
|
||||
} catch (EvaluationException ee) {
|
||||
SpelException sEx = (SpelException)ee;
|
||||
assertEquals(SpelMessages.NOT_COMPARABLE,sEx.getMessageUnformatted());
|
||||
}
|
||||
}
|
||||
|
||||
public void testCanCompare() throws EvaluationException {
|
||||
TypeComparator comparator = new StandardTypeComparator();
|
||||
assertTrue(comparator.canCompare(null,1));
|
||||
assertTrue(comparator.canCompare(1,null));
|
||||
|
||||
assertTrue(comparator.canCompare(2,1));
|
||||
assertTrue(comparator.canCompare("abc","def"));
|
||||
assertFalse(comparator.canCompare("abc",3));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,21 +16,16 @@
|
|||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* Tests the evaluation of real expressions in a real context.
|
||||
*
|
||||
* Node: Some tests commented out as language support has been removed
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class EvaluationTests extends ExpressionTestCase {
|
||||
|
||||
// relational operators: lt, le, gt, ge, eq, ne
|
||||
public void testRelOperatorGT01() {
|
||||
evaluate("3 > 6", "false", Boolean.class);
|
||||
}
|
||||
|
|
@ -51,48 +46,10 @@ public class EvaluationTests extends ExpressionTestCase {
|
|||
evaluate("3 >= 3", "true", Boolean.class);
|
||||
}
|
||||
|
||||
|
||||
// public void testRelOperatorsIn01() {
|
||||
// evaluate("3 in {1,2,3,4,5}", "true", Boolean.class);
|
||||
// }
|
||||
|
||||
// public void testRelOperatorsIn02() {
|
||||
// evaluate("name in {null, \"Nikola Tesla\"}", "true", Boolean.class);
|
||||
// evaluate("name in {null, \"Anonymous\"}", "false", Boolean.class);
|
||||
// }
|
||||
//
|
||||
public void testRelOperatorsBetween01() {
|
||||
evaluate("1 between listOneFive", "true", Boolean.class);
|
||||
// evaluate("1 between {1, 5}", "true", Boolean.class); // no inline list building at the moment
|
||||
}
|
||||
//
|
||||
// public void testRelOperatorsBetween02() {
|
||||
// evaluate("'efg' between {'abc', 'xyz'}", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
public void testRelOperatorsBetweenErrors01() {
|
||||
evaluateAndCheckError("1 between T(String)", SpelMessages.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST, 12);
|
||||
}
|
||||
//
|
||||
// public void testRelOperatorsBetweenErrors02() {
|
||||
// evaluateAndCheckError("'abc' between {5,7}", SpelMessages.NOT_COMPARABLE, 6);
|
||||
// }
|
||||
public void testRelOperatorsBetweenErrors03() {
|
||||
evaluateAndCheckError("1 between listOfNumbersUpToTen", SpelMessages.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST, 10);
|
||||
}
|
||||
|
||||
public void testRelOperatorsIs01() {
|
||||
evaluate("'xyz' instanceof T(int)", "false", Boolean.class);
|
||||
}
|
||||
|
||||
// public void testRelOperatorsIs02() {
|
||||
// evaluate("{1, 2, 3, 4, 5} instanceof T(List)", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
// public void testRelOperatorsIs03() {
|
||||
// evaluate("{1, 2, 3, 4, 5} instanceof T(List)", "true", Boolean.class);
|
||||
// }
|
||||
|
||||
public void testRelOperatorsIs04() {
|
||||
evaluate("null instanceof T(String)", "false", Boolean.class);
|
||||
}
|
||||
|
|
@ -132,9 +89,8 @@ public class EvaluationTests extends ExpressionTestCase {
|
|||
|
||||
// property access
|
||||
public void testPropertyField01() {
|
||||
evaluate("name", "Nikola Tesla", String.class, false); // not writable because (1) name is private (2) there is
|
||||
// no
|
||||
// setter, only a getter
|
||||
evaluate("name", "Nikola Tesla", String.class, false);
|
||||
// not writable because (1) name is private (2) there is no setter, only a getter
|
||||
evaluateAndCheckError("madeup", SpelMessages.PROPERTY_OR_FIELD_NOT_FOUND, 0, "madeup",
|
||||
"org.springframework.expression.spel.testresources.Inventor");
|
||||
}
|
||||
|
|
@ -157,59 +113,11 @@ public class EvaluationTests extends ExpressionTestCase {
|
|||
evaluate("echo(name)", "Nikola Tesla", String.class);
|
||||
}
|
||||
|
||||
// inline list creation
|
||||
// public void testInlineListCreation01() {
|
||||
// evaluate("{1, 2, 3, 4, 5}", "[1, 2, 3, 4, 5]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testInlineListCreation02() {
|
||||
// evaluate("{'abc', 'xyz'}", "[abc, xyz]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// // inline map creation
|
||||
// public void testInlineMapCreation01() {
|
||||
// evaluate("#{'key1':'Value 1', 'today':'Monday'}", "{key1=Value 1, today=Monday}", HashMap.class);
|
||||
// }
|
||||
//
|
||||
// public void testInlineMapCreation02() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}.size()", 3, Integer.class);// "{2=February, 1=January,
|
||||
// // 3=March}", HashMap.class);
|
||||
// }
|
||||
//
|
||||
// public void testInlineMapCreation03() {
|
||||
// evaluate("#{'key1':'Value 1', 'today':'Monday'}['key1']", "Value 1", String.class);
|
||||
// }
|
||||
//
|
||||
// public void testInlineMapCreation04() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}[3]", "March", String.class);
|
||||
// }
|
||||
//
|
||||
// public void testInlineMapCreation05() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}.get(2)", "February", String.class);
|
||||
// }
|
||||
//
|
||||
// // set construction
|
||||
// public void testSetConstruction01() {
|
||||
// evaluate("new HashSet().addAll({'a','b','c'})", "true", Boolean.class);
|
||||
// }
|
||||
|
||||
// constructors
|
||||
public void testConstructorInvocation01() {
|
||||
evaluate("new String('hello')", "hello", String.class);
|
||||
}
|
||||
|
||||
// public void testConstructorInvocation02() {
|
||||
// evaluate("new String[3]", "java.lang.String[3]{null,null,null}", String[].class);
|
||||
// }
|
||||
|
||||
// public void testConstructorInvocation03() {
|
||||
// evaluateAndCheckError("new String[]", SpelMessages.NO_SIZE_OR_INITIALIZER_FOR_ARRAY_CONSTRUCTION, 4);
|
||||
// }
|
||||
|
||||
// public void testConstructorInvocation04() {
|
||||
// evaluateAndCheckError("new String[3]{'abc',3,'def'}", SpelMessages.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, 4);
|
||||
// }
|
||||
|
||||
public void testConstructorInvocation05() {
|
||||
evaluate("new java.lang.String('foobar')", "foobar", String.class);
|
||||
}
|
||||
|
|
@ -229,16 +137,6 @@ public class EvaluationTests extends ExpressionTestCase {
|
|||
assertEquals("new String('wibble')",expr.toStringAST());
|
||||
}
|
||||
|
||||
|
||||
// array construction
|
||||
// public void testArrayConstruction01() {
|
||||
// evaluate("new int[] {1, 2, 3, 4, 5}", "int[5]{1,2,3,4,5}", int[].class);
|
||||
// }
|
||||
|
||||
// public void testArrayConstruction02() {
|
||||
// evaluate("new String[] {'abc', 'xyz'}", "java.lang.String[2]{abc,xyz}", String[].class);
|
||||
// }
|
||||
|
||||
// unary expressions
|
||||
public void testUnaryMinus01() {
|
||||
evaluate("-5", "-5", Integer.class);
|
||||
|
|
@ -251,153 +149,11 @@ public class EvaluationTests extends ExpressionTestCase {
|
|||
public void testUnaryNot01() {
|
||||
evaluate("!true", "false", Boolean.class);
|
||||
}
|
||||
|
||||
// collection processors
|
||||
// from spring.net: count,sum,max,min,average,sort,orderBy,distinct,nonNull
|
||||
// public void testProcessorsCount01() {
|
||||
// evaluate("new String[] {'abc','def','xyz'}.count()", "3", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsCount02() {
|
||||
// evaluate("new int[] {1,2,3}.count()", "3", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsMax01() {
|
||||
// evaluate("new int[] {1,2,3}.max()", "3", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsMin01() {
|
||||
// evaluate("new int[] {1,2,3}.min()", "1", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsKeys01() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}.keySet().sort()", "[1, 2, 3]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsValues01() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}.values().sort()", "[February, January, March]",
|
||||
// ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsAverage01() {
|
||||
// evaluate("new int[] {1,2,3}.average()", "2", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsSort01() {
|
||||
// evaluate("new int[] {3,2,1}.sort()", "int[3]{1,2,3}", int[].class);
|
||||
// }
|
||||
//
|
||||
// public void testCollectionProcessorsNonNull01() {
|
||||
// evaluate("{'a','b',null,'d',null}.nonnull()", "[a, b, d]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testCollectionProcessorsDistinct01() {
|
||||
// evaluate("{'a','b','a','d','e'}.distinct()", "[a, b, d, e]", ArrayList.class);
|
||||
// }
|
||||
|
||||
// projection and selection
|
||||
public void testProjection01() {
|
||||
evaluate("listOfNumbersUpToTen.!{#this<5?'y':'n'}","[y, y, y, y, n, n, n, n, n, n]",ArrayList.class);
|
||||
// inline list creation not supported at the moment
|
||||
// evaluate("{1,2,3,4,5,6,7,8,9,10}.!{#isEven(#this)}", "[n, y, n, y, n, y, n, y, n, y]", ArrayList.class);
|
||||
}
|
||||
|
||||
public void testProjection02() {
|
||||
// inline map creation not supported at the moment
|
||||
// evaluate("#{'a':'y','b':'n','c':'y'}.!{value=='y'?key:null}.nonnull().sort()", "[a, c]", ArrayList.class);
|
||||
evaluate("mapOfNumbersUpToTen.!{key>5?value:null}", "[null, null, null, null, null, six, seven, eight, nine, ten]", ArrayList.class);
|
||||
}
|
||||
|
||||
// public void testProjection03() {
|
||||
// evaluate("{1,2,3,4,5,6,7,8,9,10}.!{#this>5}",
|
||||
// "[false, false, false, false, false, true, true, true, true, true]", ArrayList.class);
|
||||
// }
|
||||
|
||||
// public void testProjection04() {
|
||||
// evaluate("{1,2,3,4,5,6,7,8,9,10}.!{$index>5?'y':'n'}", "[n, n, n, n, n, n, y, y, y, y]", ArrayList.class);
|
||||
// }
|
||||
|
||||
public void testProjection05() {
|
||||
evaluateAndCheckError("'abc'.!{true}", SpelMessages.PROJECTION_NOT_SUPPORTED_ON_TYPE);
|
||||
}
|
||||
|
||||
public void testProjection06() throws Exception {
|
||||
SpelExpression expr = (SpelExpression)parser.parseExpression("'abc'.!{true}");
|
||||
assertEquals("'abc'.!{true}",expr.toStringAST());
|
||||
assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
}
|
||||
|
||||
//public void testSelection01() {
|
||||
// inline list creation not supported:
|
||||
// evaluate("{1,2,3,4,5,6,7,8,9,10}.?{#isEven(#this) == 'y'}", "[2, 4, 6, 8, 10]", ArrayList.class);
|
||||
//}
|
||||
|
||||
public void testSelection02() {
|
||||
evaluate("testMap.keySet().?{#this matches '.*o.*'}", "[monday]", ArrayList.class);
|
||||
evaluate("testMap.keySet().?{#this matches '.*r.*'}.contains('saturday')", "true", Boolean.class);
|
||||
evaluate("testMap.keySet().?{#this matches '.*r.*'}.size()", "3", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelectionError_NonBooleanSelectionCriteria() {
|
||||
evaluateAndCheckError("listOfNumbersUpToTen.?{'nonboolean'}",
|
||||
SpelMessages.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
|
||||
}
|
||||
|
||||
// public void testSelectionUsingIndex() {
|
||||
// evaluate("{1,2,3,4,5,6,7,8,9,10}.?{$index > 5 }", "[7, 8, 9, 10]", ArrayList.class);
|
||||
// }
|
||||
|
||||
public void testSelection03() {
|
||||
evaluate("mapOfNumbersUpToTen.?{key>5}.size()", "5", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelection04() {
|
||||
evaluateAndCheckError("mapOfNumbersUpToTen.?{'hello'}.size()",SpelMessages.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
|
||||
}
|
||||
|
||||
public void testSelectionFirst01() {
|
||||
evaluate("listOfNumbersUpToTen.^{#isEven(#this) == 'y'}", "2", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelectionFirst02() {
|
||||
evaluate("mapOfNumbersUpToTen.^{key>5}.size()", "1", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelectionLast01() {
|
||||
evaluate("listOfNumbersUpToTen.${#isEven(#this) == 'y'}", "10", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelectionLast02() {
|
||||
evaluate("mapOfNumbersUpToTen.${key>5}.size()", "1", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelectionAST() throws Exception {
|
||||
SpelExpression expr = (SpelExpression)parser.parseExpression("'abc'.^{true}");
|
||||
assertEquals("'abc'.^{true}",expr.toStringAST());
|
||||
assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
expr = (SpelExpression)parser.parseExpression("'abc'.?{true}");
|
||||
assertEquals("'abc'.?{true}",expr.toStringAST());
|
||||
assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
expr = (SpelExpression)parser.parseExpression("'abc'.${true}");
|
||||
assertEquals("'abc'.${true}",expr.toStringAST());
|
||||
assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
}
|
||||
|
||||
|
||||
// assignment
|
||||
public void testAssignmentToVariables01() {
|
||||
evaluate("#var1='value1'", "value1", String.class);
|
||||
}
|
||||
|
||||
// Ternary operator
|
||||
// public void testTernaryOperator01() {
|
||||
// evaluate("{1}.#isEven(#this[0]) == 'y'?'it is even':'it is odd'", "it is odd", String.class);
|
||||
// }
|
||||
//
|
||||
// public void testTernaryOperator02() {
|
||||
// evaluate("{2}.#isEven(#this[0]) == 'y'?'it is even':'it is odd'", "it is even", String.class);
|
||||
// }
|
||||
|
||||
public void testTernaryOperator01() {
|
||||
evaluate("2>4?1:2",2,Integer.class);
|
||||
}
|
||||
|
|
@ -414,15 +170,6 @@ public class EvaluationTests extends ExpressionTestCase {
|
|||
Expression expr = parser.parseExpression("1>2?3:4");
|
||||
assertFalse(expr.isWritable(eContext));
|
||||
}
|
||||
|
||||
// Indexer
|
||||
// public void testCutProcessor01() {
|
||||
// evaluate("{1,2,3,4,5}.cut(1,3)", "[2, 3, 4]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testCutProcessor02() {
|
||||
// evaluate("{1,2,3,4,5}.cut(3,1)", "[4, 3, 2]", ArrayList.class);
|
||||
// }
|
||||
|
||||
public void testIndexer03() {
|
||||
evaluate("'christian'[8]", "n", String.class);
|
||||
|
|
@ -432,36 +179,6 @@ public class EvaluationTests extends ExpressionTestCase {
|
|||
evaluateAndCheckError("new org.springframework.expression.spel.testresources.Inventor().inventions[1]",SpelMessages.CANNOT_INDEX_INTO_NULL_VALUE);
|
||||
}
|
||||
|
||||
// Bean references
|
||||
// public void testReferences01() {
|
||||
// evaluate("@(apple).name", "Apple", String.class, true);
|
||||
// }
|
||||
//
|
||||
// public void testReferences02() {
|
||||
// evaluate("@(fruits:banana).name", "Banana", String.class, true);
|
||||
// }
|
||||
//
|
||||
// public void testReferences03() {
|
||||
// evaluate("@(a.b.c)", null, null);
|
||||
// } // null - no context, a.b.c treated as name
|
||||
//
|
||||
// public void testReferences05() {
|
||||
// evaluate("@(a/b/c:orange).name", "Orange", String.class, true);
|
||||
// }
|
||||
//
|
||||
// public void testReferences06() {
|
||||
// evaluate("@(apple).color.getRGB() == T(java.awt.Color).green.getRGB()", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
// public void testReferences07() {
|
||||
// evaluate("@(apple).color.getRGB().equals(T(java.awt.Color).green.getRGB())", "true", Boolean.class);
|
||||
// }
|
||||
|
||||
// value is not public, it is accessed through getRGB()
|
||||
// public void testStaticRef01() {
|
||||
// evaluate("T(Color).green.value!=0", "true", Boolean.class);
|
||||
// }
|
||||
|
||||
public void testStaticRef02() {
|
||||
evaluate("T(java.awt.Color).green.getRGB()!=0", "true", Boolean.class);
|
||||
}
|
||||
|
|
@ -479,42 +196,6 @@ public class EvaluationTests extends ExpressionTestCase {
|
|||
evaluate("#reverseString('hello')", "olleh", String.class);
|
||||
}
|
||||
|
||||
//
|
||||
// public void testLambda02() {
|
||||
// evaluate("(#max={|x,y| $x > $y ? $x : $y };true)", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaMax() {
|
||||
// evaluate("(#max = {|x,y| $x > $y ? $x : $y }; #max(5,25))", "25", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaFactorial01() {
|
||||
// evaluate("(#fact = {|n| $n <= 1 ? 1 : $n * #fact($n-1) }; #fact(5))", "120", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaFactorial02() {
|
||||
// evaluate("(#fact = {|n| $n <= 1 ? 1 : #fact($n-1) * $n }; #fact(5))", "120", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaAlphabet01() {
|
||||
// evaluate("(#alpha = {|l,s| $l>'z'?$s:#alpha($l+1,$s+$l)};#alphabet={||#alpha('a','')}; #alphabet())",
|
||||
// "abcdefghijklmnopqrstuvwxyz", String.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaAlphabet02() {
|
||||
// evaluate("(#alphabet = {|l,s| $l>'z'?$s:#alphabet($l+1,$s+$l)};#alphabet('a',''))",
|
||||
// "abcdefghijklmnopqrstuvwxyz", String.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaDelegation01() {
|
||||
// evaluate("(#sqrt={|n| T(Math).sqrt($n)};#delegate={|f,n| $f($n)};#delegate(#sqrt,4))", "2.0", Double.class);
|
||||
// }
|
||||
//
|
||||
// public void testVariableReferences() {
|
||||
// evaluate("(#answer=42;#answer)", "42", Integer.class, true);
|
||||
// evaluate("($answer=42;$answer)", "42", Integer.class, true);
|
||||
// }
|
||||
|
||||
// type references
|
||||
public void testTypeReferences01() {
|
||||
evaluate("T(java.lang.String)", "class java.lang.String", Class.class);
|
||||
|
|
@ -556,6 +237,5 @@ public class EvaluationTests extends ExpressionTestCase {
|
|||
evaluateAndAskForReturnType("3*4+5", (short) 17, Short.class);
|
||||
evaluateAndAskForReturnType("3*4+5", "17", String.class);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Operation;
|
||||
import org.springframework.expression.TypedValue;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.testresources.Inventor;
|
||||
|
||||
|
||||
/**
|
||||
* Tests for the expression state object - some features are not yet exploited in the language (eg nested scopes)
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class ExpressionStateTests extends ExpressionTestCase {
|
||||
|
||||
public void testConstruction() {
|
||||
EvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
|
||||
ExpressionState state = new ExpressionState(context);
|
||||
assertEquals(context,state.getEvaluationContext());
|
||||
}
|
||||
|
||||
// Local variables are in variable scopes which come and go during evaluation. Normal variables are
|
||||
// accessible through the evaluation context
|
||||
|
||||
|
||||
public void testLocalVariables() {
|
||||
ExpressionState state = getState();
|
||||
|
||||
Object value = state.lookupLocalVariable("foo");
|
||||
assertNull(value);
|
||||
|
||||
state.setLocalVariable("foo",34);
|
||||
value = state.lookupLocalVariable("foo");
|
||||
assertEquals(34,value);
|
||||
|
||||
state.setLocalVariable("foo",null);
|
||||
value = state.lookupLocalVariable("foo");
|
||||
assertEquals(null,value);
|
||||
|
||||
}
|
||||
|
||||
public void testVariables() {
|
||||
ExpressionState state = getState();
|
||||
TypedValue typedValue = state.lookupVariable("foo");
|
||||
assertEquals(TypedValue.NULL_TYPED_VALUE,typedValue);
|
||||
|
||||
state.setVariable("foo",34);
|
||||
typedValue = state.lookupVariable("foo");
|
||||
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());
|
||||
}
|
||||
|
||||
public void testNoVariableInteference() {
|
||||
ExpressionState state = getState();
|
||||
TypedValue typedValue = state.lookupVariable("foo");
|
||||
assertEquals(TypedValue.NULL_TYPED_VALUE,typedValue);
|
||||
|
||||
state.setLocalVariable("foo",34);
|
||||
typedValue = state.lookupVariable("foo");
|
||||
assertEquals(TypedValue.NULL_TYPED_VALUE,typedValue);
|
||||
|
||||
state.setVariable("goo","hello");
|
||||
assertNull(state.lookupLocalVariable("goo"));
|
||||
}
|
||||
|
||||
public void testLocalVariableNestedScopes() {
|
||||
ExpressionState state = getState();
|
||||
assertEquals(null,state.lookupLocalVariable("foo"));
|
||||
|
||||
state.setLocalVariable("foo",12);
|
||||
assertEquals(12,state.lookupLocalVariable("foo"));
|
||||
|
||||
state.enterScope(null);
|
||||
assertEquals(12,state.lookupLocalVariable("foo")); // found in upper scope
|
||||
|
||||
state.setLocalVariable("foo","abc");
|
||||
assertEquals("abc",state.lookupLocalVariable("foo")); // found in nested scope
|
||||
|
||||
state.exitScope();
|
||||
assertEquals(12,state.lookupLocalVariable("foo")); // found in nested scope
|
||||
}
|
||||
|
||||
public void testRootContextObject() {
|
||||
ExpressionState state = getState();
|
||||
assertEquals(Inventor.class,state.getRootContextObject().getValue().getClass());
|
||||
|
||||
state.getEvaluationContext().setRootObject(null);
|
||||
assertEquals(null,state.getRootContextObject().getValue());
|
||||
|
||||
state = new ExpressionState(new StandardEvaluationContext());
|
||||
assertEquals(TypedValue.NULL_TYPED_VALUE,state.getRootContextObject());
|
||||
}
|
||||
|
||||
public void testActiveContextObject() {
|
||||
ExpressionState state = getState();
|
||||
assertEquals(state.getRootContextObject().getValue(),state.getActiveContextObject().getValue());
|
||||
|
||||
state.pushActiveContextObject(new TypedValue(34));
|
||||
assertEquals(34,state.getActiveContextObject().getValue());
|
||||
|
||||
state.pushActiveContextObject(new TypedValue("hello"));
|
||||
assertEquals("hello",state.getActiveContextObject().getValue());
|
||||
|
||||
state.popActiveContextObject();
|
||||
assertEquals(34,state.getActiveContextObject().getValue());
|
||||
|
||||
state.popActiveContextObject();
|
||||
assertEquals(state.getRootContextObject().getValue(),state.getActiveContextObject().getValue());
|
||||
|
||||
state = new ExpressionState(new StandardEvaluationContext());
|
||||
assertEquals(TypedValue.NULL_TYPED_VALUE,state.getActiveContextObject());
|
||||
}
|
||||
|
||||
public void testPopulatedNestedScopes() {
|
||||
ExpressionState state = getState();
|
||||
assertNull(state.lookupLocalVariable("foo"));
|
||||
|
||||
state.enterScope("foo",34);
|
||||
assertEquals(34,state.lookupLocalVariable("foo"));
|
||||
|
||||
state.enterScope(null);
|
||||
state.setLocalVariable("foo",12);
|
||||
assertEquals(12,state.lookupLocalVariable("foo"));
|
||||
|
||||
state.exitScope();
|
||||
assertEquals(34,state.lookupLocalVariable("foo"));
|
||||
|
||||
state.exitScope();
|
||||
assertNull(state.lookupLocalVariable("goo"));
|
||||
}
|
||||
|
||||
public void testPopulatedNestedScopesMap() {
|
||||
ExpressionState state = getState();
|
||||
assertNull(state.lookupLocalVariable("foo"));
|
||||
assertNull(state.lookupLocalVariable("goo"));
|
||||
|
||||
Map<String,Object> m = new HashMap<String,Object>();
|
||||
m.put("foo",34);
|
||||
m.put("goo","abc");
|
||||
|
||||
state.enterScope(m);
|
||||
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"));
|
||||
|
||||
state.exitScope();
|
||||
state.exitScope();
|
||||
assertNull(state.lookupLocalVariable("foo"));
|
||||
assertNull(state.lookupLocalVariable("goo"));
|
||||
}
|
||||
|
||||
public void testOperators() throws Exception {
|
||||
ExpressionState state = getState();
|
||||
try {
|
||||
state.operate(Operation.ADD,1,2);
|
||||
fail("should have failed");
|
||||
} catch (EvaluationException ee) {
|
||||
SpelException sEx = (SpelException)ee;
|
||||
assertEquals(SpelMessages.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES,sEx.getMessageUnformatted());
|
||||
}
|
||||
|
||||
try {
|
||||
state.operate(Operation.ADD,null,null);
|
||||
fail("should have failed");
|
||||
} catch (EvaluationException ee) {
|
||||
SpelException sEx = (SpelException)ee;
|
||||
assertEquals(SpelMessages.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES,sEx.getMessageUnformatted());
|
||||
}
|
||||
}
|
||||
|
||||
public void testComparator() {
|
||||
ExpressionState state = getState();
|
||||
assertEquals(state.getEvaluationContext().getTypeComparator(),state.getTypeComparator());
|
||||
}
|
||||
|
||||
public void testTypeLocator() throws EvaluationException {
|
||||
ExpressionState state = getState();
|
||||
assertNotNull(state.getEvaluationContext().getTypeLocator());
|
||||
assertEquals(Integer.class,state.findType("java.lang.Integer"));
|
||||
try {
|
||||
state.findType("someMadeUpName");
|
||||
fail("Should have failed to find it");
|
||||
} catch (EvaluationException ee) {
|
||||
SpelException sEx = (SpelException)ee;
|
||||
assertEquals(SpelMessages.TYPE_NOT_FOUND,sEx.getMessageUnformatted());
|
||||
}
|
||||
}
|
||||
|
||||
public void testTypeConversion() throws EvaluationException {
|
||||
ExpressionState state = getState();
|
||||
String s = (String)state.convertValue(34,TypeDescriptor.valueOf(String.class));
|
||||
assertEquals("34",s);
|
||||
|
||||
s = (String)state.convertValue(new TypedValue(34),TypeDescriptor.valueOf(String.class));
|
||||
assertEquals("34",s);
|
||||
}
|
||||
|
||||
public void testPropertyAccessors() {
|
||||
ExpressionState state = getState();
|
||||
assertEquals(state.getEvaluationContext().getPropertyAccessors(),state.getPropertyAccessors());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a new ExpressionState
|
||||
*/
|
||||
private ExpressionState getState() {
|
||||
EvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
|
||||
ExpressionState state = new ExpressionState(context);
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,10 @@
|
|||
*/
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.spel.ast.FormatHelper;
|
||||
|
||||
/**
|
||||
|
|
@ -38,8 +42,33 @@ public class HelperTests extends ExpressionTestCase {
|
|||
assertEquals("boo()",FormatHelper.formatMethodForMessage("boo"));
|
||||
}
|
||||
|
||||
// public void testReflectionHelper01() {
|
||||
// ReflectionHelper.convertArguments(parameterTypes, isVarargs, converter, arguments)
|
||||
//// ReflectionHelper.setupArgumentsForVarargsInvocation(;, args)
|
||||
// }
|
||||
public void testUtilities() throws ParseException {
|
||||
SpelExpression expr = (SpelExpression)parser.parseExpression("3+4+5+6+7-2");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
PrintStream ps = new PrintStream(baos);
|
||||
SpelUtilities.printAbstractSyntaxTree(ps, expr);
|
||||
ps.flush();
|
||||
String s = baos.toString();
|
||||
// ===> Expression '3+4+5+6+7-2' - AST start
|
||||
// OperatorMinus value:(((((3 + 4) + 5) + 6) + 7) - 2) #children:2
|
||||
// OperatorPlus value:((((3 + 4) + 5) + 6) + 7) #children:2
|
||||
// OperatorPlus value:(((3 + 4) + 5) + 6) #children:2
|
||||
// OperatorPlus value:((3 + 4) + 5) #children:2
|
||||
// OperatorPlus value:(3 + 4) #children:2
|
||||
// CompoundExpression value:3
|
||||
// IntLiteral value:3
|
||||
// CompoundExpression value:4
|
||||
// IntLiteral value:4
|
||||
// CompoundExpression value:5
|
||||
// IntLiteral value:5
|
||||
// CompoundExpression value:6
|
||||
// IntLiteral value:6
|
||||
// CompoundExpression value:7
|
||||
// IntLiteral value:7
|
||||
// CompoundExpression value:2
|
||||
// IntLiteral value:2
|
||||
// ===> Expression '3+4+5+6+7-2' - AST end
|
||||
assertTrue(s.indexOf("===> Expression '3+4+5+6+7-2' - AST start")!=-1);
|
||||
assertTrue(s.indexOf(" OperatorPlus value:((((3 + 4) + 5) + 6) + 7) #children:2")!=-1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
||||
/**
|
||||
* These are tests for language features that are not yet considered 'live'. Either missing implementation, or documentation.
|
||||
*
|
||||
* Where implementation is missing the tests are commented out.
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class InProgressTests extends ExpressionTestCase {
|
||||
|
||||
// Constructor invocation
|
||||
|
||||
// public void testPrimitiveTypeArrayConstructors() {
|
||||
// evaluate("new int[]{1,2,3,4}.count()", 4, Integer.class);
|
||||
// evaluate("new boolean[]{true,false,true}.count()", 3, Integer.class);
|
||||
// evaluate("new char[]{'a','b','c'}.count()", 3, Integer.class);
|
||||
// evaluate("new long[]{1,2,3,4,5}.count()", 5, Integer.class);
|
||||
// evaluate("new short[]{2,3,4,5,6}.count()", 5, Integer.class);
|
||||
// evaluate("new double[]{1d,2d,3d,4d}.count()", 4, Integer.class);
|
||||
// evaluate("new float[]{1f,2f,3f,4f}.count()", 4, Integer.class);
|
||||
// evaluate("new byte[]{1,2,3,4}.count()", 4, Integer.class);
|
||||
// }
|
||||
|
||||
// public void testPrimitiveTypeArrayConstructorsElements() {
|
||||
// evaluate("new int[]{1,2,3,4}[0]", 1, Integer.class);
|
||||
// evaluate("new boolean[]{true,false,true}[0]", true, Boolean.class);
|
||||
// evaluate("new char[]{'a','b','c'}[0]", 'a', Character.class);
|
||||
// evaluate("new long[]{1,2,3,4,5}[0]", 1L, Long.class);
|
||||
// evaluate("new short[]{2,3,4,5,6}[0]", (short) 2, Short.class);
|
||||
// evaluate("new double[]{1d,2d,3d,4d}[0]", (double) 1, Double.class);
|
||||
// evaluate("new float[]{1f,2f,3f,4f}[0]", (float) 1, Float.class);
|
||||
// evaluate("new byte[]{1,2,3,4}[0]", (byte) 1, Byte.class);
|
||||
// }
|
||||
|
||||
// public void testErrorCases() {
|
||||
// evaluateAndCheckError("new char[7]{'a','c','d','e'}", SpelMessages.INITIALIZER_LENGTH_INCORRECT);
|
||||
// evaluateAndCheckError("new char[3]{'a','c','d','e'}", SpelMessages.INITIALIZER_LENGTH_INCORRECT);
|
||||
// evaluateAndCheckError("new char[2]{'hello','world'}", SpelMessages.TYPE_CONVERSION_ERROR);
|
||||
// evaluateAndCheckError("new String('a','c','d')", SpelMessages.CONSTRUCTOR_NOT_FOUND);
|
||||
// }
|
||||
|
||||
// public void testTypeArrayConstructors() {
|
||||
// evaluate("new String[]{'a','b','c','d'}[1]", "b", String.class);
|
||||
// evaluateAndCheckError("new String[]{'a','b','c','d'}.size()", SpelMessages.METHOD_NOT_FOUND, 30, "size()",
|
||||
// "java.lang.String[]");
|
||||
// evaluateAndCheckError("new String[]{'a','b','c','d'}.juggernaut", SpelMessages.PROPERTY_OR_FIELD_NOT_FOUND, 30,
|
||||
// "juggernaut", "java.lang.String[]");
|
||||
// evaluate("new String[]{'a','b','c','d'}.length", 4, Integer.class);
|
||||
// }
|
||||
|
||||
// public void testMultiDimensionalArrays() {
|
||||
// evaluate(
|
||||
// "new String[3,4]",
|
||||
// "[Ljava.lang.String;[3]{java.lang.String[4]{null,null,null,null},java.lang.String[4]{null,null,null,null},java.lang.String[4]{null,null,null,null}}"
|
||||
// ,
|
||||
// new String[3][4].getClass());
|
||||
// }
|
||||
|
||||
|
||||
// evaluate("new String(new char[]{'h','e','l','l','o'})", "hello", String.class);
|
||||
|
||||
|
||||
|
||||
// public void testRelOperatorsIn01() {
|
||||
// evaluate("3 in {1,2,3,4,5}", "true", Boolean.class);
|
||||
// }
|
||||
|
||||
// public void testRelOperatorsIn02() {
|
||||
// evaluate("name in {null, \"Nikola Tesla\"}", "true", Boolean.class);
|
||||
// evaluate("name in {null, \"Anonymous\"}", "false", Boolean.class);
|
||||
// }
|
||||
//
|
||||
public void testRelOperatorsBetween01() {
|
||||
evaluate("1 between listOneFive", "true", Boolean.class);
|
||||
// evaluate("1 between {1, 5}", "true", Boolean.class); // no inline list building at the moment
|
||||
}
|
||||
//
|
||||
// public void testRelOperatorsBetween02() {
|
||||
// evaluate("'efg' between {'abc', 'xyz'}", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
public void testRelOperatorsBetweenErrors01() {
|
||||
evaluateAndCheckError("1 between T(String)", SpelMessages.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST, 12);
|
||||
}
|
||||
//
|
||||
// public void testRelOperatorsBetweenErrors02() {
|
||||
// evaluateAndCheckError("'abc' between {5,7}", SpelMessages.NOT_COMPARABLE, 6);
|
||||
// }
|
||||
public void testRelOperatorsBetweenErrors03() {
|
||||
evaluateAndCheckError("1 between listOfNumbersUpToTen", SpelMessages.BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST, 10);
|
||||
}
|
||||
|
||||
// Lambda calculations
|
||||
|
||||
//
|
||||
// public void testLambda02() {
|
||||
// evaluate("(#max={|x,y| $x > $y ? $x : $y };true)", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaMax() {
|
||||
// evaluate("(#max = {|x,y| $x > $y ? $x : $y }; #max(5,25))", "25", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaFactorial01() {
|
||||
// evaluate("(#fact = {|n| $n <= 1 ? 1 : $n * #fact($n-1) }; #fact(5))", "120", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaFactorial02() {
|
||||
// evaluate("(#fact = {|n| $n <= 1 ? 1 : #fact($n-1) * $n }; #fact(5))", "120", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaAlphabet01() {
|
||||
// evaluate("(#alpha = {|l,s| $l>'z'?$s:#alpha($l+1,$s+$l)};#alphabet={||#alpha('a','')}; #alphabet())",
|
||||
// "abcdefghijklmnopqrstuvwxyz", String.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaAlphabet02() {
|
||||
// evaluate("(#alphabet = {|l,s| $l>'z'?$s:#alphabet($l+1,$s+$l)};#alphabet('a',''))",
|
||||
// "abcdefghijklmnopqrstuvwxyz", String.class);
|
||||
// }
|
||||
//
|
||||
// public void testLambdaDelegation01() {
|
||||
// evaluate("(#sqrt={|n| T(Math).sqrt($n)};#delegate={|f,n| $f($n)};#delegate(#sqrt,4))", "2.0", Double.class);
|
||||
// }
|
||||
//
|
||||
// public void testVariableReferences() {
|
||||
// evaluate("(#answer=42;#answer)", "42", Integer.class, true);
|
||||
// evaluate("($answer=42;$answer)", "42", Integer.class, true);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public void testRelOperatorsIs02() {
|
||||
// evaluate("{1, 2, 3, 4, 5} instanceof T(List)", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
// public void testRelOperatorsIs03() {
|
||||
// evaluate("{1, 2, 3, 4, 5} instanceof T(List)", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
// inline list creation
|
||||
// public void testInlineListCreation01() {
|
||||
// evaluate("{1, 2, 3, 4, 5}", "[1, 2, 3, 4, 5]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testInlineListCreation02() {
|
||||
// evaluate("{'abc', 'xyz'}", "[abc, xyz]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// // inline map creation
|
||||
// public void testInlineMapCreation01() {
|
||||
// evaluate("#{'key1':'Value 1', 'today':'Monday'}", "{key1=Value 1, today=Monday}", HashMap.class);
|
||||
// }
|
||||
//
|
||||
// public void testInlineMapCreation02() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}.size()", 3, Integer.class);// "{2=February, 1=January,
|
||||
// // 3=March}", HashMap.class);
|
||||
// }
|
||||
//
|
||||
// public void testInlineMapCreation03() {
|
||||
// evaluate("#{'key1':'Value 1', 'today':'Monday'}['key1']", "Value 1", String.class);
|
||||
// }
|
||||
//
|
||||
// public void testInlineMapCreation04() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}[3]", "March", String.class);
|
||||
// }
|
||||
//
|
||||
// public void testInlineMapCreation05() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}.get(2)", "February", String.class);
|
||||
// }
|
||||
//
|
||||
// // set construction
|
||||
// public void testSetConstruction01() {
|
||||
// evaluate("new HashSet().addAll({'a','b','c'})", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
// public void testConstructorInvocation02() {
|
||||
// evaluate("new String[3]", "java.lang.String[3]{null,null,null}", String[].class);
|
||||
// }
|
||||
//
|
||||
// public void testConstructorInvocation03() {
|
||||
// evaluateAndCheckError("new String[]", SpelMessages.NO_SIZE_OR_INITIALIZER_FOR_ARRAY_CONSTRUCTION, 4);
|
||||
// }
|
||||
//
|
||||
// public void testConstructorInvocation04() {
|
||||
// evaluateAndCheckError("new String[3]{'abc',3,'def'}", SpelMessages.INCORRECT_ELEMENT_TYPE_FOR_ARRAY, 4);
|
||||
// }
|
||||
// // array construction
|
||||
// public void testArrayConstruction01() {
|
||||
// evaluate("new int[] {1, 2, 3, 4, 5}", "int[5]{1,2,3,4,5}", int[].class);
|
||||
// }
|
||||
// public void testArrayConstruction02() {
|
||||
// evaluate("new String[] {'abc', 'xyz'}", "java.lang.String[2]{abc,xyz}", String[].class);
|
||||
// }
|
||||
|
||||
// collection processors
|
||||
// from spring.net: count,sum,max,min,average,sort,orderBy,distinct,nonNull
|
||||
// public void testProcessorsCount01() {
|
||||
// evaluate("new String[] {'abc','def','xyz'}.count()", "3", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsCount02() {
|
||||
// evaluate("new int[] {1,2,3}.count()", "3", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsMax01() {
|
||||
// evaluate("new int[] {1,2,3}.max()", "3", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsMin01() {
|
||||
// evaluate("new int[] {1,2,3}.min()", "1", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsKeys01() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}.keySet().sort()", "[1, 2, 3]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsValues01() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}.values().sort()", "[February, January, March]",
|
||||
// ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsAverage01() {
|
||||
// evaluate("new int[] {1,2,3}.average()", "2", Integer.class);
|
||||
// }
|
||||
//
|
||||
// public void testProcessorsSort01() {
|
||||
// evaluate("new int[] {3,2,1}.sort()", "int[3]{1,2,3}", int[].class);
|
||||
// }
|
||||
//
|
||||
// public void testCollectionProcessorsNonNull01() {
|
||||
// evaluate("{'a','b',null,'d',null}.nonnull()", "[a, b, d]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testCollectionProcessorsDistinct01() {
|
||||
// evaluate("{'a','b','a','d','e'}.distinct()", "[a, b, d, e]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testProjection03() {
|
||||
// evaluate("{1,2,3,4,5,6,7,8,9,10}.!{#this>5}",
|
||||
// "[false, false, false, false, false, true, true, true, true, true]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testProjection04() {
|
||||
// evaluate("{1,2,3,4,5,6,7,8,9,10}.!{$index>5?'y':'n'}", "[n, n, n, n, n, n, y, y, y, y]", ArrayList.class);
|
||||
// }
|
||||
// Bean references
|
||||
// public void testReferences01() {
|
||||
// evaluate("@(apple).name", "Apple", String.class, true);
|
||||
// }
|
||||
//
|
||||
// public void testReferences02() {
|
||||
// evaluate("@(fruits:banana).name", "Banana", String.class, true);
|
||||
// }
|
||||
//
|
||||
// public void testReferences03() {
|
||||
// evaluate("@(a.b.c)", null, null);
|
||||
// } // null - no context, a.b.c treated as name
|
||||
//
|
||||
// public void testReferences05() {
|
||||
// evaluate("@(a/b/c:orange).name", "Orange", String.class, true);
|
||||
// }
|
||||
//
|
||||
// public void testReferences06() {
|
||||
// evaluate("@(apple).color.getRGB() == T(java.awt.Color).green.getRGB()", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
// public void testReferences07() {
|
||||
// evaluate("@(apple).color.getRGB().equals(T(java.awt.Color).green.getRGB())", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
// value is not public, it is accessed through getRGB()
|
||||
// public void testStaticRef01() {
|
||||
// evaluate("T(Color).green.value!=0", "true", Boolean.class);
|
||||
// }
|
||||
// Indexer
|
||||
// public void testCutProcessor01() {
|
||||
// evaluate("{1,2,3,4,5}.cut(1,3)", "[2, 3, 4]", ArrayList.class);
|
||||
// }
|
||||
//
|
||||
// public void testCutProcessor02() {
|
||||
// evaluate("{1,2,3,4,5}.cut(3,1)", "[4, 3, 2]", ArrayList.class);
|
||||
// }
|
||||
// Ternary operator
|
||||
// public void testTernaryOperator01() {
|
||||
// evaluate("{1}.#isEven(#this[0]) == 'y'?'it is even':'it is odd'", "it is odd", String.class);
|
||||
// }
|
||||
//
|
||||
// public void testTernaryOperator02() {
|
||||
// evaluate("{2}.#isEven(#this[0]) == 'y'?'it is even':'it is odd'", "it is even", String.class);
|
||||
// }
|
||||
// public void testSelectionUsingIndex() {
|
||||
// evaluate("{1,2,3,4,5,6,7,8,9,10}.?{$index > 5 }", "[7, 8, 9, 10]", ArrayList.class);
|
||||
// }
|
||||
//public void testSelection01() {
|
||||
// inline list creation not supported:
|
||||
// evaluate("{1,2,3,4,5,6,7,8,9,10}.?{#isEven(#this) == 'y'}", "[2, 4, 6, 8, 10]", ArrayList.class);
|
||||
//}
|
||||
|
||||
// projection and selection
|
||||
public void testProjection01() {
|
||||
evaluate("listOfNumbersUpToTen.!{#this<5?'y':'n'}","[y, y, y, y, n, n, n, n, n, n]",ArrayList.class);
|
||||
// inline list creation not supported at the moment
|
||||
// evaluate("{1,2,3,4,5,6,7,8,9,10}.!{#isEven(#this)}", "[n, y, n, y, n, y, n, y, n, y]", ArrayList.class);
|
||||
}
|
||||
|
||||
public void testProjection02() {
|
||||
// inline map creation not supported at the moment
|
||||
// evaluate("#{'a':'y','b':'n','c':'y'}.!{value=='y'?key:null}.nonnull().sort()", "[a, c]", ArrayList.class);
|
||||
evaluate("mapOfNumbersUpToTen.!{key>5?value:null}", "[null, null, null, null, null, six, seven, eight, nine, ten]", ArrayList.class);
|
||||
}
|
||||
|
||||
public void testProjection05() {
|
||||
evaluateAndCheckError("'abc'.!{true}", SpelMessages.PROJECTION_NOT_SUPPORTED_ON_TYPE);
|
||||
}
|
||||
|
||||
public void testProjection06() throws Exception {
|
||||
SpelExpression expr = (SpelExpression)parser.parseExpression("'abc'.!{true}");
|
||||
assertEquals("'abc'.!{true}",expr.toStringAST());
|
||||
assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
}
|
||||
|
||||
public void testSelection02() {
|
||||
evaluate("testMap.keySet().?{#this matches '.*o.*'}", "[monday]", ArrayList.class);
|
||||
evaluate("testMap.keySet().?{#this matches '.*r.*'}.contains('saturday')", "true", Boolean.class);
|
||||
evaluate("testMap.keySet().?{#this matches '.*r.*'}.size()", "3", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelectionError_NonBooleanSelectionCriteria() {
|
||||
evaluateAndCheckError("listOfNumbersUpToTen.?{'nonboolean'}",
|
||||
SpelMessages.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
|
||||
}
|
||||
|
||||
public void testSelection03() {
|
||||
evaluate("mapOfNumbersUpToTen.?{key>5}.size()", "5", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelection04() {
|
||||
evaluateAndCheckError("mapOfNumbersUpToTen.?{'hello'}.size()",SpelMessages.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
|
||||
}
|
||||
|
||||
public void testSelectionFirst01() {
|
||||
evaluate("listOfNumbersUpToTen.^{#isEven(#this) == 'y'}", "2", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelectionFirst02() {
|
||||
evaluate("mapOfNumbersUpToTen.^{key>5}.size()", "1", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelectionLast01() {
|
||||
evaluate("listOfNumbersUpToTen.${#isEven(#this) == 'y'}", "10", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelectionLast02() {
|
||||
evaluate("mapOfNumbersUpToTen.${key>5}.size()", "1", Integer.class);
|
||||
}
|
||||
|
||||
public void testSelectionAST() throws Exception {
|
||||
SpelExpression expr = (SpelExpression)parser.parseExpression("'abc'.^{true}");
|
||||
assertEquals("'abc'.^{true}",expr.toStringAST());
|
||||
assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
expr = (SpelExpression)parser.parseExpression("'abc'.?{true}");
|
||||
assertEquals("'abc'.?{true}",expr.toStringAST());
|
||||
assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
expr = (SpelExpression)parser.parseExpression("'abc'.${true}");
|
||||
assertEquals("'abc'.${true}",expr.toStringAST());
|
||||
assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -26,6 +26,7 @@ import org.springframework.expression.ParseException;
|
|||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
import org.springframework.expression.spel.testresources.PlaceOfBirth;
|
||||
|
||||
|
||||
/**
|
||||
* Tests set value expressions.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2004-2008 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.spel.support.StandardTypeLocator;
|
||||
|
||||
/**
|
||||
* Unit tests for type comparison
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class StandardTypeLocatorTests extends TestCase {
|
||||
|
||||
public void testPrimitives() throws EvaluationException {
|
||||
StandardTypeLocator locator = new StandardTypeLocator();
|
||||
assertEquals(Integer.class,locator.findType("java.lang.Integer"));
|
||||
assertEquals(String.class,locator.findType("java.lang.String"));
|
||||
|
||||
List<String> prefixes = locator.getImportPrefixes();
|
||||
assertEquals(2,prefixes.size());
|
||||
assertTrue(prefixes.contains("java.lang"));
|
||||
assertTrue(prefixes.contains("java.util"));
|
||||
|
||||
assertEquals(Boolean.class,locator.findType("Boolean"));
|
||||
assertEquals(java.util.List.class,locator.findType("List"));
|
||||
|
||||
try {
|
||||
locator.findType("URL");
|
||||
fail("Should have failed");
|
||||
} catch (EvaluationException ee) {
|
||||
SpelException sEx = (SpelException)ee;
|
||||
assertEquals(SpelMessages.TYPE_NOT_FOUND,sEx.getMessageUnformatted());
|
||||
}
|
||||
locator.registerImport("java.net");
|
||||
assertEquals(java.net.URL.class,locator.findType("URL"));
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@ package org.springframework.expression.spel;
|
|||
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.ParseException;
|
||||
import org.springframework.expression.ParserContext;
|
||||
import org.springframework.expression.spel.antlr.SpelAntlrExpressionParser;
|
||||
import org.springframework.expression.spel.support.StandardEvaluationContext;
|
||||
|
|
@ -63,6 +64,21 @@ public class TemplateExpressionParsingTests extends ExpressionTestCase {
|
|||
assertEquals("The quick brown fox jumped over the lazy dog", o.toString());
|
||||
}
|
||||
|
||||
public void testParsingSimpleTemplateExpression04() throws Exception {
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
Expression expr = parser.parseExpression("${'hello'} world", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
Object o = expr.getValue();
|
||||
assertEquals("hello world", o.toString());
|
||||
|
||||
expr = parser.parseExpression("", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
o = expr.getValue();
|
||||
assertEquals("", o.toString());
|
||||
|
||||
expr = parser.parseExpression("abc", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
o = expr.getValue();
|
||||
assertEquals("abc", o.toString());
|
||||
}
|
||||
|
||||
public void testCompositeStringExpression() throws Exception {
|
||||
SpelAntlrExpressionParser parser = new SpelAntlrExpressionParser();
|
||||
Expression ex = parser.parseExpression("hello ${'world'}", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
|
|
@ -74,6 +90,36 @@ public class TemplateExpressionParsingTests extends ExpressionTestCase {
|
|||
assertEquals("hello ${'world'}", ex.getExpressionString());
|
||||
assertFalse(ex.isWritable(new StandardEvaluationContext()));
|
||||
}
|
||||
|
||||
public void testParsingNormalExpressionThroughTemplateParser() throws Exception {
|
||||
Expression expr = parser.parseExpression("1+2+3");
|
||||
assertEquals(6,expr.getValue());
|
||||
expr = parser.parseExpression("1+2+3",null);
|
||||
assertEquals(6,expr.getValue());
|
||||
}
|
||||
|
||||
public void testErrorCases() throws Exception {
|
||||
try {
|
||||
parser.parseExpression("hello ${'world'", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
fail("Should have failed");
|
||||
} catch (ParseException pe) {
|
||||
assertEquals("No ending suffix '}' for expression starting at character 6: ${'world'",pe.getMessage());
|
||||
assertEquals("hello ${'world'",pe.getExpressionString());
|
||||
}
|
||||
try {
|
||||
parser.parseExpression("hello ${'wibble'${'world'}", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
fail("Should have failed");
|
||||
} catch (ParseException pe) {
|
||||
assertEquals("No ending suffix '}' for expression starting at character 6: ${'wibble'${'world'}",pe.getMessage());
|
||||
}
|
||||
try {
|
||||
parser.parseExpression("hello ${} world", DEFAULT_TEMPLATE_PARSER_CONTEXT);
|
||||
fail("Should have failed");
|
||||
} catch (ParseException pe) {
|
||||
assertEquals("No expression defined within delimiter '${}' at character 6",pe.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void checkString(String expectedString, Object value) {
|
||||
if (!(value instanceof String)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue