More test coverage for the expression AST
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@927 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
2bd40484cf
commit
7cc791ae9e
|
|
@ -43,19 +43,14 @@ public class OperatorGreaterThan extends Operator {
|
||||||
Object left = getLeftOperand().getValueInternal(state).getValue();
|
Object left = getLeftOperand().getValueInternal(state).getValue();
|
||||||
Object right = getRightOperand().getValueInternal(state).getValue();
|
Object right = getRightOperand().getValueInternal(state).getValue();
|
||||||
if (left instanceof Number && right instanceof Number) {
|
if (left instanceof Number && right instanceof Number) {
|
||||||
Number op1 = (Number) left;
|
Number leftNumber = (Number) left;
|
||||||
Number op2 = (Number) right;
|
Number rightNumber = (Number) right;
|
||||||
if (op1 instanceof Double || op2 instanceof Double) {
|
if (leftNumber instanceof Double || rightNumber instanceof Double) {
|
||||||
return BooleanTypedValue.forValue(op1.doubleValue() > op2.doubleValue());
|
return BooleanTypedValue.forValue(leftNumber.doubleValue() > rightNumber.doubleValue());
|
||||||
}
|
} else if (leftNumber instanceof Long || rightNumber instanceof Long) {
|
||||||
else if (op1 instanceof Float || op2 instanceof Float) {
|
return BooleanTypedValue.forValue(leftNumber.longValue() > rightNumber.longValue());
|
||||||
return BooleanTypedValue.forValue(op1.floatValue() > op2.floatValue());
|
} else {
|
||||||
}
|
return BooleanTypedValue.forValue(leftNumber.intValue() > rightNumber.intValue());
|
||||||
else if (op1 instanceof Long || op2 instanceof Long) {
|
|
||||||
return BooleanTypedValue.forValue(op1.longValue() > op2.longValue());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return BooleanTypedValue.forValue(op1.intValue() > op2.intValue());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return BooleanTypedValue.forValue(state.getTypeComparator().compare(left, right) > 0);
|
return BooleanTypedValue.forValue(state.getTypeComparator().compare(left, right) > 0);
|
||||||
|
|
|
||||||
|
|
@ -42,20 +42,16 @@ public class OperatorLessThan extends Operator {
|
||||||
public BooleanTypedValue getValueInternal(ExpressionState state) throws EvaluationException {
|
public BooleanTypedValue getValueInternal(ExpressionState state) throws EvaluationException {
|
||||||
Object left = getLeftOperand().getValueInternal(state).getValue();
|
Object left = getLeftOperand().getValueInternal(state).getValue();
|
||||||
Object right = getRightOperand().getValueInternal(state).getValue();
|
Object right = getRightOperand().getValueInternal(state).getValue();
|
||||||
|
// TODO could leave all of these to the comparator - just seems quicker to do some here
|
||||||
if (left instanceof Number && right instanceof Number) {
|
if (left instanceof Number && right instanceof Number) {
|
||||||
Number op1 = (Number) left;
|
Number leftNumber = (Number) left;
|
||||||
Number op2 = (Number) right;
|
Number rightNumber = (Number) right;
|
||||||
if (op1 instanceof Double || op2 instanceof Double) {
|
if (leftNumber instanceof Double || rightNumber instanceof Double) {
|
||||||
return BooleanTypedValue.forValue(op1.doubleValue() < op2.doubleValue());
|
return BooleanTypedValue.forValue(leftNumber.doubleValue() < rightNumber.doubleValue());
|
||||||
}
|
} else if (leftNumber instanceof Long || rightNumber instanceof Long) {
|
||||||
else if (op1 instanceof Float || op2 instanceof Float) {
|
return BooleanTypedValue.forValue(leftNumber.longValue() < rightNumber.longValue());
|
||||||
return BooleanTypedValue.forValue(op1.floatValue() < op2.floatValue());
|
} else {
|
||||||
}
|
return BooleanTypedValue.forValue(leftNumber.intValue() < rightNumber.intValue());
|
||||||
else if (op1 instanceof Long || op2 instanceof Long) {
|
|
||||||
return BooleanTypedValue.forValue(op1.longValue() < op2.longValue());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return BooleanTypedValue.forValue(op1.intValue() < op2.intValue());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return BooleanTypedValue.forValue(state.getTypeComparator().compare(left, right) < 0);
|
return BooleanTypedValue.forValue(state.getTypeComparator().compare(left, right) < 0);
|
||||||
|
|
|
||||||
|
|
@ -38,19 +38,14 @@ public class OperatorLessThanOrEqual extends Operator {
|
||||||
Object left = getLeftOperand().getValueInternal(state).getValue();
|
Object left = getLeftOperand().getValueInternal(state).getValue();
|
||||||
Object right = getRightOperand().getValueInternal(state).getValue();
|
Object right = getRightOperand().getValueInternal(state).getValue();
|
||||||
if (left instanceof Number && right instanceof Number) {
|
if (left instanceof Number && right instanceof Number) {
|
||||||
Number op1 = (Number) left;
|
Number leftNumber = (Number) left;
|
||||||
Number op2 = (Number) right;
|
Number rightNumber = (Number) right;
|
||||||
if (op1 instanceof Double || op2 instanceof Double) {
|
if (leftNumber instanceof Double || rightNumber instanceof Double) {
|
||||||
return BooleanTypedValue.forValue(op1.doubleValue() <= op2.doubleValue());
|
return BooleanTypedValue.forValue(leftNumber.doubleValue() <= rightNumber.doubleValue());
|
||||||
}
|
} else if (leftNumber instanceof Long || rightNumber instanceof Long) {
|
||||||
else if (op1 instanceof Float || op2 instanceof Float) {
|
return BooleanTypedValue.forValue(leftNumber.longValue() <= rightNumber.longValue());
|
||||||
return BooleanTypedValue.forValue(op1.floatValue() <= op2.floatValue());
|
} else {
|
||||||
}
|
return BooleanTypedValue.forValue(leftNumber.intValue() <= rightNumber.intValue());
|
||||||
else if (op1 instanceof Long || op2 instanceof Long) {
|
|
||||||
return BooleanTypedValue.forValue(op1.longValue() <= op2.longValue());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return BooleanTypedValue.forValue(op1.intValue() <= op2.intValue());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return BooleanTypedValue.forValue( state.getTypeComparator().compare(left, right) <= 0);
|
return BooleanTypedValue.forValue( state.getTypeComparator().compare(left, right) <= 0);
|
||||||
|
|
|
||||||
|
|
@ -44,17 +44,10 @@ public class Ternary extends SpelNodeImpl {
|
||||||
@Override
|
@Override
|
||||||
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
|
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
|
||||||
Boolean value = getChild(0).getValue(state, Boolean.class);
|
Boolean value = getChild(0).getValue(state, Boolean.class);
|
||||||
try {
|
if (value.booleanValue()) {
|
||||||
if (Boolean.TRUE.equals(value)) {
|
return getChild(1).getValueInternal(state);
|
||||||
return getChild(1).getValueInternal(state);
|
} else {
|
||||||
}
|
return getChild(2).getValueInternal(state);
|
||||||
else {
|
|
||||||
return getChild(2).getValueInternal(state);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (SpelException ex) {
|
|
||||||
ex.setPosition(getChild(0).getCharPositionInLine());
|
|
||||||
throw ex;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.expression.spel;
|
package org.springframework.expression.spel;
|
||||||
|
|
||||||
|
import org.springframework.expression.Expression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the evaluation of real expressions in a real context.
|
* Tests the evaluation of real expressions in a real context.
|
||||||
*
|
*
|
||||||
|
|
@ -323,10 +325,23 @@ public class EvaluationTests extends ExpressionTestCase {
|
||||||
// evaluate("{2}.#isEven(#this[0]) == 'y'?'it is even':'it is odd'", "it is even", String.class);
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testTernaryOperator02() {
|
||||||
|
evaluate("'abc'=='abc'?1:2",1,Integer.class);
|
||||||
|
}
|
||||||
|
|
||||||
public void testTernaryOperator03() {
|
public void testTernaryOperator03() {
|
||||||
evaluateAndCheckError("'hello'?1:2", SpelMessages.TYPE_CONVERSION_ERROR); // cannot convert String to boolean
|
evaluateAndCheckError("'hello'?1:2", SpelMessages.TYPE_CONVERSION_ERROR); // cannot convert String to boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testTernaryOperator04() throws Exception {
|
||||||
|
Expression expr = parser.parseExpression("1>2?3:4");
|
||||||
|
assertFalse(expr.isWritable(eContext));
|
||||||
|
}
|
||||||
|
|
||||||
// Indexer
|
// Indexer
|
||||||
// public void testCutProcessor01() {
|
// public void testCutProcessor01() {
|
||||||
// evaluate("{1,2,3,4,5}.cut(1,3)", "[2, 3, 4]", ArrayList.class);
|
// evaluate("{1,2,3,4,5}.cut(1,3)", "[2, 3, 4]", ArrayList.class);
|
||||||
|
|
|
||||||
|
|
@ -36,12 +36,27 @@ public class OperatorTests extends ExpressionTestCase {
|
||||||
public void testLessThan() {
|
public void testLessThan() {
|
||||||
evaluate("3 < 5", true, Boolean.class);
|
evaluate("3 < 5", true, Boolean.class);
|
||||||
evaluate("5 < 3", false, Boolean.class);
|
evaluate("5 < 3", false, Boolean.class);
|
||||||
|
evaluate("3L < 5L", true, Boolean.class);
|
||||||
|
evaluate("5L < 3L", false, Boolean.class);
|
||||||
|
evaluate("3.0d < 5.0d", true, Boolean.class);
|
||||||
|
evaluate("5.0d < 3.0d", false, Boolean.class);
|
||||||
|
evaluate("'abc' < 'def'",true,Boolean.class);
|
||||||
|
evaluate("'def' < 'abc'",false,Boolean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testLessThanOrEqual() {
|
public void testLessThanOrEqual() {
|
||||||
evaluate("3 <= 5", true, Boolean.class);
|
evaluate("3 <= 5", true, Boolean.class);
|
||||||
evaluate("5 <= 3", false, Boolean.class);
|
evaluate("5 <= 3", false, Boolean.class);
|
||||||
evaluate("6 <= 6", true, Boolean.class);
|
evaluate("6 <= 6", true, Boolean.class);
|
||||||
|
evaluate("3L <= 5L", true, Boolean.class);
|
||||||
|
evaluate("5L <= 3L", false, Boolean.class);
|
||||||
|
evaluate("5L <= 5L", true, Boolean.class);
|
||||||
|
evaluate("3.0d < 5.0d", true, Boolean.class);
|
||||||
|
evaluate("5.0d < 3.0d", false, Boolean.class);
|
||||||
|
evaluate("5.0d <= 5.0d", true, Boolean.class);
|
||||||
|
evaluate("'abc' <= 'def'",true,Boolean.class);
|
||||||
|
evaluate("'def' <= 'abc'",false,Boolean.class);
|
||||||
|
evaluate("'abc' <= 'abc'",true,Boolean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testEqual() {
|
public void testEqual() {
|
||||||
|
|
@ -64,7 +79,13 @@ public class OperatorTests extends ExpressionTestCase {
|
||||||
|
|
||||||
public void testGreaterThan() {
|
public void testGreaterThan() {
|
||||||
evaluate("3 > 5", false, Boolean.class);
|
evaluate("3 > 5", false, Boolean.class);
|
||||||
evaluate("5 > 3", true, Boolean.class);
|
evaluate("5 > 3", true, Boolean.class);
|
||||||
|
evaluate("3L > 5L", false, Boolean.class);
|
||||||
|
evaluate("5L > 3L", true, Boolean.class);
|
||||||
|
evaluate("3.0d > 5.0d", false, Boolean.class);
|
||||||
|
evaluate("5.0d > 3.0d", true, Boolean.class);
|
||||||
|
evaluate("'abc' > 'def'",false,Boolean.class);
|
||||||
|
evaluate("'def' > 'abc'",true,Boolean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMultiplyStringInt() {
|
public void testMultiplyStringInt() {
|
||||||
|
|
@ -136,6 +157,18 @@ public class OperatorTests extends ExpressionTestCase {
|
||||||
|
|
||||||
node = getOperatorNode((SpelExpression)parser.parseExpression("3/3"));
|
node = getOperatorNode((SpelExpression)parser.parseExpression("3/3"));
|
||||||
assertEquals("/",node.getOperatorName());
|
assertEquals("/",node.getOperatorName());
|
||||||
|
|
||||||
|
node = getOperatorNode((SpelExpression)parser.parseExpression("3+3"));
|
||||||
|
assertEquals("+",node.getOperatorName());
|
||||||
|
|
||||||
|
node = getOperatorNode((SpelExpression)parser.parseExpression("3-3"));
|
||||||
|
assertEquals("-",node.getOperatorName());
|
||||||
|
|
||||||
|
node = getOperatorNode((SpelExpression)parser.parseExpression("3<4"));
|
||||||
|
assertEquals("<",node.getOperatorName());
|
||||||
|
|
||||||
|
node = getOperatorNode((SpelExpression)parser.parseExpression("3<=4"));
|
||||||
|
assertEquals("<=",node.getOperatorName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testMixedOperands_FloatsAndDoubles() {
|
public void testMixedOperands_FloatsAndDoubles() {
|
||||||
|
|
|
||||||
|
|
@ -346,7 +346,13 @@ public class ParsingTests extends TestCase {
|
||||||
parseCheck("#var1='value1'");
|
parseCheck("#var1='value1'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ternary operator
|
// ternary operator
|
||||||
|
|
||||||
|
public void testTernaryOperator01() {
|
||||||
|
parseCheck("1>2?3:4","(1 > 2) ? 3 : 4");
|
||||||
|
}
|
||||||
|
|
||||||
// public void testTernaryOperator01() {
|
// public void testTernaryOperator01() {
|
||||||
// parseCheck("{1}.#isEven(#this) == 'y'?'it is even':'it is odd'",
|
// parseCheck("{1}.#isEven(#this) == 'y'?'it is even':'it is odd'",
|
||||||
// "({1}.#isEven(#this) == 'y') ? 'it is even' : 'it is odd'");
|
// "({1}.#isEven(#this) == 'y') ? 'it is even' : 'it is odd'");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue