1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.jexl;
17
18 import java.io.StringReader;
19 import java.math.BigDecimal;
20 import java.math.BigInteger;
21 import java.util.ArrayList;
22 import java.util.BitSet;
23 import java.util.Calendar;
24 import java.util.Collections;
25 import java.util.GregorianCalendar;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.LinkedList;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32
33 import junit.framework.Test;
34 import junit.framework.TestCase;
35 import junit.framework.TestSuite;
36
37 import org.apache.commons.jexl.parser.ParseException;
38 import org.apache.commons.jexl.parser.Parser;
39 import org.apache.commons.jexl.resolver.FlatResolver;
40
41 /***
42 * Simple testcases
43 *
44 * @since 1.0
45 * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
46 * @version $Id: JexlTest.java 391888 2006-04-06 03:34:59Z dion $
47 */
48 public class JexlTest extends TestCase
49 {
50 protected static final String METHOD_STRING = "Method string";
51 protected static final String GET_METHOD_STRING = "GetMethod string";
52
53 protected static final String[] GET_METHOD_ARRAY =
54 new String[] { "One", "Two", "Three" };
55
56 protected static final String[][] GET_METHOD_ARRAY2 =
57 new String[][] { {"One", "Two", "Three"},{"Four", "Five", "Six"} };
58
59 public static Test suite()
60 {
61 return new TestSuite(JexlTest.class);
62 }
63
64 public JexlTest(String testName)
65 {
66 super(testName);
67 }
68
69 /***
70 * test a simple property expression
71 */
72 public void testProperty()
73 throws Exception
74 {
75
76
77
78
79 Expression e = ExpressionFactory.createExpression("foo.bar");
80 JexlContext jc = JexlHelper.createContext();
81
82 jc.getVars().put("foo", new Foo() );
83 Object o = e.evaluate(jc);
84
85 assertTrue("o not instanceof String", o instanceof String);
86 assertEquals("o incorrect", GET_METHOD_STRING, o);
87 }
88
89 /***
90 * test a simple method expression
91 */
92 public void testMethod()
93 throws Exception
94 {
95
96
97
98 JexlContext jc = JexlHelper.createContext();
99 jc.getVars().put("foo", new Foo() );
100 assertExpression(jc, "foo.bar()", METHOD_STRING);
101 }
102
103 /***
104 * test a simple method expression
105 */
106 public void testArrayAccess()
107 throws Exception
108 {
109 JexlContext jc = JexlHelper.createContext();
110
111
112
113
114
115 List l = new ArrayList();
116 l.add(new Integer(1));
117 l.add(new Integer(2));
118 l.add(new Integer(3));
119
120 jc.getVars().put("list", l);
121
122 assertExpression(jc, "list[1]", new Integer(2));
123 assertExpression(jc, "list[1+1]", new Integer(3));
124 jc.getVars().put("loc", new Integer(1));
125 assertExpression(jc, "list[loc+1]", new Integer(3));
126
127
128
129
130
131 String[] args = {"hello", "there"};
132 jc.getVars().put("array", args);
133 assertExpression(jc, "array[0]", "hello");
134
135
136
137
138 assertExpression(jc, "array.0", "hello");
139
140
141
142
143 Map m = new HashMap();
144 m.put("foo", "bar");
145
146 jc.getVars().put("map", m);
147 jc.getVars().put("key", "foo");
148
149 assertExpression(jc, "map[\"foo\"]", "bar");
150 assertExpression(jc, "map[key]", "bar");
151
152
153
154
155 jc.getVars().put("foo", new Foo());
156 assertExpression(jc, "foo[\"bar\"]", GET_METHOD_STRING);
157 assertExpression(jc, "foo[\"bar\"] == foo.bar", Boolean.TRUE);
158
159 }
160
161 public void testMulti()
162 throws Exception
163 {
164
165
166
167 JexlContext jc = JexlHelper.createContext();
168 jc.getVars().put("foo", new Foo() );
169 assertExpression(jc, "foo.innerFoo.bar()", METHOD_STRING);
170 }
171
172 public void testBoolean()
173 throws Exception
174 {
175 JexlContext jc = JexlHelper.createContext();
176 jc.getVars().put("foo", new Foo() );
177 jc.getVars().put("a", Boolean.TRUE);
178 jc.getVars().put("b", Boolean.FALSE);
179
180 assertExpression(jc, "foo.convertBoolean(a==b)", "Boolean : false");
181 assertExpression(jc, "foo.convertBoolean(a==true)", "Boolean : true");
182 assertExpression(jc, "foo.convertBoolean(a==false)", "Boolean : false");
183 assertExpression(jc, "foo.convertBoolean(true==false)", "Boolean : false");
184 assertExpression(jc, "true eq false", Boolean.FALSE);
185 assertExpression(jc, "true ne false", Boolean.TRUE);
186 }
187
188 public void testStringLit()
189 throws Exception
190 {
191
192
193
194 JexlContext jc = JexlHelper.createContext();
195 jc.getVars().put("foo", new Foo() );
196 assertExpression(jc, "foo.get(\"woogie\")", "Repeat : woogie");
197 }
198
199 public void testExpression()
200 throws Exception
201 {
202 JexlContext jc = JexlHelper.createContext();
203 jc.getVars().put("foo", new Foo() );
204 jc.getVars().put("a", Boolean.TRUE);
205 jc.getVars().put("b", Boolean.FALSE);
206 jc.getVars().put("num", new Integer(5));
207 jc.getVars().put("now", Calendar.getInstance().getTime());
208 GregorianCalendar gc = new GregorianCalendar(5000, 11, 20);
209 jc.getVars().put("now2", gc.getTime());
210
211 assertExpression(jc, "a == b", Boolean.FALSE);
212 assertExpression(jc, "a==true", Boolean.TRUE);
213 assertExpression(jc, "a==false", Boolean.FALSE);
214 assertExpression(jc, "true==false", Boolean.FALSE);
215
216 assertExpression(jc, "2 < 3", Boolean.TRUE);
217 assertExpression(jc, "num < 5", Boolean.FALSE);
218 assertExpression(jc, "num < num", Boolean.FALSE);
219 assertExpression(jc, "num < null", Boolean.FALSE);
220 assertExpression(jc, "num < 2.5", Boolean.FALSE);
221 assertExpression(jc, "now2 < now", Boolean.FALSE);
222
223 assertExpression(jc, "'6' <= '5'", Boolean.FALSE);
224 assertExpression(jc, "num <= 5", Boolean.TRUE);
225 assertExpression(jc, "num <= num", Boolean.TRUE);
226 assertExpression(jc, "num <= null", Boolean.FALSE);
227 assertExpression(jc, "num <= 2.5", Boolean.FALSE);
228 assertExpression(jc, "now2 <= now", Boolean.FALSE);
229
230
231 assertExpression(jc, "'6' >= '5'", Boolean.TRUE);
232 assertExpression(jc, "num >= 5", Boolean.TRUE);
233 assertExpression(jc, "num >= num", Boolean.TRUE);
234 assertExpression(jc, "num >= null", Boolean.FALSE);
235 assertExpression(jc, "num >= 2.5", Boolean.TRUE);
236 assertExpression(jc, "now2 >= now", Boolean.TRUE);
237
238 assertExpression(jc, "'6' > '5'", Boolean.TRUE);
239 assertExpression(jc, "num > 4", Boolean.TRUE);
240 assertExpression(jc, "num > num", Boolean.FALSE);
241 assertExpression(jc, "num > null", Boolean.FALSE);
242 assertExpression(jc, "num > 2.5", Boolean.TRUE);
243 assertExpression(jc, "now2 > now", Boolean.TRUE);
244
245 assertExpression(jc, "\"foo\" + \"bar\" == \"foobar\"", Boolean.TRUE);
246
247 }
248
249 public void testEmpty()
250 throws Exception
251 {
252 JexlContext jc = JexlHelper.createContext();
253 jc.getVars().put("string", "");
254 jc.getVars().put("array", new Object[0]);
255 jc.getVars().put("map", new HashMap());
256 jc.getVars().put("list", new ArrayList());
257 jc.getVars().put("set", (new HashMap()).keySet());
258 jc.getVars().put("longstring", "thingthing");
259
260
261
262
263 assertExpression(jc, "empty nullthing", Boolean.TRUE);
264 assertExpression(jc, "empty string", Boolean.TRUE);
265 assertExpression(jc, "empty array", Boolean.TRUE);
266 assertExpression(jc, "empty map", Boolean.TRUE);
267 assertExpression(jc, "empty set", Boolean.TRUE);
268 assertExpression(jc, "empty list", Boolean.TRUE);
269 assertExpression(jc, "empty longstring", Boolean.FALSE);
270 assertExpression(jc, "not empty longstring", Boolean.TRUE);
271 }
272
273 public void testSize()
274 throws Exception
275 {
276 JexlContext jc = JexlHelper.createContext();
277 jc.getVars().put("s", "five!");
278 jc.getVars().put("array", new Object[5]);
279
280 Map map = new HashMap();
281
282 map.put("1", new Integer(1));
283 map.put("2", new Integer(2));
284 map.put("3", new Integer(3));
285 map.put("4", new Integer(4));
286 map.put("5", new Integer(5));
287
288 jc.getVars().put("map", map);
289
290 List list = new ArrayList();
291
292 list.add("1");
293 list.add("2");
294 list.add("3");
295 list.add("4");
296 list.add("5");
297
298 jc.getVars().put("list", list);
299
300
301 Set set = new HashSet();
302 set.addAll(list);
303 set.add("1");
304
305 jc.getVars().put("set", set);
306
307
308 BitSet bitset = new BitSet(5);
309 jc.getVars().put("bitset", bitset);
310
311 assertExpression(jc, "size(s)", new Integer(5));
312 assertExpression(jc, "size(array)", new Integer(5));
313 assertExpression(jc, "size(list)", new Integer(5));
314 assertExpression(jc, "size(map)", new Integer(5));
315 assertExpression(jc, "size(set)", new Integer(5));
316 assertExpression(jc, "size(bitset)", new Integer(64));
317 assertExpression(jc, "list.size()", new Integer(5));
318 assertExpression(jc, "map.size()", new Integer(5));
319 assertExpression(jc, "set.size()", new Integer(5));
320 assertExpression(jc, "bitset.size()", new Integer(64));
321
322 assertExpression(jc, "list.get(size(list) - 1)", "5");
323 assertExpression(jc, "list[size(list) - 1]", "5");
324 assertExpression(jc, "list.get(list.size() - 1)", "5");
325 }
326
327 public void testSizeAsProperty() throws Exception
328 {
329 JexlContext jc = JexlHelper.createContext();
330
331 jc.getVars().put("map", Collections.singletonMap( "size", "cheese"));
332 jc.getVars().put("foo", new Foo());
333
334 assertExpression(jc, "map['size']", "cheese");
335
336
337 assertExpression(jc, "foo.getSize()", new Integer(22));
338
339
340 }
341
342 /***
343 * test some String method calls
344 */
345 public void testStringMethods()
346 throws Exception
347 {
348 JexlContext jc = JexlHelper.createContext();
349
350 jc.getVars().put("foo", "abcdef");
351
352 assertExpression(jc, "foo.substring(3)", "def");
353 assertExpression(jc, "foo.substring(0,(size(foo)-3))", "abc");
354 assertExpression(jc, "foo.substring(0,size(foo)-3)", "abc");
355 assertExpression(jc, "foo.substring(0,foo.length()-3)", "abc");
356 assertExpression(jc, "foo.substring(0, 1+1)", "ab");
357 }
358
359
360
361 /***
362 * test some simple mathematical calculations
363 */
364 public void testUnaryMinus()
365 throws Exception
366 {
367 JexlContext jc = JexlHelper.createContext();
368
369 jc.getVars().put("aByte", new Byte((byte)1));
370 jc.getVars().put("aShort", new Short((short)2));
371 jc.getVars().put("anInteger", new Integer(3));
372 jc.getVars().put("aLong", new Long(4));
373 jc.getVars().put("aFloat", new Float(5.5));
374 jc.getVars().put("aDouble", new Double(6.6));
375 jc.getVars().put("aBigInteger", new BigInteger("7"));
376 jc.getVars().put("aBigDecimal", new BigDecimal("8.8"));
377 assertExpression(jc, "-3", new Integer("-3"));
378 assertExpression(jc, "-3.0", new Float("-3.0"));
379 assertExpression(jc, "-aByte", new Byte((byte)-1));
380 assertExpression(jc, "-aShort", new Short((short)-2));
381 assertExpression(jc, "-anInteger", new Integer(-3));
382 assertExpression(jc, "-aLong", new Long(-4));
383 assertExpression(jc, "-aFloat", new Float(-5.5));
384 assertExpression(jc, "-aDouble", new Double(-6.6));
385 assertExpression(jc, "-aBigInteger", new BigInteger("-7"));
386 assertExpression(jc, "-aBigDecimal", new BigDecimal("-8.8"));
387 }
388
389
390 /***
391 * test some simple mathematical calculations
392 */
393 public void testCalculations()
394 throws Exception
395 {
396 JexlContext jc = JexlHelper.createContext();
397
398 jc.getVars().put("foo", new Integer(2) );
399
400 assertExpression(jc, "foo + 2", new Long(4));
401 assertExpression(jc, "3 + 3", new Long(6));
402 assertExpression(jc, "3 + 3 + foo", new Long(8));
403 assertExpression(jc, "3 * 3", new Long(9));
404 assertExpression(jc, "3 * 3 + foo", new Long(11));
405 assertExpression(jc, "3 * 3 - foo", new Long(7));
406
407
408
409
410 assertExpression(jc, "3 * \"3.0\"", new Double(9));
411 assertExpression(jc, "3 * 3.0", new Double(9));
412
413
414
415
416 assertExpression(jc, "6 / 3", new Double(6/3));
417 assertExpression(jc, "6.4 / 3", new Double(6.4 / 3));
418 assertExpression(jc, "0 / 3", new Double(0 / 3));
419 assertExpression(jc, "3 / 0", new Double(0));
420 assertExpression(jc, "4 % 3", new Long(1));
421 assertExpression(jc, "4.8 % 3", new Double(4.8 % 3));
422
423
424
425
426 jc.getVars().put("stringy", "thingy" );
427 assertExpression(jc, "stringy + 2", "thingy2");
428
429
430
431
432 jc.getVars().put("imanull", null );
433 assertExpression(jc, "imanull + 2", new Long(2));
434 assertExpression(jc, "imanull + imanull", new Long(0));
435
436
437 jc.getVars().put("n", new Integer(0));
438 assertExpression(jc, "n != null && n != 0", Boolean.FALSE);
439 }
440
441 /***
442 * test some simple conditions
443 */
444 public void testConditions()
445 throws Exception
446 {
447 JexlContext jc = JexlHelper.createContext();
448 jc.getVars().put("foo", new Integer(2) );
449 jc.getVars().put("aFloat", new Float(1));
450 jc.getVars().put("aDouble", new Double(2));
451 jc.getVars().put("aChar", new Character('A'));
452 jc.getVars().put("aBool", Boolean.TRUE);
453 StringBuffer buffer = new StringBuffer("abc");
454 List list = new ArrayList();
455 List list2 = new LinkedList();
456 jc.getVars().put("aBuffer", buffer);
457 jc.getVars().put("aList", list);
458 jc.getVars().put("bList", list2);
459
460 assertExpression(jc, "foo == 2", Boolean.TRUE);
461 assertExpression(jc, "2 == 3", Boolean.FALSE);
462 assertExpression(jc, "3 == foo", Boolean.FALSE);
463 assertExpression(jc, "3 != foo", Boolean.TRUE);
464 assertExpression(jc, "foo != 2", Boolean.FALSE);
465
466 assertExpression(jc, "aFloat eq aDouble", Boolean.FALSE);
467 assertExpression(jc, "aFloat ne aDouble", Boolean.TRUE);
468 assertExpression(jc, "aFloat == aDouble", Boolean.FALSE);
469 assertExpression(jc, "aFloat != aDouble", Boolean.TRUE);
470
471 assertExpression(jc, "foo == aChar", Boolean.FALSE);
472 assertExpression(jc, "foo != aChar", Boolean.TRUE);
473
474 assertExpression(jc, "aBool == 'true'", Boolean.TRUE);
475 assertExpression(jc, "aBool == 'false'", Boolean.FALSE);
476 assertExpression(jc, "aBool != 'false'", Boolean.TRUE);
477
478 assertExpression(jc, "aBool == notThere", Boolean.FALSE);
479 assertExpression(jc, "aBool != notThere", Boolean.TRUE);
480
481 assertExpression(jc, "aBuffer == 'abc'", Boolean.TRUE);
482 assertExpression(jc, "aBuffer != 'abc'", Boolean.FALSE);
483
484 assertExpression(jc, "aList == bList", Boolean.TRUE);
485 assertExpression(jc, "aList != bList", Boolean.FALSE);
486 }
487
488 /***
489 * test some simple conditions
490 */
491 public void testNotConditions()
492 throws Exception
493 {
494 JexlContext jc = JexlHelper.createContext();
495
496 Foo foo = new Foo();
497 jc.getVars().put("x", Boolean.TRUE );
498 jc.getVars().put("foo", foo );
499 jc.getVars().put("bar", "true" );
500
501 assertExpression(jc, "!x", Boolean.FALSE);
502 assertExpression(jc, "x", Boolean.TRUE);
503 assertExpression(jc, "!bar", Boolean.FALSE);
504 assertExpression(jc, "!foo.isSimple()", Boolean.FALSE);
505 assertExpression(jc, "foo.isSimple()", Boolean.TRUE);
506 assertExpression(jc, "!foo.simple", Boolean.FALSE);
507 assertExpression(jc, "foo.simple", Boolean.TRUE);
508 assertExpression(jc, "foo.getCheeseList().size() == 3", Boolean.TRUE);
509 assertExpression(jc, "foo.cheeseList.size() == 3", Boolean.TRUE);
510
511 jc.getVars().put("string", "");
512 assertExpression(jc, "not empty string", Boolean.FALSE);
513 assertExpression(jc, "not(empty string)", Boolean.FALSE);
514 assertExpression(jc, "not empty(string)", Boolean.FALSE);
515 assertExpression(jc, "! empty string", Boolean.FALSE);
516 assertExpression(jc, "!(empty string)", Boolean.FALSE);
517 assertExpression(jc, "!empty(string)", Boolean.FALSE);
518
519 }
520
521
522 /***
523 * GMJ : disabled - need to fix
524 *
525 * test some simple conditions
526 */
527 public void testNotConditionsWithDots()
528 throws Exception
529 {
530 JexlContext jc = JexlHelper.createContext();
531
532 jc.getVars().put("x.a", Boolean.TRUE );
533 jc.getVars().put("x.b", Boolean.FALSE );
534
535 assertExpression(jc, "x.a", Boolean.TRUE);
536 assertExpression(jc, "!x.a", Boolean.FALSE);
537 assertExpression(jc, "!x.b", Boolean.TRUE);
538 }
539
540 /***
541 * test some simple conditions
542 */
543 public void testComparisons()
544 throws Exception
545 {
546 JexlContext jc = JexlHelper.createContext();
547 jc.getVars().put("foo", "the quick and lazy fox" );
548
549 assertExpression(jc, "foo.indexOf('quick') > 0", Boolean.TRUE);
550 assertExpression(jc, "foo.indexOf('bar') >= 0", Boolean.FALSE);
551 assertExpression(jc, "foo.indexOf('bar') < 0", Boolean.TRUE);
552 }
553
554 /***
555 * test some null conditions
556 */
557 public void testNull()
558 throws Exception
559 {
560 JexlContext jc = JexlHelper.createContext();
561 jc.getVars().put("bar", new Integer(2) );
562
563 assertExpression(jc, "empty foo", Boolean.TRUE);
564 assertExpression(jc, "bar == null", Boolean.FALSE);
565 assertExpression(jc, "foo == null", Boolean.TRUE);
566 assertExpression(jc, "bar != null", Boolean.TRUE);
567 assertExpression(jc, "foo != null", Boolean.FALSE);
568 assertExpression(jc, "empty(bar)", Boolean.FALSE);
569 assertExpression(jc, "empty(foo)", Boolean.TRUE);
570 }
571
572 /***
573 * test some blank strings
574 */
575 public void testBlankStrings()
576 throws Exception
577 {
578 JexlContext jc = JexlHelper.createContext();
579 jc.getVars().put("bar", "" );
580
581 assertExpression(jc, "foo == ''", Boolean.FALSE);
582 assertExpression(jc, "bar == ''", Boolean.TRUE);
583 assertExpression(jc, "barnotexist == ''", Boolean.FALSE);
584 assertExpression(jc, "empty bar", Boolean.TRUE);
585 assertExpression(jc, "bar.length() == 0", Boolean.TRUE);
586 assertExpression(jc, "size(bar) == 0", Boolean.TRUE);
587 }
588
589 /***
590 * test some blank strings
591 */
592 public void testLogicExpressions()
593 throws Exception
594 {
595 JexlContext jc = JexlHelper.createContext();
596 jc.getVars().put("foo", "abc" );
597 jc.getVars().put("bar", "def" );
598
599 assertExpression(jc, "foo == 'abc' || bar == 'abc'", Boolean.TRUE);
600 assertExpression(jc, "foo == 'abc' or bar == 'abc'", Boolean.TRUE);
601 assertExpression(jc, "foo == 'abc' && bar == 'abc'", Boolean.FALSE);
602 assertExpression(jc, "foo == 'abc' and bar == 'abc'", Boolean.FALSE);
603
604 assertExpression(jc, "foo == 'def' || bar == 'abc'", Boolean.FALSE);
605 assertExpression(jc, "foo == 'def' or bar == 'abc'", Boolean.FALSE);
606 assertExpression(jc, "foo == 'abc' && bar == 'def'", Boolean.TRUE);
607 assertExpression(jc, "foo == 'abc' and bar == 'def'", Boolean.TRUE);
608 }
609
610
611 /***
612 * test some simple double array lookups
613 */
614 public void testDoubleArrays()
615 throws Exception
616 {
617 JexlContext jc = JexlHelper.createContext();
618
619 Object[][] foo = new Object[2][2];
620 foo[0][0] = "one";
621 foo[0][1] = "two";
622
623 jc.getVars().put("foo", foo );
624
625 assertExpression(jc, "foo[0][1]", "two");
626 }
627
628 /***
629 * test variables with underscore names
630 */
631 public void testVariableNames()
632 throws Exception
633 {
634 JexlContext jc = JexlHelper.createContext();
635 jc.getVars().put("foo_bar", "123" );
636
637 assertExpression(jc, "foo_bar", "123");
638 }
639
640 /***
641 * test the use of dot notation to lookup map entries
642 */
643 public void testMapDot()
644 throws Exception
645 {
646 Map foo = new HashMap();
647 foo.put( "bar", "123" );
648
649 JexlContext jc = JexlHelper.createContext();
650 jc.getVars().put("foo", foo );
651
652 assertExpression(jc, "foo.bar", "123");
653 }
654
655 /***
656 * Tests string literals
657 */
658 public void testStringLiterals()
659 throws Exception
660 {
661 JexlContext jc = JexlHelper.createContext();
662 jc.getVars().put("foo", "bar" );
663
664 assertExpression(jc, "foo == \"bar\"", Boolean.TRUE);
665 assertExpression(jc, "foo == 'bar'", Boolean.TRUE);
666 }
667
668 /***
669 * test the use of an int based property
670 */
671 public void testIntProperty()
672 throws Exception
673 {
674 Foo foo = new Foo();
675
676
677 assertEquals(4, foo.square(2));
678 assertEquals(4, foo.square(-2));
679
680 JexlContext jc = JexlHelper.createContext();
681 jc.getVars().put("foo", foo );
682
683 assertExpression(jc, "foo.count", new Integer(5));
684 assertExpression(jc, "foo.square(2)", new Integer(4));
685 assertExpression(jc, "foo.square(-2)", new Integer(4));
686 }
687
688 /***
689 * test the -1 comparison bug
690 */
691 public void testNegativeIntComparison()
692 throws Exception
693 {
694 JexlContext jc = JexlHelper.createContext();
695 Foo foo = new Foo();
696 jc.getVars().put("foo", foo );
697
698 assertExpression(jc, "foo.count != -1", Boolean.TRUE);
699 assertExpression(jc, "foo.count == 5", Boolean.TRUE);
700 assertExpression(jc, "foo.count == -1", Boolean.FALSE);
701 }
702
703 public void testArrayProperty()
704 throws Exception
705 {
706 Foo foo = new Foo();
707
708 JexlContext jc = JexlHelper.createContext();
709 jc.getVars().put("foo", foo );
710
711 assertExpression(jc, "foo.array[1]", GET_METHOD_ARRAY[1]);
712 assertExpression(jc, "foo.array.1", GET_METHOD_ARRAY[1]);
713 assertExpression(jc, "foo.array2[1][1]", GET_METHOD_ARRAY2[1][1]);
714
715 }
716
717 /***
718 * Attempts to recreate bug http://jira.werken.com/ViewIssue.jspa?key=JELLY-8
719 */
720 public void testCharAtBug()
721 throws Exception
722 {
723 JexlContext jc = JexlHelper.createContext();
724
725 jc.getVars().put("foo", "abcdef");
726
727 assertExpression(jc, "foo.substring(2,4)", "cd");
728 assertExpression(jc, "foo.charAt(2)", new Character('c'));
729
730 try {
731 assertExpression(jc, "foo.charAt(-2)", null);
732 fail("this test should have thrown an exception" );
733 }
734 catch (IndexOutOfBoundsException e) {
735
736 }
737 catch (Exception e) {
738 throw e;
739 }
740 }
741
742 public void testEmptyDottedVariableName() throws Exception
743 {
744 JexlContext jc = JexlHelper.createContext();
745
746 jc.getVars().put( "this.is.a.test", "");
747
748 assertExpression(jc, "empty(this.is.a.test)", Boolean.TRUE);
749 }
750
751 public void testEmptySubListOfMap() throws Exception
752 {
753 JexlContext jc = JexlHelper.createContext();
754 Map m = Collections.singletonMap("aList", Collections.EMPTY_LIST);
755
756 jc.getVars().put( "aMap", m );
757
758 assertExpression( jc, "empty( aMap.aList )", Boolean.TRUE );
759 }
760
761 public void testCoercionWithComparisionOperators()
762 throws Exception
763 {
764 JexlContext jc = JexlHelper.createContext();
765
766 assertExpression(jc, "'2' > 1", Boolean.TRUE);
767 assertExpression(jc, "'2' >= 1", Boolean.TRUE);
768 assertExpression(jc, "'2' >= 2", Boolean.TRUE);
769 assertExpression(jc, "'2' < 1", Boolean.FALSE);
770 assertExpression(jc, "'2' <= 1", Boolean.FALSE);
771 assertExpression(jc, "'2' <= 2", Boolean.TRUE);
772
773 assertExpression(jc, "2 > '1'", Boolean.TRUE);
774 assertExpression(jc, "2 >= '1'", Boolean.TRUE);
775 assertExpression(jc, "2 >= '2'", Boolean.TRUE);
776 assertExpression(jc, "2 < '1'", Boolean.FALSE);
777 assertExpression(jc, "2 <= '1'", Boolean.FALSE);
778 assertExpression(jc, "2 <= '2'", Boolean.TRUE);
779 }
780
781 public void testResolver()
782 throws Exception
783 {
784
785
786
787
788 Expression expr = ExpressionFactory.createExpression("foo.bar");
789 expr.addPreResolver(new FlatResolver());
790
791 JexlContext jc = JexlHelper.createContext();
792 Foo foo = new Foo();
793 jc.getVars().put("foo.bar", "flat value");
794 jc.getVars().put("foo", foo );
795
796 Object o = expr.evaluate(jc);
797 assertEquals("flat override", "flat value", o);
798
799
800
801
802 expr = ExpressionFactory.createExpression("foo.bar.length()");
803 expr.addPreResolver(new FlatResolver());
804 o = expr.evaluate(jc);
805 assertEquals("flat override 1", new Integer(GET_METHOD_STRING.length()), o);
806
807
808
809
810
811 expr = ExpressionFactory.createExpression("foo.bar.length()");
812 expr.addPreResolver(new FlatResolver(false));
813 o = expr.evaluate(jc);
814 assertEquals("flat override 2", o, null);
815
816
817 expr = ExpressionFactory.createExpression("foo.bar.baz");
818 Long result = new Long(1);
819 jc.getVars().put("foo.bar.baz", result);
820 expr.addPostResolver(new FlatResolver());
821 assertEquals("flat override", result, expr.evaluate(jc));
822
823 }
824
825 /***
826 * Test that 'and' only evaluates the second item if needed
827 * @throws Exception if there are errors
828 */
829 public void testBooleanShortCircuitAnd() throws Exception
830 {
831
832 Foo tester = new Foo();
833 JexlContext jc = JexlHelper.createContext();
834 jc.getVars().put("first", Boolean.FALSE);
835 jc.getVars().put("foo", tester);
836 Expression expr = ExpressionFactory.createExpression("first and foo.trueAndModify");
837 expr.evaluate(jc);
838 assertTrue("Short circuit failure: rhs evaluated when lhs FALSE", !tester.getModified());
839
840 tester = new Foo();
841 jc.getVars().put("first", Boolean.TRUE);
842 jc.getVars().put("foo", tester);
843 expr.evaluate(jc);
844 assertTrue("Short circuit failure: rhs not evaluated when lhs TRUE", tester.getModified());
845 }
846
847 /***
848 * Test that 'or' only evaluates the second item if needed
849 * @throws Exception if there are errors
850 */
851 public void testBooleanShortCircuitOr() throws Exception
852 {
853
854 Foo tester = new Foo();
855 JexlContext jc = JexlHelper.createContext();
856 jc.getVars().put("first", Boolean.FALSE);
857 jc.getVars().put("foo", tester);
858 Expression expr = ExpressionFactory.createExpression("first or foo.trueAndModify");
859 expr.evaluate(jc);
860 assertTrue("Short circuit failure: rhs not evaluated when lhs FALSE", tester.getModified());
861
862 tester = new Foo();
863 jc.getVars().put("first", Boolean.TRUE);
864 jc.getVars().put("foo", tester);
865 expr.evaluate(jc);
866 assertTrue("Short circuit failure: rhs evaluated when lhs TRUE", !tester.getModified());
867 }
868
869 /***
870 * Simple test of '+' as a string concatenation operator
871 * @throws Exception
872 */
873 public void testStringConcatenation() throws Exception
874 {
875 JexlContext jc = JexlHelper.createContext();
876 jc.getVars().put("first", "Hello");
877 jc.getVars().put("second", "World");
878 assertExpression(jc, "first + ' ' + second", "Hello World");
879 }
880
881 /***
882 * Ensures static methods on objects can be called.
883 */
884 public void testStaticMethodInvocation() throws Exception
885 {
886 JexlContext jc = JexlHelper.createContext();
887 jc.getVars().put("aBool", Boolean.FALSE);
888 assertExpression(jc, "aBool.valueOf('true')", Boolean.TRUE);
889 }
890
891 public void testStaticMethodInvocationOnClasses() throws Exception
892 {
893 JexlContext jc = JexlHelper.createContext();
894 jc.getVars().put("Boolean", Boolean.class);
895 assertExpression(jc, "Boolean.valueOf('true')", Boolean.TRUE);
896 }
897
898 public void testToString() throws Exception {
899 String code = "abcd";
900 Expression expr = ExpressionFactory.createExpression(code);
901 assertEquals("Bad expression value", code, expr.toString());
902 }
903
904 /***
905 * Make sure bad syntax throws ParseException
906 * @throws Exception on errors
907 */
908 public void testBadParse() throws Exception
909 {
910 try
911 {
912 assertExpression(JexlHelper.createContext(), "empty()", null);
913 fail("Bad expression didn't throw ParseException");
914 }
915 catch (ParseException pe)
916 {
917
918 }
919 }
920
921 /***
922 * Test the ## comment in a string
923 * @throws Exception
924 */
925 public void testComment() throws Exception
926 {
927 assertExpression(JexlHelper.createContext(), "## double or nothing\n 1 + 1", Long.valueOf("2"));
928 }
929
930 /***
931 * Test assignment.
932 * @throws Exception
933 */
934 public void testAssignment() throws Exception
935 {
936 JexlContext jc = JexlHelper.createContext();
937 jc.getVars().put("aString", "Hello");
938 Foo foo = new Foo();
939 jc.getVars().put("foo", foo);
940 Parser parser = new Parser(new StringReader(";"));
941 parser.parse(new StringReader("aString = 'World';"));
942
943 assertExpression(jc, "hello = 'world'", "world");
944 assertEquals("hello variable not changed", "world", jc.getVars().get("hello"));
945 assertExpression(jc, "result = 1 + 1", new Long(2));
946 assertEquals("result variable not changed", new Long(2), jc.getVars().get("result"));
947
948
949
950 }
951
952 public void testAntPropertiesWithMethods() throws Exception
953 {
954 JexlContext jc = JexlHelper.createContext();
955 String value = "Stinky Cheese";
956 jc.getVars().put("maven.bob.food", value);
957 assertExpression(jc, "maven.bob.food.length()", new Integer(value.length()));
958 assertExpression(jc, "empty(maven.bob.food)", Boolean.FALSE);
959 assertExpression(jc, "size(maven.bob.food)", new Integer(value.length()));
960 assertExpression(jc, "maven.bob.food + ' is good'", value + " is good");
961
962
963
964
965
966 }
967
968 /***
969 * Asserts that the given expression returns the given value when applied to the
970 * given context
971 */
972 protected void assertExpression(JexlContext jc, String expression, Object expected) throws Exception
973 {
974 Expression e = ExpressionFactory.createExpression(expression);
975 Object actual = e.evaluate(jc);
976 assertEquals(expression, expected, actual);
977 }
978
979
980 /***
981 * Helps in debugging the testcases when working with it
982 *
983 */
984 public static void main(String[] args)
985 throws Exception
986 {
987 JexlTest jt = new JexlTest("foo");
988 jt.testEmpty();
989 }
990
991 }