mirror of
https://github.com/spring-projects/spring-framework
synced 2026-06-08 17:33:33 +00:00
Add SpEL support for increment/decrement operators
With this commit the Spring Expression Language now supports increment (++) and decrement (--) operators. These can be used as either prefix or postfix operators. For example: 'somearray[index++]' and 'somearray[--index]' are valid. In order to support this there are serious changes to the evaluation process for expressions. The concept of a value reference for an expression component has been introduced. Value references can be passed around and at any time the actual value can be retrieved (via a get) or set (where applicable). This was needed to avoid double evaluation of expression components. For example, in evaluating the expression 'somearray[index++]--' without a value reference SpEL would need to evaluate the 'somearray[index++]' component twice, once to get the value and then again to determine where to put the new value. If that component is evaluated twice, index would be double incremented. A value reference for 'somearray[index++]' avoids this problem. Many new tests have been introduced into the EvaluationTests to ensure not only that ++ and -- work but also that the introduction of value references across the all of SpEL has not caused regressions. Issue: SPR-9751
This commit is contained in:
committed by
Chris Beams
parent
33d37e8680
commit
f64325882d
+763
-1
@@ -27,6 +27,7 @@ import org.junit.Test;
|
||||
|
||||
import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.expression.AccessException;
|
||||
import org.springframework.expression.BeanResolver;
|
||||
import org.springframework.expression.EvaluationContext;
|
||||
import org.springframework.expression.EvaluationException;
|
||||
import org.springframework.expression.Expression;
|
||||
@@ -43,7 +44,7 @@ import org.springframework.expression.spel.testresources.TestPerson;
|
||||
|
||||
/**
|
||||
* Tests the evaluation of real expressions in a real context.
|
||||
*
|
||||
*
|
||||
* @author Andy Clement
|
||||
* @author Mark Fisher
|
||||
* @author Sam Brannen
|
||||
@@ -622,4 +623,765 @@ public class EvaluationTests extends ExpressionTestCase {
|
||||
|
||||
}
|
||||
|
||||
// increment/decrement operators - SPR-9751
|
||||
|
||||
static class Spr9751 {
|
||||
public String type = "hello";
|
||||
public double ddd = 2.0d;
|
||||
public float fff = 3.0f;
|
||||
public long lll = 66666L;
|
||||
public int iii = 42;
|
||||
public short sss = (short)15;
|
||||
public Spr9751_2 foo = new Spr9751_2();
|
||||
|
||||
public void m() {}
|
||||
|
||||
public int[] intArray = new int[]{1,2,3,4,5};
|
||||
public int index1 = 2;
|
||||
|
||||
public Integer[] integerArray;
|
||||
public int index2 = 2;
|
||||
|
||||
public List<String> listOfStrings;
|
||||
public int index3 = 0;
|
||||
|
||||
public Spr9751() {
|
||||
integerArray = new Integer[5];
|
||||
integerArray[0] = 1;
|
||||
integerArray[1] = 2;
|
||||
integerArray[2] = 3;
|
||||
integerArray[3] = 4;
|
||||
integerArray[4] = 5;
|
||||
listOfStrings = new ArrayList<String>();
|
||||
listOfStrings.add("abc");
|
||||
}
|
||||
|
||||
public static boolean isEven(int i) {
|
||||
return (i%2)==0;
|
||||
}
|
||||
}
|
||||
|
||||
static class Spr9751_2 {
|
||||
public int iii = 99;
|
||||
}
|
||||
|
||||
/**
|
||||
* This test is checking that with the changes for 9751 that the refactoring in Indexer is
|
||||
* coping correctly for references beyond collection boundaries.
|
||||
*/
|
||||
@Test
|
||||
public void collectionGrowingViaIndexer() {
|
||||
Spr9751 instance = new Spr9751();
|
||||
|
||||
// Add a new element to the list
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(instance);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = parser.parseExpression("listOfStrings[++index3]='def'");
|
||||
e.getValue(ctx);
|
||||
assertEquals(2,instance.listOfStrings.size());
|
||||
assertEquals("def",instance.listOfStrings.get(1));
|
||||
|
||||
// Check reference beyond end of collection
|
||||
ctx = new StandardEvaluationContext(instance);
|
||||
parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
e = parser.parseExpression("listOfStrings[0]");
|
||||
String value = e.getValue(ctx,String.class);
|
||||
assertEquals("abc",value);
|
||||
e = parser.parseExpression("listOfStrings[1]");
|
||||
value = e.getValue(ctx,String.class);
|
||||
assertEquals("def",value);
|
||||
e = parser.parseExpression("listOfStrings[2]");
|
||||
value = e.getValue(ctx,String.class);
|
||||
assertEquals("",value);
|
||||
|
||||
// Now turn off growing and reference off the end
|
||||
ctx = new StandardEvaluationContext(instance);
|
||||
parser = new SpelExpressionParser(new SpelParserConfiguration(false, false));
|
||||
e = parser.parseExpression("listOfStrings[3]");
|
||||
try {
|
||||
e.getValue(ctx,String.class);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.COLLECTION_INDEX_OUT_OF_BOUNDS,see.getMessageCode());
|
||||
}
|
||||
}
|
||||
|
||||
// For now I am making #this not assignable
|
||||
@Test
|
||||
public void increment01root() {
|
||||
Integer i = 42;
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(i);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = parser.parseExpression("#this++");
|
||||
assertEquals(42,i.intValue());
|
||||
try {
|
||||
e.getValue(ctx,Integer.class);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void increment02postfix() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = null;
|
||||
|
||||
// double
|
||||
e = parser.parseExpression("ddd++");
|
||||
assertEquals(2.0d,helper.ddd,0d);
|
||||
double return_ddd = e.getValue(ctx,Double.TYPE);
|
||||
assertEquals(2.0d,return_ddd,0d);
|
||||
assertEquals(3.0d,helper.ddd,0d);
|
||||
|
||||
// float
|
||||
e = parser.parseExpression("fff++");
|
||||
assertEquals(3.0f,helper.fff,0d);
|
||||
float return_fff = e.getValue(ctx,Float.TYPE);
|
||||
assertEquals(3.0f,return_fff,0d);
|
||||
assertEquals(4.0f,helper.fff,0d);
|
||||
|
||||
// long
|
||||
e = parser.parseExpression("lll++");
|
||||
assertEquals(66666L,helper.lll);
|
||||
long return_lll = e.getValue(ctx,Long.TYPE);
|
||||
assertEquals(66666L,return_lll);
|
||||
assertEquals(66667L,helper.lll);
|
||||
|
||||
// int
|
||||
e = parser.parseExpression("iii++");
|
||||
assertEquals(42,helper.iii);
|
||||
int return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(42,return_iii);
|
||||
assertEquals(43,helper.iii);
|
||||
return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(43,return_iii);
|
||||
assertEquals(44,helper.iii);
|
||||
|
||||
// short
|
||||
e = parser.parseExpression("sss++");
|
||||
assertEquals(15,helper.sss);
|
||||
short return_sss = e.getValue(ctx,Short.TYPE);
|
||||
assertEquals(15,return_sss);
|
||||
assertEquals(16,helper.sss);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void increment02prefix() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = null;
|
||||
|
||||
// double
|
||||
e = parser.parseExpression("++ddd");
|
||||
assertEquals(2.0d,helper.ddd,0d);
|
||||
double return_ddd = e.getValue(ctx,Double.TYPE);
|
||||
assertEquals(3.0d,return_ddd,0d);
|
||||
assertEquals(3.0d,helper.ddd,0d);
|
||||
|
||||
// float
|
||||
e = parser.parseExpression("++fff");
|
||||
assertEquals(3.0f,helper.fff,0d);
|
||||
float return_fff = e.getValue(ctx,Float.TYPE);
|
||||
assertEquals(4.0f,return_fff,0d);
|
||||
assertEquals(4.0f,helper.fff,0d);
|
||||
|
||||
// long
|
||||
e = parser.parseExpression("++lll");
|
||||
assertEquals(66666L,helper.lll);
|
||||
long return_lll = e.getValue(ctx,Long.TYPE);
|
||||
assertEquals(66667L,return_lll);
|
||||
assertEquals(66667L,helper.lll);
|
||||
|
||||
// int
|
||||
e = parser.parseExpression("++iii");
|
||||
assertEquals(42,helper.iii);
|
||||
int return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(43,return_iii);
|
||||
assertEquals(43,helper.iii);
|
||||
return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(44,return_iii);
|
||||
assertEquals(44,helper.iii);
|
||||
|
||||
// short
|
||||
e = parser.parseExpression("++sss");
|
||||
assertEquals(15,helper.sss);
|
||||
int return_sss = (Integer)e.getValue(ctx);
|
||||
assertEquals(16,return_sss);
|
||||
assertEquals(16,helper.sss);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void increment03() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = null;
|
||||
|
||||
e = parser.parseExpression("m()++");
|
||||
try {
|
||||
e.getValue(ctx,Double.TYPE);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.OPERAND_NOT_INCREMENTABLE,see.getMessageCode());
|
||||
}
|
||||
|
||||
e = parser.parseExpression("++m()");
|
||||
try {
|
||||
e.getValue(ctx,Double.TYPE);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.OPERAND_NOT_INCREMENTABLE,see.getMessageCode());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void increment04() {
|
||||
Integer i = 42;
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(i);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
try {
|
||||
Expression e = parser.parseExpression("++1");
|
||||
e.getValue(ctx,Integer.class);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
|
||||
}
|
||||
try {
|
||||
Expression e = parser.parseExpression("1++");
|
||||
e.getValue(ctx,Integer.class);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void decrement01root() {
|
||||
Integer i = 42;
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(i);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = parser.parseExpression("#this--");
|
||||
assertEquals(42,i.intValue());
|
||||
try {
|
||||
e.getValue(ctx,Integer.class);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decrement02postfix() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = null;
|
||||
|
||||
// double
|
||||
e = parser.parseExpression("ddd--");
|
||||
assertEquals(2.0d,helper.ddd,0d);
|
||||
double return_ddd = e.getValue(ctx,Double.TYPE);
|
||||
assertEquals(2.0d,return_ddd,0d);
|
||||
assertEquals(1.0d,helper.ddd,0d);
|
||||
|
||||
// float
|
||||
e = parser.parseExpression("fff--");
|
||||
assertEquals(3.0f,helper.fff,0d);
|
||||
float return_fff = e.getValue(ctx,Float.TYPE);
|
||||
assertEquals(3.0f,return_fff,0d);
|
||||
assertEquals(2.0f,helper.fff,0d);
|
||||
|
||||
// long
|
||||
e = parser.parseExpression("lll--");
|
||||
assertEquals(66666L,helper.lll);
|
||||
long return_lll = e.getValue(ctx,Long.TYPE);
|
||||
assertEquals(66666L,return_lll);
|
||||
assertEquals(66665L,helper.lll);
|
||||
|
||||
// int
|
||||
e = parser.parseExpression("iii--");
|
||||
assertEquals(42,helper.iii);
|
||||
int return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(42,return_iii);
|
||||
assertEquals(41,helper.iii);
|
||||
return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(41,return_iii);
|
||||
assertEquals(40,helper.iii);
|
||||
|
||||
// short
|
||||
e = parser.parseExpression("sss--");
|
||||
assertEquals(15,helper.sss);
|
||||
short return_sss = e.getValue(ctx,Short.TYPE);
|
||||
assertEquals(15,return_sss);
|
||||
assertEquals(14,helper.sss);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decrement02prefix() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = null;
|
||||
|
||||
// double
|
||||
e = parser.parseExpression("--ddd");
|
||||
assertEquals(2.0d,helper.ddd,0d);
|
||||
double return_ddd = e.getValue(ctx,Double.TYPE);
|
||||
assertEquals(1.0d,return_ddd,0d);
|
||||
assertEquals(1.0d,helper.ddd,0d);
|
||||
|
||||
// float
|
||||
e = parser.parseExpression("--fff");
|
||||
assertEquals(3.0f,helper.fff,0d);
|
||||
float return_fff = e.getValue(ctx,Float.TYPE);
|
||||
assertEquals(2.0f,return_fff,0d);
|
||||
assertEquals(2.0f,helper.fff,0d);
|
||||
|
||||
// long
|
||||
e = parser.parseExpression("--lll");
|
||||
assertEquals(66666L,helper.lll);
|
||||
long return_lll = e.getValue(ctx,Long.TYPE);
|
||||
assertEquals(66665L,return_lll);
|
||||
assertEquals(66665L,helper.lll);
|
||||
|
||||
// int
|
||||
e = parser.parseExpression("--iii");
|
||||
assertEquals(42,helper.iii);
|
||||
int return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(41,return_iii);
|
||||
assertEquals(41,helper.iii);
|
||||
return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(40,return_iii);
|
||||
assertEquals(40,helper.iii);
|
||||
|
||||
// short
|
||||
e = parser.parseExpression("--sss");
|
||||
assertEquals(15,helper.sss);
|
||||
int return_sss = (Integer)e.getValue(ctx);
|
||||
assertEquals(14,return_sss);
|
||||
assertEquals(14,helper.sss);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decrement03() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = null;
|
||||
|
||||
e = parser.parseExpression("m()--");
|
||||
try {
|
||||
e.getValue(ctx,Double.TYPE);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.OPERAND_NOT_DECREMENTABLE,see.getMessageCode());
|
||||
}
|
||||
|
||||
e = parser.parseExpression("--m()");
|
||||
try {
|
||||
e.getValue(ctx,Double.TYPE);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.OPERAND_NOT_DECREMENTABLE,see.getMessageCode());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void decrement04() {
|
||||
Integer i = 42;
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(i);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
try {
|
||||
Expression e = parser.parseExpression("--1");
|
||||
e.getValue(ctx,Integer.class);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
|
||||
}
|
||||
try {
|
||||
Expression e = parser.parseExpression("1--");
|
||||
e.getValue(ctx,Integer.class);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void incdecTogether() {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = null;
|
||||
|
||||
// index1 is 2 at the start - the 'intArray[#root.index1++]' should not be evaluated twice!
|
||||
// intArray[2] is 3
|
||||
e = parser.parseExpression("intArray[#root.index1++]++");
|
||||
e.getValue(ctx,Integer.class);
|
||||
assertEquals(3,helper.index1);
|
||||
assertEquals(4,helper.intArray[2]);
|
||||
|
||||
// index1 is 3 intArray[3] is 4
|
||||
e = parser.parseExpression("intArray[#root.index1++]--");
|
||||
assertEquals(4,e.getValue(ctx,Integer.class).intValue());
|
||||
assertEquals(4,helper.index1);
|
||||
assertEquals(3,helper.intArray[3]);
|
||||
|
||||
// index1 is 4, intArray[3] is 3
|
||||
e = parser.parseExpression("intArray[--#root.index1]++");
|
||||
assertEquals(3,e.getValue(ctx,Integer.class).intValue());
|
||||
assertEquals(3,helper.index1);
|
||||
assertEquals(4,helper.intArray[3]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void expectFail(ExpressionParser parser, EvaluationContext eContext, String expressionString, SpelMessage messageCode) {
|
||||
try {
|
||||
Expression e = parser.parseExpression(expressionString);
|
||||
SpelUtilities.printAbstractSyntaxTree(System.out, e);
|
||||
e.getValue(eContext);
|
||||
fail();
|
||||
} catch (SpelEvaluationException see) {
|
||||
see.printStackTrace();
|
||||
assertEquals(messageCode,see.getMessageCode());
|
||||
}
|
||||
}
|
||||
|
||||
private void expectFailNotAssignable(ExpressionParser parser, EvaluationContext eContext, String expressionString) {
|
||||
expectFail(parser,eContext,expressionString,SpelMessage.NOT_ASSIGNABLE);
|
||||
}
|
||||
|
||||
private void expectFailSetValueNotSupported(ExpressionParser parser, EvaluationContext eContext, String expressionString) {
|
||||
expectFail(parser,eContext,expressionString,SpelMessage.SETVALUE_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
private void expectFailNotIncrementable(ExpressionParser parser, EvaluationContext eContext, String expressionString) {
|
||||
expectFail(parser,eContext,expressionString,SpelMessage.OPERAND_NOT_INCREMENTABLE);
|
||||
}
|
||||
|
||||
private void expectFailNotDecrementable(ExpressionParser parser, EvaluationContext eContext, String expressionString) {
|
||||
expectFail(parser,eContext,expressionString,SpelMessage.OPERAND_NOT_DECREMENTABLE);
|
||||
}
|
||||
|
||||
// Verify how all the nodes behave with assignment (++, --, =)
|
||||
@Test
|
||||
public void incrementAllNodeTypes() throws SecurityException, NoSuchMethodException {
|
||||
Spr9751 helper = new Spr9751();
|
||||
StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
|
||||
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
|
||||
Expression e = null;
|
||||
|
||||
// BooleanLiteral
|
||||
expectFailNotAssignable(parser, ctx, "true++");
|
||||
expectFailNotAssignable(parser, ctx, "--false");
|
||||
expectFailSetValueNotSupported(parser, ctx, "true=false");
|
||||
|
||||
// IntLiteral
|
||||
expectFailNotAssignable(parser, ctx, "12++");
|
||||
expectFailNotAssignable(parser, ctx, "--1222");
|
||||
expectFailSetValueNotSupported(parser, ctx, "12=16");
|
||||
|
||||
// LongLiteral
|
||||
expectFailNotAssignable(parser, ctx, "1.0d++");
|
||||
expectFailNotAssignable(parser, ctx, "--3.4d");
|
||||
expectFailSetValueNotSupported(parser, ctx, "1.0d=3.2d");
|
||||
|
||||
// NullLiteral
|
||||
expectFailNotAssignable(parser, ctx, "null++");
|
||||
expectFailNotAssignable(parser, ctx, "--null");
|
||||
expectFailSetValueNotSupported(parser, ctx, "null=null");
|
||||
expectFailSetValueNotSupported(parser, ctx, "null=123");
|
||||
|
||||
// OpAnd
|
||||
expectFailNotAssignable(parser, ctx, "(true && false)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(false AND true)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(true && false)=(false && true)");
|
||||
|
||||
// OpDivide
|
||||
expectFailNotAssignable(parser, ctx, "(3/4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2/5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1/2)=(3/4)");
|
||||
|
||||
// OpEq
|
||||
expectFailNotAssignable(parser, ctx, "(3==4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2==5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1==2)=(3==4)");
|
||||
|
||||
// OpGE
|
||||
expectFailNotAssignable(parser, ctx, "(3>=4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2>=5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1>=2)=(3>=4)");
|
||||
|
||||
// OpGT
|
||||
expectFailNotAssignable(parser, ctx, "(3>4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2>5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1>2)=(3>4)");
|
||||
|
||||
// OpLE
|
||||
expectFailNotAssignable(parser, ctx, "(3<=4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2<=5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1<=2)=(3<=4)");
|
||||
|
||||
// OpLT
|
||||
expectFailNotAssignable(parser, ctx, "(3<4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2<5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1<2)=(3<4)");
|
||||
|
||||
// OpMinus
|
||||
expectFailNotAssignable(parser, ctx, "(3-4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2-5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1-2)=(3-4)");
|
||||
|
||||
// OpModulus
|
||||
expectFailNotAssignable(parser, ctx, "(3%4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2%5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1%2)=(3%4)");
|
||||
|
||||
// OpMultiply
|
||||
expectFailNotAssignable(parser, ctx, "(3*4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2*5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1*2)=(3*4)");
|
||||
|
||||
// OpNE
|
||||
expectFailNotAssignable(parser, ctx, "(3!=4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2!=5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1!=2)=(3!=4)");
|
||||
|
||||
// OpOr
|
||||
expectFailNotAssignable(parser, ctx, "(true || false)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(false OR true)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(true || false)=(false OR true)");
|
||||
|
||||
// OpPlus
|
||||
expectFailNotAssignable(parser, ctx, "(3+4)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(2+5)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1+2)=(3+4)");
|
||||
|
||||
// RealLiteral
|
||||
expectFailNotAssignable(parser, ctx, "1.0d++");
|
||||
expectFailNotAssignable(parser, ctx, "--2.0d");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1.0d)=(3.0d)");
|
||||
expectFailNotAssignable(parser, ctx, "1.0f++");
|
||||
expectFailNotAssignable(parser, ctx, "--2.0f");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(1.0f)=(3.0f)");
|
||||
|
||||
// StringLiteral
|
||||
expectFailNotAssignable(parser, ctx, "'abc'++");
|
||||
expectFailNotAssignable(parser, ctx, "--'def'");
|
||||
expectFailSetValueNotSupported(parser, ctx, "'abc'='def'");
|
||||
|
||||
// Ternary
|
||||
expectFailNotAssignable(parser, ctx, "(true?true:false)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(true?true:false)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(true?true:false)=(true?true:false)");
|
||||
|
||||
// TypeReference
|
||||
expectFailNotAssignable(parser, ctx, "T(String)++");
|
||||
expectFailNotAssignable(parser, ctx, "--T(Integer)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "T(String)=T(Integer)");
|
||||
|
||||
// OperatorBetween
|
||||
expectFailNotAssignable(parser, ctx, "(3 between {1,5})++");
|
||||
expectFailNotAssignable(parser, ctx, "--(3 between {1,5})");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(3 between {1,5})=(3 between {1,5})");
|
||||
|
||||
// OperatorInstanceOf
|
||||
expectFailNotAssignable(parser, ctx, "(type instanceof T(String))++");
|
||||
expectFailNotAssignable(parser, ctx, "--(type instanceof T(String))");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(type instanceof T(String))=(type instanceof T(String))");
|
||||
|
||||
// Elvis
|
||||
expectFailNotAssignable(parser, ctx, "(true?:false)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(true?:false)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(true?:false)=(true?:false)");
|
||||
|
||||
// OpInc
|
||||
expectFailNotAssignable(parser, ctx, "(iii++)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(++iii)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(iii++)=(++iii)");
|
||||
|
||||
// OpDec
|
||||
expectFailNotAssignable(parser, ctx, "(iii--)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(--iii)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(iii--)=(--iii)");
|
||||
|
||||
// OperatorNot
|
||||
expectFailNotAssignable(parser, ctx, "(!true)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(!false)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(!true)=(!false)");
|
||||
|
||||
// OperatorPower
|
||||
expectFailNotAssignable(parser, ctx, "(iii^2)++");
|
||||
expectFailNotAssignable(parser, ctx, "--(iii^2)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(iii^2)=(iii^3)");
|
||||
|
||||
// Assign
|
||||
// iii=42
|
||||
e = parser.parseExpression("iii=iii++");
|
||||
assertEquals(42,helper.iii);
|
||||
int return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(42,helper.iii);
|
||||
assertEquals(42,return_iii);
|
||||
|
||||
// Identifier
|
||||
e = parser.parseExpression("iii++");
|
||||
assertEquals(42,helper.iii);
|
||||
return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(42,return_iii);
|
||||
assertEquals(43,helper.iii);
|
||||
|
||||
e = parser.parseExpression("--iii");
|
||||
assertEquals(43,helper.iii);
|
||||
return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(42,return_iii);
|
||||
assertEquals(42,helper.iii);
|
||||
|
||||
e = parser.parseExpression("iii=99");
|
||||
assertEquals(42,helper.iii);
|
||||
return_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(99,return_iii);
|
||||
assertEquals(99,helper.iii);
|
||||
|
||||
// CompoundExpression
|
||||
// foo.iii == 99
|
||||
e = parser.parseExpression("foo.iii++");
|
||||
assertEquals(99,helper.foo.iii);
|
||||
int return_foo_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(99,return_foo_iii);
|
||||
assertEquals(100,helper.foo.iii);
|
||||
|
||||
e = parser.parseExpression("--foo.iii");
|
||||
assertEquals(100,helper.foo.iii);
|
||||
return_foo_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(99,return_foo_iii);
|
||||
assertEquals(99,helper.foo.iii);
|
||||
|
||||
e = parser.parseExpression("foo.iii=999");
|
||||
assertEquals(99,helper.foo.iii);
|
||||
return_foo_iii = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(999,return_foo_iii);
|
||||
assertEquals(999,helper.foo.iii);
|
||||
|
||||
// ConstructorReference
|
||||
expectFailNotAssignable(parser, ctx, "(new String('abc'))++");
|
||||
expectFailNotAssignable(parser, ctx, "--(new String('abc'))");
|
||||
expectFailSetValueNotSupported(parser, ctx, "(new String('abc'))=(new String('abc'))");
|
||||
|
||||
// MethodReference
|
||||
expectFailNotIncrementable(parser, ctx, "m()++");
|
||||
expectFailNotDecrementable(parser, ctx, "--m()");
|
||||
expectFailSetValueNotSupported(parser, ctx, "m()=m()");
|
||||
|
||||
// OperatorMatches
|
||||
expectFailNotAssignable(parser, ctx, "('abc' matches '^a..')++");
|
||||
expectFailNotAssignable(parser, ctx, "--('abc' matches '^a..')");
|
||||
expectFailSetValueNotSupported(parser, ctx, "('abc' matches '^a..')=('abc' matches '^a..')");
|
||||
|
||||
// Selection
|
||||
ctx.registerFunction("isEven", Spr9751.class.getDeclaredMethod("isEven", Integer.TYPE));
|
||||
|
||||
expectFailNotIncrementable(parser, ctx, "({1,2,3}.?[#isEven(#this)])++");
|
||||
expectFailNotDecrementable(parser, ctx, "--({1,2,3}.?[#isEven(#this)])");
|
||||
expectFailNotAssignable(parser, ctx, "({1,2,3}.?[#isEven(#this)])=({1,2,3}.?[#isEven(#this)])");
|
||||
|
||||
// slightly diff here because return value isn't a list, it is a single entity
|
||||
expectFailNotAssignable(parser, ctx, "({1,2,3}.^[#isEven(#this)])++");
|
||||
expectFailNotAssignable(parser, ctx, "--({1,2,3}.^[#isEven(#this)])");
|
||||
expectFailNotAssignable(parser, ctx, "({1,2,3}.^[#isEven(#this)])=({1,2,3}.^[#isEven(#this)])");
|
||||
|
||||
expectFailNotAssignable(parser, ctx, "({1,2,3}.$[#isEven(#this)])++");
|
||||
expectFailNotAssignable(parser, ctx, "--({1,2,3}.$[#isEven(#this)])");
|
||||
expectFailNotAssignable(parser, ctx, "({1,2,3}.$[#isEven(#this)])=({1,2,3}.$[#isEven(#this)])");
|
||||
|
||||
// FunctionReference
|
||||
expectFailNotAssignable(parser, ctx, "#isEven(3)++");
|
||||
expectFailNotAssignable(parser, ctx, "--#isEven(4)");
|
||||
expectFailSetValueNotSupported(parser, ctx, "#isEven(3)=#isEven(5)");
|
||||
|
||||
// VariableReference
|
||||
ctx.setVariable("wibble", "hello world");
|
||||
expectFailNotIncrementable(parser, ctx, "#wibble++");
|
||||
expectFailNotDecrementable(parser, ctx, "--#wibble");
|
||||
e = parser.parseExpression("#wibble=#wibble+#wibble");
|
||||
String s = e.getValue(ctx,String.class);
|
||||
assertEquals("hello worldhello world",s);
|
||||
assertEquals("hello worldhello world",(String)ctx.lookupVariable("wibble"));
|
||||
|
||||
ctx.setVariable("wobble", 3);
|
||||
e = parser.parseExpression("#wobble++");
|
||||
assertEquals(3,((Integer)ctx.lookupVariable("wobble")).intValue());
|
||||
int r = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(3,r);
|
||||
assertEquals(4,((Integer)ctx.lookupVariable("wobble")).intValue());
|
||||
|
||||
e = parser.parseExpression("--#wobble");
|
||||
assertEquals(4,((Integer)ctx.lookupVariable("wobble")).intValue());
|
||||
r = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(3,r);
|
||||
assertEquals(3,((Integer)ctx.lookupVariable("wobble")).intValue());
|
||||
|
||||
e = parser.parseExpression("#wobble=34");
|
||||
assertEquals(3,((Integer)ctx.lookupVariable("wobble")).intValue());
|
||||
r = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(34,r);
|
||||
assertEquals(34,((Integer)ctx.lookupVariable("wobble")).intValue());
|
||||
|
||||
// Projection
|
||||
expectFailNotIncrementable(parser, ctx, "({1,2,3}.![#isEven(#this)])++"); // projection would be {false,true,false}
|
||||
expectFailNotDecrementable(parser, ctx, "--({1,2,3}.![#isEven(#this)])"); // projection would be {false,true,false}
|
||||
expectFailNotAssignable(parser, ctx, "({1,2,3}.![#isEven(#this)])=({1,2,3}.![#isEven(#this)])");
|
||||
|
||||
// InlineList
|
||||
expectFailNotAssignable(parser, ctx, "({1,2,3})++");
|
||||
expectFailNotAssignable(parser, ctx, "--({1,2,3})");
|
||||
expectFailSetValueNotSupported(parser, ctx, "({1,2,3})=({1,2,3})");
|
||||
|
||||
// BeanReference
|
||||
ctx.setBeanResolver(new MyBeanResolver());
|
||||
expectFailNotAssignable(parser, ctx, "@foo++");
|
||||
expectFailNotAssignable(parser, ctx, "--@foo");
|
||||
expectFailSetValueNotSupported(parser, ctx, "@foo=@bar");
|
||||
|
||||
// PropertyOrFieldReference
|
||||
helper.iii = 42;
|
||||
e = parser.parseExpression("iii++");
|
||||
assertEquals(42,helper.iii);
|
||||
r = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(42,r);
|
||||
assertEquals(43,helper.iii);
|
||||
|
||||
e = parser.parseExpression("--iii");
|
||||
assertEquals(43,helper.iii);
|
||||
r = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(42,r);
|
||||
assertEquals(42,helper.iii);
|
||||
|
||||
e = parser.parseExpression("iii=100");
|
||||
assertEquals(42,helper.iii);
|
||||
r = e.getValue(ctx,Integer.TYPE);
|
||||
assertEquals(100,r);
|
||||
assertEquals(100,helper.iii);
|
||||
|
||||
}
|
||||
|
||||
static class MyBeanResolver implements BeanResolver {
|
||||
|
||||
public Object resolve(EvaluationContext context, String beanName)
|
||||
throws AccessException {
|
||||
if (beanName.equals("foo") || beanName.equals("bar")) {
|
||||
return new Spr9751_2();
|
||||
}
|
||||
throw new AccessException("not heard of "+beanName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+6
-275
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -13,6 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -22,14 +23,13 @@ import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.expression.spel.standard.SpelExpression;
|
||||
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 {
|
||||
@@ -37,7 +37,8 @@ public class InProgressTests extends ExpressionTestCase {
|
||||
@Test
|
||||
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
|
||||
// no inline list building at the moment
|
||||
// evaluate("1 between {1, 5}", "true", Boolean.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -78,7 +79,6 @@ public class InProgressTests extends ExpressionTestCase {
|
||||
public void testProjection06() throws Exception {
|
||||
SpelExpression expr = (SpelExpression) parser.parseExpression("'abc'.![true]");
|
||||
Assert.assertEquals("'abc'.![true]", expr.toStringAST());
|
||||
Assert.assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
}
|
||||
|
||||
// SELECTION
|
||||
@@ -99,7 +99,6 @@ public class InProgressTests extends ExpressionTestCase {
|
||||
@Test
|
||||
public void testSelection03() {
|
||||
evaluate("mapOfNumbersUpToTen.?[key>5].size()", "5", Integer.class);
|
||||
// evaluate("listOfNumbersUpToTen.?{#this>5}", "5", ArrayList.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,284 +142,16 @@ public class InProgressTests extends ExpressionTestCase {
|
||||
public void testSelectionAST() throws Exception {
|
||||
SpelExpression expr = (SpelExpression) parser.parseExpression("'abc'.^[true]");
|
||||
Assert.assertEquals("'abc'.^[true]", expr.toStringAST());
|
||||
Assert.assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
expr = (SpelExpression) parser.parseExpression("'abc'.?[true]");
|
||||
Assert.assertEquals("'abc'.?[true]", expr.toStringAST());
|
||||
Assert.assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
expr = (SpelExpression) parser.parseExpression("'abc'.$[true]");
|
||||
Assert.assertEquals("'abc'.$[true]", expr.toStringAST());
|
||||
Assert.assertFalse(expr.isWritable(new StandardEvaluationContext()));
|
||||
}
|
||||
|
||||
// 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 testRelOperatorsBetween02() {
|
||||
// evaluate("'efg' between {'abc', 'xyz'}", "true", Boolean.class);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public void testRelOperatorsBetweenErrors02() {
|
||||
// evaluateAndCheckError("'abc' between {5,7}", SpelMessages.NOT_COMPARABLE, 6);
|
||||
// }
|
||||
// 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);
|
||||
// }
|
||||
|
||||
// // inline map creation
|
||||
// @Test
|
||||
// public void testInlineMapCreation01() {
|
||||
// evaluate("#{'key1':'Value 1', 'today':'Monday'}", "{key1=Value 1, today=Monday}", HashMap.class);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testInlineMapCreation02() {
|
||||
// // "{2=February, 1=January, 3=March}", HashMap.class);
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}.size()", 3, Integer.class);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testInlineMapCreation03() {
|
||||
// evaluate("#{'key1':'Value 1', 'today':'Monday'}['key1']", "Value 1", String.class);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testInlineMapCreation04() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}[3]", "March", String.class);
|
||||
// }
|
||||
//
|
||||
// @Test
|
||||
// public void testInlineMapCreation05() {
|
||||
// evaluate("#{1:'January', 2:'February', 3:'March'}.get(2)", "February", String.class);
|
||||
// }
|
||||
|
||||
// set construction
|
||||
@Test
|
||||
public void testSetConstruction01() {
|
||||
evaluate("new java.util.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
|
||||
// @Test
|
||||
// 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);
|
||||
// }
|
||||
//
|
||||
// public void testSelectionUsingIndex() {
|
||||
// evaluate("listOfNumbersUpToTen.?[#index > 5 ]", "[7, 8, 9, 10]", ArrayList.class);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user