1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.expression.spel;
18
19 import java.lang.reflect.Method;
20 import java.math.BigDecimal;
21 import java.math.BigInteger;
22 import java.util.ArrayList;
23 import java.util.List;
24 import java.util.Map;
25
26 import org.junit.Test;
27
28 import org.springframework.core.convert.TypeDescriptor;
29 import org.springframework.expression.AccessException;
30 import org.springframework.expression.BeanResolver;
31 import org.springframework.expression.EvaluationContext;
32 import org.springframework.expression.EvaluationException;
33 import org.springframework.expression.Expression;
34 import org.springframework.expression.ExpressionParser;
35 import org.springframework.expression.MethodExecutor;
36 import org.springframework.expression.MethodFilter;
37 import org.springframework.expression.MethodResolver;
38 import org.springframework.expression.ParseException;
39 import org.springframework.expression.spel.standard.SpelExpression;
40 import org.springframework.expression.spel.standard.SpelExpressionParser;
41 import org.springframework.expression.spel.support.StandardEvaluationContext;
42 import org.springframework.expression.spel.support.StandardTypeLocator;
43 import org.springframework.expression.spel.testresources.TestPerson;
44
45 import static org.hamcrest.Matchers.*;
46 import static org.junit.Assert.*;
47
48
49
50
51
52
53
54
55
56
57
58 public class EvaluationTests extends AbstractExpressionTests {
59
60 @Test
61 public void testCreateListsOnAttemptToIndexNull01() throws EvaluationException, ParseException {
62 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
63 Expression expression = parser.parseExpression("list[0]");
64 TestClass testClass = new TestClass();
65 Object o = null;
66 o = expression.getValue(new StandardEvaluationContext(testClass));
67 assertEquals("", o);
68 o = parser.parseExpression("list[3]").getValue(new StandardEvaluationContext(testClass));
69 assertEquals("", o);
70 assertEquals(4, testClass.list.size());
71 try {
72 o = parser.parseExpression("list2[3]").getValue(new StandardEvaluationContext(testClass));
73 fail();
74 } catch (EvaluationException ee) {
75 ee.printStackTrace();
76
77 }
78 o = parser.parseExpression("foo[3]").getValue(new StandardEvaluationContext(testClass));
79 assertEquals("", o);
80 assertEquals(4, testClass.getFoo().size());
81 }
82
83 @Test(expected = SpelEvaluationException.class)
84 public void testCreateMapsOnAttemptToIndexNull01() throws Exception {
85 TestClass testClass = new TestClass();
86 StandardEvaluationContext ctx = new StandardEvaluationContext(testClass);
87 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
88 Object o = null;
89 o = parser.parseExpression("map['a']").getValue(ctx);
90 assertNull(o);
91 o = parser.parseExpression("map").getValue(ctx);
92 assertNotNull(o);
93
94 o = parser.parseExpression("map2['a']").getValue(ctx);
95
96 }
97
98
99 @Test(expected = SpelEvaluationException.class)
100 public void testCreateObjectsOnAttemptToReferenceNull() throws Exception {
101 TestClass testClass = new TestClass();
102 StandardEvaluationContext ctx = new StandardEvaluationContext(testClass);
103 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
104 Object o = null;
105 o = parser.parseExpression("wibble.bar").getValue(ctx);
106 assertEquals("hello", o);
107 o = parser.parseExpression("wibble").getValue(ctx);
108 assertNotNull(o);
109
110 o = parser.parseExpression("wibble2.bar").getValue(ctx);
111 }
112
113
114 @SuppressWarnings("rawtypes")
115 static class TestClass {
116 public Foo wibble;
117 private Foo wibble2;
118 public Map map;
119 public Map<String, Integer> mapStringToInteger;
120 public List<String> list;
121 public List list2;
122 private Map map2;
123 private List<String> foo;
124
125 public Map getMap2() { return this.map2; }
126 public Foo getWibble2() { return this.wibble2; }
127 public List<String> getFoo() { return this.foo; }
128 public void setFoo(List<String> newfoo) { this.foo = newfoo; }
129 }
130
131 public static class Foo {
132 public Foo() {}
133 public String bar = "hello";
134 }
135
136
137 @Test
138 public void testElvis01() {
139 evaluate("'Andy'?:'Dave'", "Andy", String.class);
140 evaluate("null?:'Dave'", "Dave", String.class);
141 }
142
143 @Test
144 public void testSafeNavigation() {
145 evaluate("null?.null?.null", null, null);
146 }
147
148 @Test
149 public void testRelOperatorGT01() {
150 evaluate("3 > 6", "false", Boolean.class);
151 }
152
153 @Test
154 public void testRelOperatorLT01() {
155 evaluate("3 < 6", "true", Boolean.class);
156 }
157
158 @Test
159 public void testRelOperatorLE01() {
160 evaluate("3 <= 6", "true", Boolean.class);
161 }
162
163 @Test
164 public void testRelOperatorGE01() {
165 evaluate("3 >= 6", "false", Boolean.class);
166 }
167
168 @Test
169 public void testRelOperatorGE02() {
170 evaluate("3 >= 3", "true", Boolean.class);
171 }
172
173 @Test
174 public void testRelOperatorsInstanceof01() {
175 evaluate("'xyz' instanceof T(int)", "false", Boolean.class);
176 }
177
178 @Test
179 public void testRelOperatorsInstanceof04() {
180 evaluate("null instanceof T(String)", "false", Boolean.class);
181 }
182
183 @Test
184 public void testRelOperatorsInstanceof05() {
185 evaluate("null instanceof T(Integer)", "false", Boolean.class);
186 }
187
188 @Test
189 public void testRelOperatorsInstanceof06() {
190 evaluateAndCheckError("'A' instanceof null", SpelMessage.INSTANCEOF_OPERATOR_NEEDS_CLASS_OPERAND, 15, "null");
191 }
192
193 @Test
194 public void testRelOperatorsMatches01() {
195 evaluate("'5.0067' matches '^-?\\d+(\\.\\d{2})?$'", "false", Boolean.class);
196 }
197
198 @Test
199 public void testRelOperatorsMatches02() {
200 evaluate("'5.00' matches '^-?\\d+(\\.\\d{2})?$'", "true", Boolean.class);
201 }
202
203 @Test
204 public void testRelOperatorsMatches03() {
205 evaluateAndCheckError("null matches '^.*$'", SpelMessage.INVALID_FIRST_OPERAND_FOR_MATCHES_OPERATOR, 0, null);
206 }
207
208 @Test
209 public void testRelOperatorsMatches04() {
210 evaluateAndCheckError("'abc' matches null", SpelMessage.INVALID_SECOND_OPERAND_FOR_MATCHES_OPERATOR, 14, null);
211 }
212
213 @Test
214 public void testRelOperatorsMatches05() {
215 evaluate("27 matches '^.*2.*$'", true, Boolean.class);
216 }
217
218
219 @Test
220 public void testMixingOperators01() {
221 evaluate("true and 5>3", "true", Boolean.class);
222 }
223
224
225 @Test
226 public void testPropertyField01() {
227 evaluate("name", "Nikola Tesla", String.class, false);
228
229 evaluateAndCheckError("madeup", SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE, 0, "madeup",
230 "org.springframework.expression.spel.testresources.Inventor");
231 }
232
233 @Test
234 public void testPropertyField02_SPR7100() {
235 evaluate("_name", "Nikola Tesla", String.class);
236 evaluate("_name_", "Nikola Tesla", String.class);
237 }
238
239 @Test
240 public void testRogueTrailingDotCausesNPE_SPR6866() {
241 try {
242 new SpelExpressionParser().parseExpression("placeOfBirth.foo.");
243 fail("Should have failed to parse");
244 } catch (ParseException e) {
245 assertTrue(e instanceof SpelParseException);
246 SpelParseException spe = (SpelParseException) e;
247 assertEquals(SpelMessage.OOD, spe.getMessageCode());
248 assertEquals(16, spe.getPosition());
249 }
250 }
251
252
253 @Test
254 public void testPropertiesNested01() {
255 evaluate("placeOfBirth.city", "SmilJan", String.class, true);
256 }
257
258 @Test
259 public void testPropertiesNested02() {
260 evaluate("placeOfBirth.doubleIt(12)", "24", Integer.class);
261 }
262
263 @Test
264 public void testPropertiesNested03() throws ParseException {
265 try {
266 new SpelExpressionParser().parseRaw("placeOfBirth.23");
267 fail();
268 } catch (SpelParseException spe) {
269 assertEquals(spe.getMessageCode(), SpelMessage.UNEXPECTED_DATA_AFTER_DOT);
270 assertEquals("23", spe.getInserts()[0]);
271 }
272 }
273
274
275 @Test
276 public void testMethods01() {
277 evaluate("echo(12)", "12", String.class);
278 }
279
280 @Test
281 public void testMethods02() {
282 evaluate("echo(name)", "Nikola Tesla", String.class);
283 }
284
285
286 @Test
287 public void testConstructorInvocation01() {
288 evaluate("new String('hello')", "hello", String.class);
289 }
290
291 @Test
292 public void testConstructorInvocation05() {
293 evaluate("new java.lang.String('foobar')", "foobar", String.class);
294 }
295
296 @Test
297 public void testConstructorInvocation06() throws Exception {
298
299 SpelExpression expr = (SpelExpression) parser.parseExpression("new String('wibble')");
300 String newString = expr.getValue(String.class);
301 assertEquals("wibble", newString);
302 newString = expr.getValue(String.class);
303 assertEquals("wibble", newString);
304
305
306 assertFalse(expr.isWritable(new StandardEvaluationContext()));
307
308
309 assertEquals("new String('wibble')", expr.toStringAST());
310 }
311
312
313 @Test
314 public void testUnaryMinus01() {
315 evaluate("-5", "-5", Integer.class);
316 }
317
318 @Test
319 public void testUnaryPlus01() {
320 evaluate("+5", "5", Integer.class);
321 }
322
323 @Test
324 public void testUnaryNot01() {
325 evaluate("!true", "false", Boolean.class);
326 }
327
328 @Test
329 public void testUnaryNot02() {
330 evaluate("!false", "true", Boolean.class);
331 }
332
333 @Test(expected = EvaluationException.class)
334 public void testUnaryNotWithNullValue() {
335 parser.parseExpression("!null").getValue();
336 }
337
338 @Test(expected = EvaluationException.class)
339 public void testAndWithNullValueOnLeft() {
340 parser.parseExpression("null and true").getValue();
341 }
342
343 @Test(expected = EvaluationException.class)
344 public void testAndWithNullValueOnRight() {
345 parser.parseExpression("true and null").getValue();
346 }
347
348 @Test(expected = EvaluationException.class)
349 public void testOrWithNullValueOnLeft() {
350 parser.parseExpression("null or false").getValue();
351 }
352
353 @Test(expected = EvaluationException.class)
354 public void testOrWithNullValueOnRight() {
355 parser.parseExpression("false or null").getValue();
356 }
357
358
359 @Test
360 public void testAssignmentToVariables01() {
361 evaluate("#var1='value1'", "value1", String.class);
362 }
363
364 @Test
365 public void testTernaryOperator01() {
366 evaluate("2>4?1:2", 2, Integer.class);
367 }
368
369 @Test
370 public void testTernaryOperator02() {
371 evaluate("'abc'=='abc'?1:2", 1, Integer.class);
372 }
373
374 @Test
375 public void testTernaryOperator03() {
376
377 evaluateAndCheckError("'hello'?1:2", SpelMessage.TYPE_CONVERSION_ERROR);
378 }
379
380 @Test
381 public void testTernaryOperator04() throws Exception {
382 Expression expr = parser.parseExpression("1>2?3:4");
383 assertFalse(expr.isWritable(eContext));
384 }
385
386 @Test
387 public void testTernaryOperator05() {
388 evaluate("1>2?#var=4:#var=5", 5, Integer.class);
389 evaluate("3?:#var=5", 3, Integer.class);
390 evaluate("null?:#var=5", 5, Integer.class);
391 evaluate("2>4?(3>2?true:false):(5<3?true:false)", false, Boolean.class);
392 }
393
394 @Test(expected = EvaluationException.class)
395 public void testTernaryOperatorWithNullValue() {
396 parser.parseExpression("null ? 0 : 1").getValue();
397 }
398
399 @Test
400 public void methodCallWithRootReferenceThroughParameter() {
401 evaluate("placeOfBirth.doubleIt(inventions.length)", 18, Integer.class);
402 }
403
404 @Test
405 public void ctorCallWithRootReferenceThroughParameter() {
406 evaluate("new org.springframework.expression.spel.testresources.PlaceOfBirth(inventions[0].toString()).city",
407 "Telephone repeater", String.class);
408 }
409
410 @Test
411 public void fnCallWithRootReferenceThroughParameter() {
412 evaluate("#reverseInt(inventions.length, inventions.length, inventions.length)", "int[3]{9,9,9}", int[].class);
413 }
414
415 @Test
416 public void methodCallWithRootReferenceThroughParameterThatIsAFunctionCall() {
417 evaluate("placeOfBirth.doubleIt(#reverseInt(inventions.length,2,3)[2])", 18, Integer.class);
418 }
419
420 @Test
421 public void testIndexer03() {
422 evaluate("'christian'[8]", "n", String.class);
423 }
424
425 @Test
426 public void testIndexerError() {
427 evaluateAndCheckError("new org.springframework.expression.spel.testresources.Inventor().inventions[1]",
428 SpelMessage.CANNOT_INDEX_INTO_NULL_VALUE);
429 }
430
431 @Test
432 public void testStaticRef02() {
433 evaluate("T(java.awt.Color).green.getRGB()!=0", "true", Boolean.class);
434 }
435
436
437 @Test
438 public void testVariableAccess01() {
439 evaluate("#answer", "42", Integer.class, true);
440 }
441
442 @Test
443 public void testFunctionAccess01() {
444 evaluate("#reverseInt(1,2,3)", "int[3]{3,2,1}", int[].class);
445 }
446
447 @Test
448 public void testFunctionAccess02() {
449 evaluate("#reverseString('hello')", "olleh", String.class);
450 }
451
452
453 @Test
454 public void testTypeReferences01() {
455 evaluate("T(java.lang.String)", "class java.lang.String", Class.class);
456 }
457
458 @Test
459 public void testTypeReferencesAndQualifiedIdentifierCaching() throws Exception {
460 SpelExpression expr = (SpelExpression) parser.parseExpression("T(java.lang.String)");
461 assertFalse(expr.isWritable(new StandardEvaluationContext()));
462 assertEquals("T(java.lang.String)", expr.toStringAST());
463 assertEquals(String.class, expr.getValue(Class.class));
464
465 assertEquals("T(java.lang.String)", expr.toStringAST());
466 assertEquals(String.class, expr.getValue(Class.class));
467 }
468
469 @Test
470 public void operatorVariants() throws Exception {
471 SpelExpression expr = (SpelExpression)parser.parseExpression("#a < #b");
472 EvaluationContext ctx = new StandardEvaluationContext();
473 ctx.setVariable("a", (short)3);
474 ctx.setVariable("b", (short)6);
475 assertTrue(expr.getValue(ctx, Boolean.class));
476 ctx.setVariable("b", (byte)6);
477 assertTrue(expr.getValue(ctx, Boolean.class));
478 ctx.setVariable("a", (byte)9);
479 ctx.setVariable("b", (byte)6);
480 assertFalse(expr.getValue(ctx, Boolean.class));
481 ctx.setVariable("a", 10L);
482 ctx.setVariable("b", (short)30);
483 assertTrue(expr.getValue(ctx, Boolean.class));
484 ctx.setVariable("a", (byte)3);
485 ctx.setVariable("b", (short)30);
486 assertTrue(expr.getValue(ctx, Boolean.class));
487 ctx.setVariable("a", (byte)3);
488 ctx.setVariable("b", 30L);
489 assertTrue(expr.getValue(ctx, Boolean.class));
490 ctx.setVariable("a", (byte)3);
491 ctx.setVariable("b", 30f);
492 assertTrue(expr.getValue(ctx, Boolean.class));
493 ctx.setVariable("a", new BigInteger("10"));
494 ctx.setVariable("b", new BigInteger("20"));
495 assertTrue(expr.getValue(ctx, Boolean.class));
496 }
497
498 @Test
499 public void testTypeReferencesPrimitive() {
500 evaluate("T(int)", "int", Class.class);
501 evaluate("T(byte)", "byte", Class.class);
502 evaluate("T(char)", "char", Class.class);
503 evaluate("T(boolean)", "boolean", Class.class);
504 evaluate("T(long)", "long", Class.class);
505 evaluate("T(short)", "short", Class.class);
506 evaluate("T(double)", "double", Class.class);
507 evaluate("T(float)", "float", Class.class);
508 }
509
510 @Test
511 public void testTypeReferences02() {
512 evaluate("T(String)", "class java.lang.String", Class.class);
513 }
514
515 @Test
516 public void testStringType() {
517 evaluateAndAskForReturnType("getPlaceOfBirth().getCity()", "SmilJan", String.class);
518 }
519
520 @Test
521 public void testNumbers01() {
522 evaluateAndAskForReturnType("3*4+5", 17, Integer.class);
523 evaluateAndAskForReturnType("3*4+5", 17L, Long.class);
524 evaluateAndAskForReturnType("65", 'A', Character.class);
525 evaluateAndAskForReturnType("3*4+5", (short) 17, Short.class);
526 evaluateAndAskForReturnType("3*4+5", "17", String.class);
527 }
528
529 @Test
530 public void testAdvancedNumerics() throws Exception {
531 int twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Integer.class);
532 assertEquals(24, twentyFour);
533 double one = parser.parseExpression("8.0 / 5e0 % 2").getValue(Double.class);
534 assertEquals(1.6d, one, 0);
535 int o = parser.parseExpression("8.0 / 5e0 % 2").getValue(Integer.class);
536 assertEquals(1, o);
537 int sixteen = parser.parseExpression("-2 ^ 4").getValue(Integer.class);
538 assertEquals(16, sixteen);
539 int minusFortyFive = parser.parseExpression("1+2-3*8^2/2/2").getValue(Integer.class);
540 assertEquals(-45, minusFortyFive);
541 }
542
543 @Test
544 public void testComparison() throws Exception {
545 EvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
546 boolean trueValue = parser.parseExpression("T(java.util.Date) == Birthdate.Class").getValue(context,
547 Boolean.class);
548 assertTrue(trueValue);
549 }
550
551 @Test
552 public void testResolvingList() throws Exception {
553 StandardEvaluationContext context = TestScenarioCreator.getTestEvaluationContext();
554 try {
555 assertFalse(parser.parseExpression("T(List)!=null").getValue(context, Boolean.class));
556 fail("should have failed to find List");
557 } catch (EvaluationException ee) {
558
559 }
560 ((StandardTypeLocator) context.getTypeLocator()).registerImport("java.util");
561 assertTrue(parser.parseExpression("T(List)!=null").getValue(context, Boolean.class));
562 }
563
564 @Test
565 public void testResolvingString() throws Exception {
566 Class<?> stringClass = parser.parseExpression("T(String)").getValue(Class.class);
567 assertEquals(String.class, stringClass);
568 }
569
570
571
572
573
574 @Test
575 public void initializingCollectionElementsOnWrite() throws Exception {
576 TestPerson person = new TestPerson();
577 EvaluationContext context = new StandardEvaluationContext(person);
578 SpelParserConfiguration config = new SpelParserConfiguration(true, true);
579 ExpressionParser parser = new SpelExpressionParser(config);
580 Expression expression = parser.parseExpression("name");
581 expression.setValue(context, "Oleg");
582 assertEquals("Oleg", person.getName());
583
584 expression = parser.parseExpression("address.street");
585 expression.setValue(context, "123 High St");
586 assertEquals("123 High St", person.getAddress().getStreet());
587
588 expression = parser.parseExpression("address.crossStreets[0]");
589 expression.setValue(context, "Blah");
590 assertEquals("Blah", person.getAddress().getCrossStreets().get(0));
591
592 expression = parser.parseExpression("address.crossStreets[3]");
593 expression.setValue(context, "Wibble");
594 assertEquals("Blah", person.getAddress().getCrossStreets().get(0));
595 assertEquals("Wibble", person.getAddress().getCrossStreets().get(3));
596 }
597
598
599
600
601 @Test
602 public void caseInsensitiveNullLiterals() {
603 ExpressionParser parser = new SpelExpressionParser();
604 Expression exp;
605
606 exp = parser.parseExpression("null");
607 assertNull(exp.getValue());
608
609 exp = parser.parseExpression("NULL");
610 assertNull(exp.getValue());
611
612 exp = parser.parseExpression("NuLl");
613 assertNull(exp.getValue());
614 }
615
616
617
618
619 @Test
620 public void customMethodFilter() throws Exception {
621 StandardEvaluationContext context = new StandardEvaluationContext();
622
623
624 List<MethodResolver> customResolvers = new ArrayList<MethodResolver>();
625 customResolvers.add(new CustomMethodResolver());
626 context.setMethodResolvers(customResolvers);
627
628
629
630
631
632 MethodFilter filter = new CustomMethodFilter();
633 try {
634 context.registerMethodFilter(String.class, filter);
635 fail("should have failed");
636 } catch (IllegalStateException ise) {
637 assertEquals(
638 "Method filter cannot be set as the reflective method resolver is not in use",
639 ise.getMessage());
640 }
641 }
642
643 static class CustomMethodResolver implements MethodResolver {
644
645 @Override
646 public MethodExecutor resolve(EvaluationContext context,
647 Object targetObject, String name,
648 List<TypeDescriptor> argumentTypes) throws AccessException {
649 return null;
650 }
651 }
652
653 static class CustomMethodFilter implements MethodFilter {
654
655 @Override
656 public List<Method> filter(List<Method> methods) {
657 return null;
658 }
659
660 }
661
662
663
664 static class Spr9751 {
665 public String type = "hello";
666 public BigDecimal bd = new BigDecimal("2");
667 public double ddd = 2.0d;
668 public float fff = 3.0f;
669 public long lll = 66666L;
670 public int iii = 42;
671 public short sss = (short)15;
672 public Spr9751_2 foo = new Spr9751_2();
673
674 public void m() {}
675
676 public int[] intArray = new int[]{1,2,3,4,5};
677 public int index1 = 2;
678
679 public Integer[] integerArray;
680 public int index2 = 2;
681
682 public List<String> listOfStrings;
683 public int index3 = 0;
684
685 public Spr9751() {
686 integerArray = new Integer[5];
687 integerArray[0] = 1;
688 integerArray[1] = 2;
689 integerArray[2] = 3;
690 integerArray[3] = 4;
691 integerArray[4] = 5;
692 listOfStrings = new ArrayList<String>();
693 listOfStrings.add("abc");
694 }
695
696 public static boolean isEven(int i) {
697 return (i%2)==0;
698 }
699 }
700
701 static class Spr9751_2 {
702 public int iii = 99;
703 }
704
705
706
707
708
709 @Test
710 public void collectionGrowingViaIndexer() {
711 Spr9751 instance = new Spr9751();
712
713
714 StandardEvaluationContext ctx = new StandardEvaluationContext(instance);
715 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
716 Expression e = parser.parseExpression("listOfStrings[++index3]='def'");
717 e.getValue(ctx);
718 assertEquals(2,instance.listOfStrings.size());
719 assertEquals("def",instance.listOfStrings.get(1));
720
721
722 ctx = new StandardEvaluationContext(instance);
723 parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
724 e = parser.parseExpression("listOfStrings[0]");
725 String value = e.getValue(ctx,String.class);
726 assertEquals("abc",value);
727 e = parser.parseExpression("listOfStrings[1]");
728 value = e.getValue(ctx,String.class);
729 assertEquals("def",value);
730 e = parser.parseExpression("listOfStrings[2]");
731 value = e.getValue(ctx,String.class);
732 assertEquals("",value);
733
734
735 ctx = new StandardEvaluationContext(instance);
736 parser = new SpelExpressionParser(new SpelParserConfiguration(false, false));
737 e = parser.parseExpression("listOfStrings[3]");
738 try {
739 e.getValue(ctx,String.class);
740 fail();
741 } catch (SpelEvaluationException see) {
742 assertEquals(SpelMessage.COLLECTION_INDEX_OUT_OF_BOUNDS,see.getMessageCode());
743 }
744 }
745
746 @Test
747 public void limitCollectionGrowing() throws Exception {
748 TestClass instance = new TestClass();
749 StandardEvaluationContext ctx = new StandardEvaluationContext(instance);
750 SpelExpressionParser parser = new SpelExpressionParser( new SpelParserConfiguration(true, true, 3));
751 Expression expression = parser.parseExpression("foo[2]");
752 expression.setValue(ctx, "2");
753 assertThat(instance.getFoo().size(), equalTo(3));
754 expression = parser.parseExpression("foo[3]");
755 try {
756 expression.setValue(ctx, "3");
757 } catch(SpelEvaluationException see) {
758 assertEquals(SpelMessage.UNABLE_TO_GROW_COLLECTION, see.getMessageCode());
759 assertThat(instance.getFoo().size(), equalTo(3));
760 }
761 }
762
763
764 @Test
765 public void increment01root() {
766 Integer i = 42;
767 StandardEvaluationContext ctx = new StandardEvaluationContext(i);
768 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
769 Expression e = parser.parseExpression("#this++");
770 assertEquals(42,i.intValue());
771 try {
772 e.getValue(ctx,Integer.class);
773 fail();
774 } catch (SpelEvaluationException see) {
775 assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
776 }
777 }
778
779 @Test
780 public void increment02postfix() {
781 Spr9751 helper = new Spr9751();
782 StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
783 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
784 Expression e = null;
785
786
787 e = parser.parseExpression("bd++");
788 assertTrue(new BigDecimal("2").equals(helper.bd));
789 BigDecimal return_bd = e.getValue(ctx,BigDecimal.class);
790 assertTrue(new BigDecimal("2").equals(return_bd));
791 assertTrue(new BigDecimal("3").equals(helper.bd));
792
793
794 e = parser.parseExpression("ddd++");
795 assertEquals(2.0d,helper.ddd,0d);
796 double return_ddd = e.getValue(ctx,Double.TYPE);
797 assertEquals(2.0d,return_ddd,0d);
798 assertEquals(3.0d,helper.ddd,0d);
799
800
801 e = parser.parseExpression("fff++");
802 assertEquals(3.0f,helper.fff,0d);
803 float return_fff = e.getValue(ctx,Float.TYPE);
804 assertEquals(3.0f,return_fff,0d);
805 assertEquals(4.0f,helper.fff,0d);
806
807
808 e = parser.parseExpression("lll++");
809 assertEquals(66666L,helper.lll);
810 long return_lll = e.getValue(ctx,Long.TYPE);
811 assertEquals(66666L,return_lll);
812 assertEquals(66667L,helper.lll);
813
814
815 e = parser.parseExpression("iii++");
816 assertEquals(42,helper.iii);
817 int return_iii = e.getValue(ctx,Integer.TYPE);
818 assertEquals(42,return_iii);
819 assertEquals(43,helper.iii);
820 return_iii = e.getValue(ctx,Integer.TYPE);
821 assertEquals(43,return_iii);
822 assertEquals(44,helper.iii);
823
824
825 e = parser.parseExpression("sss++");
826 assertEquals(15,helper.sss);
827 short return_sss = e.getValue(ctx,Short.TYPE);
828 assertEquals(15,return_sss);
829 assertEquals(16,helper.sss);
830 }
831
832 @Test
833 public void increment02prefix() {
834 Spr9751 helper = new Spr9751();
835 StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
836 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
837 Expression e = null;
838
839
840
841 e = parser.parseExpression("++bd");
842 assertTrue(new BigDecimal("2").equals(helper.bd));
843 BigDecimal return_bd = e.getValue(ctx,BigDecimal.class);
844 assertTrue(new BigDecimal("3").equals(return_bd));
845 assertTrue(new BigDecimal("3").equals(helper.bd));
846
847
848 e = parser.parseExpression("++ddd");
849 assertEquals(2.0d,helper.ddd,0d);
850 double return_ddd = e.getValue(ctx,Double.TYPE);
851 assertEquals(3.0d,return_ddd,0d);
852 assertEquals(3.0d,helper.ddd,0d);
853
854
855 e = parser.parseExpression("++fff");
856 assertEquals(3.0f,helper.fff,0d);
857 float return_fff = e.getValue(ctx,Float.TYPE);
858 assertEquals(4.0f,return_fff,0d);
859 assertEquals(4.0f,helper.fff,0d);
860
861
862 e = parser.parseExpression("++lll");
863 assertEquals(66666L,helper.lll);
864 long return_lll = e.getValue(ctx,Long.TYPE);
865 assertEquals(66667L,return_lll);
866 assertEquals(66667L,helper.lll);
867
868
869 e = parser.parseExpression("++iii");
870 assertEquals(42,helper.iii);
871 int return_iii = e.getValue(ctx,Integer.TYPE);
872 assertEquals(43,return_iii);
873 assertEquals(43,helper.iii);
874 return_iii = e.getValue(ctx,Integer.TYPE);
875 assertEquals(44,return_iii);
876 assertEquals(44,helper.iii);
877
878
879 e = parser.parseExpression("++sss");
880 assertEquals(15,helper.sss);
881 int return_sss = (Integer)e.getValue(ctx);
882 assertEquals(16,return_sss);
883 assertEquals(16,helper.sss);
884 }
885
886 @Test
887 public void increment03() {
888 Spr9751 helper = new Spr9751();
889 StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
890 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
891 Expression e = null;
892
893 e = parser.parseExpression("m()++");
894 try {
895 e.getValue(ctx,Double.TYPE);
896 fail();
897 } catch (SpelEvaluationException see) {
898 assertEquals(SpelMessage.OPERAND_NOT_INCREMENTABLE,see.getMessageCode());
899 }
900
901 e = parser.parseExpression("++m()");
902 try {
903 e.getValue(ctx,Double.TYPE);
904 fail();
905 } catch (SpelEvaluationException see) {
906 assertEquals(SpelMessage.OPERAND_NOT_INCREMENTABLE,see.getMessageCode());
907 }
908 }
909
910
911 @Test
912 public void increment04() {
913 Integer i = 42;
914 StandardEvaluationContext ctx = new StandardEvaluationContext(i);
915 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
916 try {
917 Expression e = parser.parseExpression("++1");
918 e.getValue(ctx,Integer.class);
919 fail();
920 } catch (SpelEvaluationException see) {
921 assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
922 }
923 try {
924 Expression e = parser.parseExpression("1++");
925 e.getValue(ctx,Integer.class);
926 fail();
927 } catch (SpelEvaluationException see) {
928 assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
929 }
930 }
931 @Test
932 public void decrement01root() {
933 Integer i = 42;
934 StandardEvaluationContext ctx = new StandardEvaluationContext(i);
935 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
936 Expression e = parser.parseExpression("#this--");
937 assertEquals(42,i.intValue());
938 try {
939 e.getValue(ctx,Integer.class);
940 fail();
941 } catch (SpelEvaluationException see) {
942 assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
943 }
944 }
945
946 @Test
947 public void decrement02postfix() {
948 Spr9751 helper = new Spr9751();
949 StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
950 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
951 Expression e = null;
952
953
954 e = parser.parseExpression("bd--");
955 assertTrue(new BigDecimal("2").equals(helper.bd));
956 BigDecimal return_bd = e.getValue(ctx,BigDecimal.class);
957 assertTrue(new BigDecimal("2").equals(return_bd));
958 assertTrue(new BigDecimal("1").equals(helper.bd));
959
960
961 e = parser.parseExpression("ddd--");
962 assertEquals(2.0d,helper.ddd,0d);
963 double return_ddd = e.getValue(ctx,Double.TYPE);
964 assertEquals(2.0d,return_ddd,0d);
965 assertEquals(1.0d,helper.ddd,0d);
966
967
968 e = parser.parseExpression("fff--");
969 assertEquals(3.0f,helper.fff,0d);
970 float return_fff = e.getValue(ctx,Float.TYPE);
971 assertEquals(3.0f,return_fff,0d);
972 assertEquals(2.0f,helper.fff,0d);
973
974
975 e = parser.parseExpression("lll--");
976 assertEquals(66666L,helper.lll);
977 long return_lll = e.getValue(ctx,Long.TYPE);
978 assertEquals(66666L,return_lll);
979 assertEquals(66665L,helper.lll);
980
981
982 e = parser.parseExpression("iii--");
983 assertEquals(42,helper.iii);
984 int return_iii = e.getValue(ctx,Integer.TYPE);
985 assertEquals(42,return_iii);
986 assertEquals(41,helper.iii);
987 return_iii = e.getValue(ctx,Integer.TYPE);
988 assertEquals(41,return_iii);
989 assertEquals(40,helper.iii);
990
991
992 e = parser.parseExpression("sss--");
993 assertEquals(15,helper.sss);
994 short return_sss = e.getValue(ctx,Short.TYPE);
995 assertEquals(15,return_sss);
996 assertEquals(14,helper.sss);
997 }
998
999 @Test
1000 public void decrement02prefix() {
1001 Spr9751 helper = new Spr9751();
1002 StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
1003 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
1004 Expression e = null;
1005
1006
1007 e = parser.parseExpression("--bd");
1008 assertTrue(new BigDecimal("2").equals(helper.bd));
1009 BigDecimal return_bd = e.getValue(ctx,BigDecimal.class);
1010 assertTrue(new BigDecimal("1").equals(return_bd));
1011 assertTrue(new BigDecimal("1").equals(helper.bd));
1012
1013
1014 e = parser.parseExpression("--ddd");
1015 assertEquals(2.0d,helper.ddd,0d);
1016 double return_ddd = e.getValue(ctx,Double.TYPE);
1017 assertEquals(1.0d,return_ddd,0d);
1018 assertEquals(1.0d,helper.ddd,0d);
1019
1020
1021 e = parser.parseExpression("--fff");
1022 assertEquals(3.0f,helper.fff,0d);
1023 float return_fff = e.getValue(ctx,Float.TYPE);
1024 assertEquals(2.0f,return_fff,0d);
1025 assertEquals(2.0f,helper.fff,0d);
1026
1027
1028 e = parser.parseExpression("--lll");
1029 assertEquals(66666L,helper.lll);
1030 long return_lll = e.getValue(ctx,Long.TYPE);
1031 assertEquals(66665L,return_lll);
1032 assertEquals(66665L,helper.lll);
1033
1034
1035 e = parser.parseExpression("--iii");
1036 assertEquals(42,helper.iii);
1037 int return_iii = e.getValue(ctx,Integer.TYPE);
1038 assertEquals(41,return_iii);
1039 assertEquals(41,helper.iii);
1040 return_iii = e.getValue(ctx,Integer.TYPE);
1041 assertEquals(40,return_iii);
1042 assertEquals(40,helper.iii);
1043
1044
1045 e = parser.parseExpression("--sss");
1046 assertEquals(15,helper.sss);
1047 int return_sss = (Integer)e.getValue(ctx);
1048 assertEquals(14,return_sss);
1049 assertEquals(14,helper.sss);
1050 }
1051
1052 @Test
1053 public void decrement03() {
1054 Spr9751 helper = new Spr9751();
1055 StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
1056 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
1057 Expression e = null;
1058
1059 e = parser.parseExpression("m()--");
1060 try {
1061 e.getValue(ctx,Double.TYPE);
1062 fail();
1063 } catch (SpelEvaluationException see) {
1064 assertEquals(SpelMessage.OPERAND_NOT_DECREMENTABLE,see.getMessageCode());
1065 }
1066
1067 e = parser.parseExpression("--m()");
1068 try {
1069 e.getValue(ctx,Double.TYPE);
1070 fail();
1071 } catch (SpelEvaluationException see) {
1072 assertEquals(SpelMessage.OPERAND_NOT_DECREMENTABLE,see.getMessageCode());
1073 }
1074 }
1075
1076
1077 @Test
1078 public void decrement04() {
1079 Integer i = 42;
1080 StandardEvaluationContext ctx = new StandardEvaluationContext(i);
1081 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
1082 try {
1083 Expression e = parser.parseExpression("--1");
1084 e.getValue(ctx,Integer.class);
1085 fail();
1086 } catch (SpelEvaluationException see) {
1087 assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
1088 }
1089 try {
1090 Expression e = parser.parseExpression("1--");
1091 e.getValue(ctx,Integer.class);
1092 fail();
1093 } catch (SpelEvaluationException see) {
1094 assertEquals(SpelMessage.NOT_ASSIGNABLE,see.getMessageCode());
1095 }
1096 }
1097
1098 @Test
1099 public void incdecTogether() {
1100 Spr9751 helper = new Spr9751();
1101 StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
1102 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
1103 Expression e = null;
1104
1105
1106
1107 e = parser.parseExpression("intArray[#root.index1++]++");
1108 e.getValue(ctx,Integer.class);
1109 assertEquals(3,helper.index1);
1110 assertEquals(4,helper.intArray[2]);
1111
1112
1113 e = parser.parseExpression("intArray[#root.index1++]--");
1114 assertEquals(4,e.getValue(ctx,Integer.class).intValue());
1115 assertEquals(4,helper.index1);
1116 assertEquals(3,helper.intArray[3]);
1117
1118
1119 e = parser.parseExpression("intArray[--#root.index1]++");
1120 assertEquals(3,e.getValue(ctx,Integer.class).intValue());
1121 assertEquals(3,helper.index1);
1122 assertEquals(4,helper.intArray[3]);
1123 }
1124
1125
1126
1127
1128 private void expectFail(ExpressionParser parser, EvaluationContext eContext, String expressionString, SpelMessage messageCode) {
1129 try {
1130 Expression e = parser.parseExpression(expressionString);
1131 SpelUtilities.printAbstractSyntaxTree(System.out, e);
1132 e.getValue(eContext);
1133 fail();
1134 } catch (SpelEvaluationException see) {
1135 see.printStackTrace();
1136 assertEquals(messageCode,see.getMessageCode());
1137 }
1138 }
1139
1140 private void expectFailNotAssignable(ExpressionParser parser, EvaluationContext eContext, String expressionString) {
1141 expectFail(parser,eContext,expressionString,SpelMessage.NOT_ASSIGNABLE);
1142 }
1143
1144 private void expectFailSetValueNotSupported(ExpressionParser parser, EvaluationContext eContext, String expressionString) {
1145 expectFail(parser,eContext,expressionString,SpelMessage.SETVALUE_NOT_SUPPORTED);
1146 }
1147
1148 private void expectFailNotIncrementable(ExpressionParser parser, EvaluationContext eContext, String expressionString) {
1149 expectFail(parser,eContext,expressionString,SpelMessage.OPERAND_NOT_INCREMENTABLE);
1150 }
1151
1152 private void expectFailNotDecrementable(ExpressionParser parser, EvaluationContext eContext, String expressionString) {
1153 expectFail(parser,eContext,expressionString,SpelMessage.OPERAND_NOT_DECREMENTABLE);
1154 }
1155
1156
1157 @Test
1158 public void incrementAllNodeTypes() throws SecurityException, NoSuchMethodException {
1159 Spr9751 helper = new Spr9751();
1160 StandardEvaluationContext ctx = new StandardEvaluationContext(helper);
1161 ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
1162 Expression e = null;
1163
1164
1165 expectFailNotAssignable(parser, ctx, "true++");
1166 expectFailNotAssignable(parser, ctx, "--false");
1167 expectFailSetValueNotSupported(parser, ctx, "true=false");
1168
1169
1170 expectFailNotAssignable(parser, ctx, "12++");
1171 expectFailNotAssignable(parser, ctx, "--1222");
1172 expectFailSetValueNotSupported(parser, ctx, "12=16");
1173
1174
1175 expectFailNotAssignable(parser, ctx, "1.0d++");
1176 expectFailNotAssignable(parser, ctx, "--3.4d");
1177 expectFailSetValueNotSupported(parser, ctx, "1.0d=3.2d");
1178
1179
1180 expectFailNotAssignable(parser, ctx, "null++");
1181 expectFailNotAssignable(parser, ctx, "--null");
1182 expectFailSetValueNotSupported(parser, ctx, "null=null");
1183 expectFailSetValueNotSupported(parser, ctx, "null=123");
1184
1185
1186 expectFailNotAssignable(parser, ctx, "(true && false)++");
1187 expectFailNotAssignable(parser, ctx, "--(false AND true)");
1188 expectFailSetValueNotSupported(parser, ctx, "(true && false)=(false && true)");
1189
1190
1191 expectFailNotAssignable(parser, ctx, "(3/4)++");
1192 expectFailNotAssignable(parser, ctx, "--(2/5)");
1193 expectFailSetValueNotSupported(parser, ctx, "(1/2)=(3/4)");
1194
1195
1196 expectFailNotAssignable(parser, ctx, "(3==4)++");
1197 expectFailNotAssignable(parser, ctx, "--(2==5)");
1198 expectFailSetValueNotSupported(parser, ctx, "(1==2)=(3==4)");
1199
1200
1201 expectFailNotAssignable(parser, ctx, "(3>=4)++");
1202 expectFailNotAssignable(parser, ctx, "--(2>=5)");
1203 expectFailSetValueNotSupported(parser, ctx, "(1>=2)=(3>=4)");
1204
1205
1206 expectFailNotAssignable(parser, ctx, "(3>4)++");
1207 expectFailNotAssignable(parser, ctx, "--(2>5)");
1208 expectFailSetValueNotSupported(parser, ctx, "(1>2)=(3>4)");
1209
1210
1211 expectFailNotAssignable(parser, ctx, "(3<=4)++");
1212 expectFailNotAssignable(parser, ctx, "--(2<=5)");
1213 expectFailSetValueNotSupported(parser, ctx, "(1<=2)=(3<=4)");
1214
1215
1216 expectFailNotAssignable(parser, ctx, "(3<4)++");
1217 expectFailNotAssignable(parser, ctx, "--(2<5)");
1218 expectFailSetValueNotSupported(parser, ctx, "(1<2)=(3<4)");
1219
1220
1221 expectFailNotAssignable(parser, ctx, "(3-4)++");
1222 expectFailNotAssignable(parser, ctx, "--(2-5)");
1223 expectFailSetValueNotSupported(parser, ctx, "(1-2)=(3-4)");
1224
1225
1226 expectFailNotAssignable(parser, ctx, "(3%4)++");
1227 expectFailNotAssignable(parser, ctx, "--(2%5)");
1228 expectFailSetValueNotSupported(parser, ctx, "(1%2)=(3%4)");
1229
1230
1231 expectFailNotAssignable(parser, ctx, "(3*4)++");
1232 expectFailNotAssignable(parser, ctx, "--(2*5)");
1233 expectFailSetValueNotSupported(parser, ctx, "(1*2)=(3*4)");
1234
1235
1236 expectFailNotAssignable(parser, ctx, "(3!=4)++");
1237 expectFailNotAssignable(parser, ctx, "--(2!=5)");
1238 expectFailSetValueNotSupported(parser, ctx, "(1!=2)=(3!=4)");
1239
1240
1241 expectFailNotAssignable(parser, ctx, "(true || false)++");
1242 expectFailNotAssignable(parser, ctx, "--(false OR true)");
1243 expectFailSetValueNotSupported(parser, ctx, "(true || false)=(false OR true)");
1244
1245
1246 expectFailNotAssignable(parser, ctx, "(3+4)++");
1247 expectFailNotAssignable(parser, ctx, "--(2+5)");
1248 expectFailSetValueNotSupported(parser, ctx, "(1+2)=(3+4)");
1249
1250
1251 expectFailNotAssignable(parser, ctx, "1.0d++");
1252 expectFailNotAssignable(parser, ctx, "--2.0d");
1253 expectFailSetValueNotSupported(parser, ctx, "(1.0d)=(3.0d)");
1254 expectFailNotAssignable(parser, ctx, "1.0f++");
1255 expectFailNotAssignable(parser, ctx, "--2.0f");
1256 expectFailSetValueNotSupported(parser, ctx, "(1.0f)=(3.0f)");
1257
1258
1259 expectFailNotAssignable(parser, ctx, "'abc'++");
1260 expectFailNotAssignable(parser, ctx, "--'def'");
1261 expectFailSetValueNotSupported(parser, ctx, "'abc'='def'");
1262
1263
1264 expectFailNotAssignable(parser, ctx, "(true?true:false)++");
1265 expectFailNotAssignable(parser, ctx, "--(true?true:false)");
1266 expectFailSetValueNotSupported(parser, ctx, "(true?true:false)=(true?true:false)");
1267
1268
1269 expectFailNotAssignable(parser, ctx, "T(String)++");
1270 expectFailNotAssignable(parser, ctx, "--T(Integer)");
1271 expectFailSetValueNotSupported(parser, ctx, "T(String)=T(Integer)");
1272
1273
1274 expectFailNotAssignable(parser, ctx, "(3 between {1,5})++");
1275 expectFailNotAssignable(parser, ctx, "--(3 between {1,5})");
1276 expectFailSetValueNotSupported(parser, ctx, "(3 between {1,5})=(3 between {1,5})");
1277
1278
1279 expectFailNotAssignable(parser, ctx, "(type instanceof T(String))++");
1280 expectFailNotAssignable(parser, ctx, "--(type instanceof T(String))");
1281 expectFailSetValueNotSupported(parser, ctx, "(type instanceof T(String))=(type instanceof T(String))");
1282
1283
1284 expectFailNotAssignable(parser, ctx, "(true?:false)++");
1285 expectFailNotAssignable(parser, ctx, "--(true?:false)");
1286 expectFailSetValueNotSupported(parser, ctx, "(true?:false)=(true?:false)");
1287
1288
1289 expectFailNotAssignable(parser, ctx, "(iii++)++");
1290 expectFailNotAssignable(parser, ctx, "--(++iii)");
1291 expectFailSetValueNotSupported(parser, ctx, "(iii++)=(++iii)");
1292
1293
1294 expectFailNotAssignable(parser, ctx, "(iii--)++");
1295 expectFailNotAssignable(parser, ctx, "--(--iii)");
1296 expectFailSetValueNotSupported(parser, ctx, "(iii--)=(--iii)");
1297
1298
1299 expectFailNotAssignable(parser, ctx, "(!true)++");
1300 expectFailNotAssignable(parser, ctx, "--(!false)");
1301 expectFailSetValueNotSupported(parser, ctx, "(!true)=(!false)");
1302
1303
1304 expectFailNotAssignable(parser, ctx, "(iii^2)++");
1305 expectFailNotAssignable(parser, ctx, "--(iii^2)");
1306 expectFailSetValueNotSupported(parser, ctx, "(iii^2)=(iii^3)");
1307
1308
1309
1310 e = parser.parseExpression("iii=iii++");
1311 assertEquals(42,helper.iii);
1312 int return_iii = e.getValue(ctx,Integer.TYPE);
1313 assertEquals(42,helper.iii);
1314 assertEquals(42,return_iii);
1315
1316
1317 e = parser.parseExpression("iii++");
1318 assertEquals(42,helper.iii);
1319 return_iii = e.getValue(ctx,Integer.TYPE);
1320 assertEquals(42,return_iii);
1321 assertEquals(43,helper.iii);
1322
1323 e = parser.parseExpression("--iii");
1324 assertEquals(43,helper.iii);
1325 return_iii = e.getValue(ctx,Integer.TYPE);
1326 assertEquals(42,return_iii);
1327 assertEquals(42,helper.iii);
1328
1329 e = parser.parseExpression("iii=99");
1330 assertEquals(42,helper.iii);
1331 return_iii = e.getValue(ctx,Integer.TYPE);
1332 assertEquals(99,return_iii);
1333 assertEquals(99,helper.iii);
1334
1335
1336
1337 e = parser.parseExpression("foo.iii++");
1338 assertEquals(99,helper.foo.iii);
1339 int return_foo_iii = e.getValue(ctx,Integer.TYPE);
1340 assertEquals(99,return_foo_iii);
1341 assertEquals(100,helper.foo.iii);
1342
1343 e = parser.parseExpression("--foo.iii");
1344 assertEquals(100,helper.foo.iii);
1345 return_foo_iii = e.getValue(ctx,Integer.TYPE);
1346 assertEquals(99,return_foo_iii);
1347 assertEquals(99,helper.foo.iii);
1348
1349 e = parser.parseExpression("foo.iii=999");
1350 assertEquals(99,helper.foo.iii);
1351 return_foo_iii = e.getValue(ctx,Integer.TYPE);
1352 assertEquals(999,return_foo_iii);
1353 assertEquals(999,helper.foo.iii);
1354
1355
1356 expectFailNotAssignable(parser, ctx, "(new String('abc'))++");
1357 expectFailNotAssignable(parser, ctx, "--(new String('abc'))");
1358 expectFailSetValueNotSupported(parser, ctx, "(new String('abc'))=(new String('abc'))");
1359
1360
1361 expectFailNotIncrementable(parser, ctx, "m()++");
1362 expectFailNotDecrementable(parser, ctx, "--m()");
1363 expectFailSetValueNotSupported(parser, ctx, "m()=m()");
1364
1365
1366 expectFailNotAssignable(parser, ctx, "('abc' matches '^a..')++");
1367 expectFailNotAssignable(parser, ctx, "--('abc' matches '^a..')");
1368 expectFailSetValueNotSupported(parser, ctx, "('abc' matches '^a..')=('abc' matches '^a..')");
1369
1370
1371 ctx.registerFunction("isEven", Spr9751.class.getDeclaredMethod("isEven", Integer.TYPE));
1372
1373 expectFailNotIncrementable(parser, ctx, "({1,2,3}.?[#isEven(#this)])++");
1374 expectFailNotDecrementable(parser, ctx, "--({1,2,3}.?[#isEven(#this)])");
1375 expectFailNotAssignable(parser, ctx, "({1,2,3}.?[#isEven(#this)])=({1,2,3}.?[#isEven(#this)])");
1376
1377
1378 expectFailNotAssignable(parser, ctx, "({1,2,3}.^[#isEven(#this)])++");
1379 expectFailNotAssignable(parser, ctx, "--({1,2,3}.^[#isEven(#this)])");
1380 expectFailNotAssignable(parser, ctx, "({1,2,3}.^[#isEven(#this)])=({1,2,3}.^[#isEven(#this)])");
1381
1382 expectFailNotAssignable(parser, ctx, "({1,2,3}.$[#isEven(#this)])++");
1383 expectFailNotAssignable(parser, ctx, "--({1,2,3}.$[#isEven(#this)])");
1384 expectFailNotAssignable(parser, ctx, "({1,2,3}.$[#isEven(#this)])=({1,2,3}.$[#isEven(#this)])");
1385
1386
1387 expectFailNotAssignable(parser, ctx, "#isEven(3)++");
1388 expectFailNotAssignable(parser, ctx, "--#isEven(4)");
1389 expectFailSetValueNotSupported(parser, ctx, "#isEven(3)=#isEven(5)");
1390
1391
1392 ctx.setVariable("wibble", "hello world");
1393 expectFailNotIncrementable(parser, ctx, "#wibble++");
1394 expectFailNotDecrementable(parser, ctx, "--#wibble");
1395 e = parser.parseExpression("#wibble=#wibble+#wibble");
1396 String s = e.getValue(ctx,String.class);
1397 assertEquals("hello worldhello world",s);
1398 assertEquals("hello worldhello world",ctx.lookupVariable("wibble"));
1399
1400 ctx.setVariable("wobble", 3);
1401 e = parser.parseExpression("#wobble++");
1402 assertEquals(3,((Integer)ctx.lookupVariable("wobble")).intValue());
1403 int r = e.getValue(ctx,Integer.TYPE);
1404 assertEquals(3,r);
1405 assertEquals(4,((Integer)ctx.lookupVariable("wobble")).intValue());
1406
1407 e = parser.parseExpression("--#wobble");
1408 assertEquals(4,((Integer)ctx.lookupVariable("wobble")).intValue());
1409 r = e.getValue(ctx,Integer.TYPE);
1410 assertEquals(3,r);
1411 assertEquals(3,((Integer)ctx.lookupVariable("wobble")).intValue());
1412
1413 e = parser.parseExpression("#wobble=34");
1414 assertEquals(3,((Integer)ctx.lookupVariable("wobble")).intValue());
1415 r = e.getValue(ctx,Integer.TYPE);
1416 assertEquals(34,r);
1417 assertEquals(34,((Integer)ctx.lookupVariable("wobble")).intValue());
1418
1419
1420 expectFailNotIncrementable(parser, ctx, "({1,2,3}.![#isEven(#this)])++");
1421 expectFailNotDecrementable(parser, ctx, "--({1,2,3}.![#isEven(#this)])");
1422 expectFailNotAssignable(parser, ctx, "({1,2,3}.![#isEven(#this)])=({1,2,3}.![#isEven(#this)])");
1423
1424
1425 expectFailNotAssignable(parser, ctx, "({1,2,3})++");
1426 expectFailNotAssignable(parser, ctx, "--({1,2,3})");
1427 expectFailSetValueNotSupported(parser, ctx, "({1,2,3})=({1,2,3})");
1428
1429
1430 expectFailNotAssignable(parser, ctx, "({'a':1,'b':2,'c':3})++");
1431 expectFailNotAssignable(parser, ctx, "--({'a':1,'b':2,'c':3})");
1432 expectFailSetValueNotSupported(parser, ctx, "({'a':1,'b':2,'c':3})=({'a':1,'b':2,'c':3})");
1433
1434
1435 ctx.setBeanResolver(new MyBeanResolver());
1436 expectFailNotAssignable(parser, ctx, "@foo++");
1437 expectFailNotAssignable(parser, ctx, "--@foo");
1438 expectFailSetValueNotSupported(parser, ctx, "@foo=@bar");
1439
1440
1441 helper.iii = 42;
1442 e = parser.parseExpression("iii++");
1443 assertEquals(42,helper.iii);
1444 r = e.getValue(ctx,Integer.TYPE);
1445 assertEquals(42,r);
1446 assertEquals(43,helper.iii);
1447
1448 e = parser.parseExpression("--iii");
1449 assertEquals(43,helper.iii);
1450 r = e.getValue(ctx,Integer.TYPE);
1451 assertEquals(42,r);
1452 assertEquals(42,helper.iii);
1453
1454 e = parser.parseExpression("iii=100");
1455 assertEquals(42,helper.iii);
1456 r = e.getValue(ctx,Integer.TYPE);
1457 assertEquals(100,r);
1458 assertEquals(100,helper.iii);
1459
1460 }
1461
1462 static class MyBeanResolver implements BeanResolver {
1463
1464 @Override
1465 public Object resolve(EvaluationContext context, String beanName)
1466 throws AccessException {
1467 if (beanName.equals("foo") || beanName.equals("bar")) {
1468 return new Spr9751_2();
1469 }
1470 throw new AccessException("not heard of "+beanName);
1471 }
1472
1473 }
1474
1475
1476 }