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