1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl3;
18
19 import static org.junit.jupiter.api.Assertions.assertEquals;
20 import static org.junit.jupiter.api.Assertions.assertFalse;
21 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23 import static org.junit.jupiter.api.Assertions.assertTrue;
24
25 import java.math.BigDecimal;
26 import java.math.BigInteger;
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.BitSet;
30 import java.util.Calendar;
31 import java.util.GregorianCalendar;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.LinkedList;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38
39 import org.apache.commons.jexl3.parser.Parser;
40 import org.junit.jupiter.api.Test;
41
42
43
44
45 @SuppressWarnings({"UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
46 public final class JexlTest extends JexlTestCase {
47 public static final class Duck {
48 int user = 10;
49
50 @SuppressWarnings("boxing")
51 public Integer get(final String val) {
52 switch (val) {
53 case "zero":
54 return 0;
55 case "one":
56 return 1;
57 case "user":
58 return user;
59 default:
60 break;
61 }
62 return -1;
63 }
64
65 @SuppressWarnings("boxing")
66 public void set(final String val, final Object value) {
67 if ("user".equals(val)) {
68 if ("zero".equals(value)) {
69 user = 0;
70 } else if ("one".equals(value)) {
71 user = 1;
72 } else {
73 user = value instanceof Integer ? (Integer) value : -1;
74 }
75 }
76 }
77 }
78 static final String METHOD_STRING = "Method string";
79
80 static final String GET_METHOD_STRING = "GetMethod string";
81
82 public JexlTest() {
83 super("JexlTest",
84 new JexlBuilder()
85 .strict(false)
86 .imports(Arrays.asList("java.lang","java.math"))
87 .permissions(null)
88 .cache(128).create());
89 }
90
91
92
93
94
95 private void assertExpression(final JexlContext jc, final String expression, final Object expected) {
96 final JexlExpression e = JEXL.createExpression(expression);
97 final Object actual = e.evaluate(jc);
98 assertEquals(expected, actual, expression);
99 }
100
101 @Test
102 void testAntPropertiesWithMethods() {
103 final JexlContext jc = new MapContext();
104 final String value = "Stinky Cheese";
105 jc.set("maven.bob.food", value);
106 assertExpression(jc, "maven.bob.food.length()", Integer.valueOf(value.length()));
107 assertExpression(jc, "empty(maven.bob.food)", Boolean.FALSE);
108 assertExpression(jc, "size(maven.bob.food)", Integer.valueOf(value.length()));
109 assertExpression(jc, "maven.bob.food + ' is good'", value + " is good");
110
111
112
113
114
115 }
116
117 @SuppressWarnings("boxing")
118 @Test
119 void testArray() {
120 final int[] array = {100, 101, 102};
121 final JexlEngine jexl = JEXL;
122 final JexlContext jc = new MapContext();
123 jc.set("array", array);
124 JexlExpression expr;
125 Object result;
126 expr = jexl.createExpression("array.1");
127 result = expr.evaluate(jc);
128 assertEquals(101, result);
129 expr = jexl.createExpression("array[1] = 1010");
130 result = expr.evaluate(jc);
131 assertEquals(1010, result, expr::toString);
132 expr = jexl.createExpression("array.0");
133 result = expr.evaluate(jc);
134 assertEquals(100, result, expr::toString);
135 }
136
137
138
139
140 @Test
141 void testAssignment() {
142 final JexlContext jc = new MapContext();
143 jc.set("aString", "Hello");
144 final Foo foo = new Foo();
145 jc.set("foo", foo);
146 final Parser parser = new Parser(";");
147 parser.parse(null, new JexlFeatures().register(false), "aString = 'World';", null);
148
149 assertExpression(jc, "hello = 'world'", "world");
150 assertEquals("world", jc.get("hello"), "hello variable not changed");
151 assertExpression(jc, "result = 1 + 1", Integer.valueOf(2));
152 assertEquals(Integer.valueOf(2), jc.get("result"), "result variable not changed");
153 assertExpression(jc, "foo.property1 = '99'", "99");
154 assertEquals("99", foo.getProperty1(), "property not set");
155 }
156
157
158
159
160 @Test
161 void testBadParse() {
162 assertThrows(JexlException.class, () -> assertExpression(new MapContext(), "empty()", null));
163 }
164
165
166
167
168 @Test
169 void testBlankStrings() {
170 final JexlContext jc = new MapContext();
171 jc.set("bar", "");
172
173 assertExpression(jc, "bar == ''", Boolean.TRUE);
174 assertExpression(jc, "empty bar", Boolean.TRUE);
175 assertExpression(jc, "bar.length() == 0", Boolean.TRUE);
176 assertExpression(jc, "size(bar) == 0", Boolean.TRUE);
177 }
178
179 @Test
180 void testBoolean() {
181 final JexlContext jc = new MapContext();
182 jc.set("foo", new Foo());
183 jc.set("a", Boolean.TRUE);
184 jc.set("b", Boolean.FALSE);
185
186 assertExpression(jc, "foo.convertBoolean(a==b)", "Boolean : false");
187 assertExpression(jc, "foo.convertBoolean(a==true)", "Boolean : true");
188 assertExpression(jc, "foo.convertBoolean(a==false)", "Boolean : false");
189 assertExpression(jc, "foo.convertBoolean(true==false)", "Boolean : false");
190 assertExpression(jc, "true eq false", Boolean.FALSE);
191 assertExpression(jc, "true ne false", Boolean.TRUE);
192 }
193
194
195
196
197 @Test
198 void testBooleanShortCircuitAnd() {
199
200 Foo tester = new Foo();
201 final JexlContext jc = new MapContext();
202 jc.set("first", Boolean.FALSE);
203 jc.set("foo", tester);
204 final JexlExpression expr = JEXL.createExpression("first and foo.trueAndModify");
205 expr.evaluate(jc);
206 assertFalse(tester.getModified(), "Short circuit failure: rhs evaluated when lhs FALSE");
207
208 tester = new Foo();
209 jc.set("first", Boolean.TRUE);
210 jc.set("foo", tester);
211 expr.evaluate(jc);
212 assertTrue(tester.getModified(), "Short circuit failure: rhs not evaluated when lhs TRUE");
213 }
214
215
216
217
218 @Test
219 void testBooleanShortCircuitOr() {
220
221 Foo tester = new Foo();
222 final JexlContext jc = new MapContext();
223 jc.set("first", Boolean.FALSE);
224 jc.set("foo", tester);
225 final JexlExpression expr = JEXL.createExpression("first or foo.trueAndModify");
226 expr.evaluate(jc);
227 assertTrue(tester.getModified(), "Short circuit failure: rhs not evaluated when lhs FALSE");
228
229 tester = new Foo();
230 jc.set("first", Boolean.TRUE);
231 jc.set("foo", tester);
232 expr.evaluate(jc);
233 assertFalse(tester.getModified(), "Short circuit failure: rhs evaluated when lhs TRUE");
234 }
235
236
237
238
239 @Test
240 void testCalculations() {
241 final JexlEvalContext jc = new JexlEvalContext();
242 final JexlOptions options = jc.getEngineOptions();
243 options.setStrict(false);
244 options.setStrictArithmetic(false);
245
246
247
248
249 jc.set("stringy", "thingy");
250 assertExpression(jc, "stringy + 2", "thingy2");
251
252
253
254
255 jc.set("imanull", null);
256 assertExpression(jc, "imanull + 2", Integer.valueOf(2));
257 assertExpression(jc, "imanull + imanull", Integer.valueOf(0));
258
259
260 jc.set("n", Integer.valueOf(0));
261 assertExpression(jc, "n != null && n != 0", Boolean.FALSE);
262 }
263
264
265
266
267 @Test
268 void testCharAtBug() {
269 final JexlEvalContext jc = new JexlEvalContext();
270 final JexlOptions options = jc.getEngineOptions();
271 options.setSilent(true);
272
273 jc.set("foo", "abcdef");
274
275 assertExpression(jc, "foo.substring(2,4)", "cd");
276 assertExpression(jc, "foo.charAt(2)", Character.valueOf('c'));
277 assertExpression(jc, "foo.charAt(-2)", null);
278
279 }
280
281 @Test
282 void testCoercionWithComparisonOperators() {
283 final JexlContext jc = new MapContext();
284
285 assertExpression(jc, "'2' > 1", Boolean.TRUE);
286 assertExpression(jc, "'2' >= 1", Boolean.TRUE);
287 assertExpression(jc, "'2' >= 2", Boolean.TRUE);
288 assertExpression(jc, "'2' < 1", Boolean.FALSE);
289 assertExpression(jc, "'2' <= 1", Boolean.FALSE);
290 assertExpression(jc, "'2' <= 2", Boolean.TRUE);
291
292 assertExpression(jc, "2 > '1'", Boolean.TRUE);
293 assertExpression(jc, "2 >= '1'", Boolean.TRUE);
294 assertExpression(jc, "2 >= '2'", Boolean.TRUE);
295 assertExpression(jc, "2 < '1'", Boolean.FALSE);
296 assertExpression(jc, "2 <= '1'", Boolean.FALSE);
297 assertExpression(jc, "2 <= '2'", Boolean.TRUE);
298 }
299
300
301
302
303 @Test
304 void testComment() {
305 assertExpression(new MapContext(), "## double or nothing\n 1 + 1", Integer.valueOf("2"));
306 }
307
308
309
310
311 @Test
312 void testComparisons() {
313 final JexlContext jc = new MapContext();
314 jc.set("foo", "the quick and lazy fox");
315
316 assertExpression(jc, "foo.indexOf('quick') > 0", Boolean.TRUE);
317 assertExpression(jc, "foo.indexOf('bar') >= 0", Boolean.FALSE);
318 assertExpression(jc, "foo.indexOf('bar') < 0", Boolean.TRUE);
319 }
320
321
322
323
324 @Test
325 void testConditions() {
326 final JexlEvalContext jc = new JexlEvalContext();
327 final JexlOptions options = jc.getEngineOptions();
328 jc.set("foo", Integer.valueOf(2));
329 jc.set("aFloat", Float.valueOf(1));
330 jc.set("aDouble", Double.valueOf(2));
331 jc.set("aChar", Character.valueOf('A'));
332 jc.set("aBool", Boolean.TRUE);
333 final StringBuilder buffer = new StringBuilder("abc");
334 final List<Object> list = new ArrayList<>();
335 final List<Object> list2 = new LinkedList<>();
336 jc.set("aBuffer", buffer);
337 jc.set("aList", list);
338 jc.set("bList", list2);
339
340 assertExpression(jc, "foo == 2", Boolean.TRUE);
341 assertExpression(jc, "2 == 3", Boolean.FALSE);
342 assertExpression(jc, "3 == foo", Boolean.FALSE);
343 assertExpression(jc, "3 != foo", Boolean.TRUE);
344 assertExpression(jc, "foo != 2", Boolean.FALSE);
345
346 assertExpression(jc, "aFloat eq aDouble", Boolean.FALSE);
347 assertExpression(jc, "aFloat ne aDouble", Boolean.TRUE);
348 assertExpression(jc, "aFloat == aDouble", Boolean.FALSE);
349 assertExpression(jc, "aFloat != aDouble", Boolean.TRUE);
350
351 assertExpression(jc, "foo == aChar", Boolean.FALSE);
352 assertExpression(jc, "foo != aChar", Boolean.TRUE);
353
354 assertExpression(jc, "aBool == 'true'", Boolean.TRUE);
355 assertExpression(jc, "aBool == 'false'", Boolean.FALSE);
356 assertExpression(jc, "aBool != 'false'", Boolean.TRUE);
357
358 options.setStrict(false);
359 assertExpression(jc, "aBool == notThere", Boolean.FALSE);
360 assertExpression(jc, "aBool != notThere", Boolean.TRUE);
361
362 options.setStrict(true);
363 assertExpression(jc, "aBuffer == 'abc'", Boolean.TRUE);
364 assertExpression(jc, "aBuffer != 'abc'", Boolean.FALSE);
365
366 assertExpression(jc, "aList == bList", Boolean.TRUE);
367 assertExpression(jc, "aList != bList", Boolean.FALSE);
368 }
369
370 @SuppressWarnings("boxing")
371 @Test
372 void testDuck() {
373 final JexlEngine jexl = JEXL;
374 final JexlContext jc = new MapContext();
375 jc.set("duck", new Duck());
376 JexlExpression expr;
377 Object result;
378 expr = jexl.createExpression("duck.zero");
379 result = expr.evaluate(jc);
380 assertEquals(0, result, expr::toString);
381 expr = jexl.createExpression("duck.one");
382 result = expr.evaluate(jc);
383 assertEquals(1, result, expr::toString);
384 expr = jexl.createExpression("duck.user = 20");
385 result = expr.evaluate(jc);
386 assertEquals(20, result, expr::toString);
387 expr = jexl.createExpression("duck.user");
388 result = expr.evaluate(jc);
389 assertEquals(20, result, expr::toString);
390 expr = jexl.createExpression("duck.user = 'zero'");
391 result = expr.evaluate(jc);
392 assertEquals("zero", result, expr::toString);
393 expr = jexl.createExpression("duck.user");
394 result = expr.evaluate(jc);
395 assertEquals(0, result, expr::toString);
396 }
397
398 @Test
399 void testEmpty() {
400 final JexlEvalContext jc = new JexlEvalContext();
401 final JexlOptions options = jc.getEngineOptions();
402 options.setStrict(false);
403 jc.set("string", "");
404 jc.set("array", new Object[0]);
405 jc.set("map", new HashMap<>());
406 jc.set("list", new ArrayList<>());
407 jc.set("set", new HashMap<>().keySet());
408 jc.set("longstring", "thingthing");
409
410
411
412
413 assertExpression(jc, "empty nullthing", Boolean.TRUE);
414 assertExpression(jc, "empty string", Boolean.TRUE);
415 assertExpression(jc, "empty array", Boolean.TRUE);
416 assertExpression(jc, "empty map", Boolean.TRUE);
417 assertExpression(jc, "empty set", Boolean.TRUE);
418 assertExpression(jc, "empty list", Boolean.TRUE);
419 assertExpression(jc, "empty longstring", Boolean.FALSE);
420 assertExpression(jc, "not empty longstring", Boolean.TRUE);
421 }
422
423 @Test
424 void testEmptyDottedVariableName() {
425 final JexlContext jc = new MapContext();
426
427 jc.set("this.is.a.test", "");
428
429 assertExpression(jc, "empty(this.is.a.test)", Boolean.TRUE);
430 }
431
432 @Test
433 void testEmptySubListOfMap() {
434 final JexlContext jc = new MapContext();
435 final Map<String, ArrayList<?>> m = new HashMap<>();
436 m.put("aList", new ArrayList<>());
437
438 jc.set("aMap", m);
439
440 assertExpression(jc, "empty( aMap.aList )", Boolean.TRUE);
441 }
442
443 @Test
444 void testExpression() {
445 final JexlContext jc = new MapContext();
446 jc.set("foo", new Foo());
447 jc.set("a", Boolean.TRUE);
448 jc.set("b", Boolean.FALSE);
449 jc.set("num", Integer.valueOf(5));
450 jc.set("now", Calendar.getInstance().getTime());
451 final GregorianCalendar gc = new GregorianCalendar(5000, Calendar.DECEMBER, 20);
452 jc.set("now2", gc.getTime());
453 jc.set("bdec", new BigDecimal("7"));
454 jc.set("bint", new BigInteger("7"));
455
456 assertExpression(jc, "a == b", Boolean.FALSE);
457 assertExpression(jc, "a==true", Boolean.TRUE);
458 assertExpression(jc, "a==false", Boolean.FALSE);
459 assertExpression(jc, "true==false", Boolean.FALSE);
460
461 assertExpression(jc, "2 < 3", Boolean.TRUE);
462 assertExpression(jc, "num < 5", Boolean.FALSE);
463 assertExpression(jc, "num < num", Boolean.FALSE);
464 assertExpression(jc, "num < null", Boolean.FALSE);
465 assertExpression(jc, "num < 2.5", Boolean.FALSE);
466 assertExpression(jc, "now2 < now", Boolean.FALSE);
467
468 assertExpression(jc, "'6' <= '5'", Boolean.FALSE);
469 assertExpression(jc, "num <= 5", Boolean.TRUE);
470 assertExpression(jc, "num <= num", Boolean.TRUE);
471 assertExpression(jc, "num <= null", Boolean.FALSE);
472 assertExpression(jc, "num <= 2.5", Boolean.FALSE);
473 assertExpression(jc, "now2 <= now", Boolean.FALSE);
474
475
476 assertExpression(jc, "'6' >= '5'", Boolean.TRUE);
477 assertExpression(jc, "num >= 5", Boolean.TRUE);
478 assertExpression(jc, "num >= num", Boolean.TRUE);
479 assertExpression(jc, "num >= null", Boolean.FALSE);
480 assertExpression(jc, "num >= 2.5", Boolean.TRUE);
481 assertExpression(jc, "now2 >= now", Boolean.TRUE);
482
483 assertExpression(jc, "'6' > '5'", Boolean.TRUE);
484 assertExpression(jc, "num > 4", Boolean.TRUE);
485 assertExpression(jc, "num > num", Boolean.FALSE);
486 assertExpression(jc, "num > null", Boolean.FALSE);
487 assertExpression(jc, "num > 2.5", Boolean.TRUE);
488 assertExpression(jc, "now2 > now", Boolean.TRUE);
489
490 assertExpression(jc, "\"foo\" + \"bar\" == \"foobar\"", Boolean.TRUE);
491
492 assertExpression(jc, "bdec > num", Boolean.TRUE);
493 assertExpression(jc, "bdec >= num", Boolean.TRUE);
494 assertExpression(jc, "num <= bdec", Boolean.TRUE);
495 assertExpression(jc, "num < bdec", Boolean.TRUE);
496 assertExpression(jc, "bint > num", Boolean.TRUE);
497 assertExpression(jc, "bint == bdec", Boolean.TRUE);
498 assertExpression(jc, "bint >= num", Boolean.TRUE);
499 assertExpression(jc, "num <= bint", Boolean.TRUE);
500 assertExpression(jc, "num < bint", Boolean.TRUE);
501 }
502
503
504
505
506 @Test
507 void testIntProperty() {
508 final Foo foo = new Foo();
509
510
511 assertEquals(4, foo.square(2));
512 assertEquals(4, foo.square(-2));
513
514 final JexlContext jc = new MapContext();
515 jc.set("foo", foo);
516
517 assertExpression(jc, "foo.count", Integer.valueOf(5));
518 assertExpression(jc, "foo.square(2)", Integer.valueOf(4));
519 assertExpression(jc, "foo.square(-2)", Integer.valueOf(4));
520 }
521
522
523
524
525 @Test
526 void testLogicExpressions() {
527 final JexlContext jc = new MapContext();
528 jc.set("foo", "abc");
529 jc.set("bar", "def");
530
531 assertExpression(jc, "foo == 'abc' || bar == 'abc'", Boolean.TRUE);
532 assertExpression(jc, "foo == 'abc' or bar == 'abc'", Boolean.TRUE);
533 assertExpression(jc, "foo == 'abc' && bar == 'abc'", Boolean.FALSE);
534 assertExpression(jc, "foo == 'abc' and bar == 'abc'", Boolean.FALSE);
535
536 assertExpression(jc, "foo == 'def' || bar == 'abc'", Boolean.FALSE);
537 assertExpression(jc, "foo == 'def' or bar == 'abc'", Boolean.FALSE);
538 assertExpression(jc, "foo == 'abc' && bar == 'def'", Boolean.TRUE);
539 assertExpression(jc, "foo == 'abc' and bar == 'def'", Boolean.TRUE);
540 }
541
542
543
544
545 @Test
546 void testMapDot() {
547 final Map<String, String> foo = new HashMap<>();
548 foo.put("bar", "123");
549
550 final JexlContext jc = new MapContext();
551 jc.set("foo", foo);
552
553 assertExpression(jc, "foo.bar", "123");
554 }
555
556
557
558
559 @Test
560 void testNegativeIntComparison() {
561 final JexlContext jc = new MapContext();
562 final Foo foo = new Foo();
563 jc.set("foo", foo);
564
565 assertExpression(jc, "foo.count != -1", Boolean.TRUE);
566 assertExpression(jc, "foo.count == 5", Boolean.TRUE);
567 assertExpression(jc, "foo.count == -1", Boolean.FALSE);
568 }
569
570
571
572
573 @Test
574 void testNew() {
575 final JexlContext jc = new MapContext();
576 jc.set("double", Double.class);
577 jc.set("foo", "org.apache.commons.jexl3.Foo");
578 JexlExpression expr;
579 Object value;
580 expr = JEXL.createExpression("new(double, 1)");
581 value = expr.evaluate(jc);
582 assertEquals(Double.valueOf(1.0), value, expr::toString);
583 expr = JEXL.createExpression("new('java.lang.Float', 100)");
584 value = expr.evaluate(jc);
585 assertEquals(Float.valueOf((float) 100.0), value, expr::toString);
586 expr = JEXL.createExpression("new(foo).quux");
587 value = expr.evaluate(jc);
588 assertEquals("String : quux", value, expr::toString);
589 }
590
591 @Test
592 void testNewImports() {
593 final JexlEngine jexl = new JexlBuilder().imports("java.lang", "java.util").create();
594 JexlExpression expr;
595 Object result;
596 expr = jexl.createExpression("new LinkedList([1,2,3,...])");
597 result = expr.evaluate(null);
598 assertInstanceOf(LinkedList.class, result);
599 }
600
601
602
603
604 @Test
605 void testNotConditions() {
606 final JexlContext jc = new MapContext();
607
608 final Foo foo = new Foo();
609 jc.set("x", Boolean.TRUE);
610 jc.set("foo", foo);
611 jc.set("bar", "true");
612
613 assertExpression(jc, "!x", Boolean.FALSE);
614 assertExpression(jc, "x", Boolean.TRUE);
615 assertExpression(jc, "!bar", Boolean.FALSE);
616 assertExpression(jc, "!foo.isSimple()", Boolean.FALSE);
617 assertExpression(jc, "foo.isSimple()", Boolean.TRUE);
618 assertExpression(jc, "!foo.simple", Boolean.FALSE);
619 assertExpression(jc, "foo.simple", Boolean.TRUE);
620 assertExpression(jc, "foo.getCheeseList().size() == 3", Boolean.TRUE);
621 assertExpression(jc, "foo.cheeseList.size() == 3", Boolean.TRUE);
622
623 jc.set("string", "");
624 assertExpression(jc, "not empty string", Boolean.FALSE);
625 assertExpression(jc, "not(empty string)", Boolean.FALSE);
626 assertExpression(jc, "not empty(string)", Boolean.FALSE);
627 assertExpression(jc, "! empty string", Boolean.FALSE);
628 assertExpression(jc, "!(empty string)", Boolean.FALSE);
629 assertExpression(jc, "! empty(string)", Boolean.FALSE);
630
631 }
632
633
634
635
636 @Test
637 void testNotConditionsWithDots() {
638 final JexlContext jc = new MapContext();
639
640 jc.set("x.a", Boolean.TRUE);
641 jc.set("x.b", Boolean.FALSE);
642
643 assertExpression(jc, "x.a", Boolean.TRUE);
644 assertExpression(jc, "!x.a", Boolean.FALSE);
645 assertExpression(jc, "!x.b", Boolean.TRUE);
646 }
647
648
649
650
651 @Test
652 void testNull() {
653 final JexlEvalContext jc = new JexlEvalContext();
654 final JexlOptions options = jc.getEngineOptions();
655 options.setStrict(false);
656 jc.set("bar", Integer.valueOf(2));
657
658 assertExpression(jc, "empty foo", Boolean.TRUE);
659 assertExpression(jc, "bar == null", Boolean.FALSE);
660 assertExpression(jc, "foo == null", Boolean.TRUE);
661 assertExpression(jc, "bar != null", Boolean.TRUE);
662 assertExpression(jc, "foo != null", Boolean.FALSE);
663 assertExpression(jc, "empty(bar)", Boolean.FALSE);
664 assertExpression(jc, "empty(foo)", Boolean.TRUE);
665 }
666
667
668
669
670 @Test
671 void testProperty() {
672
673
674
675
676 final JexlExpression e = JEXL.createExpression("foo.bar");
677 final JexlContext jc = new MapContext();
678
679 jc.set("foo", new Foo());
680 final Object o = e.evaluate(jc);
681
682 assertInstanceOf(String.class, o, "o not instanceof String");
683 assertEquals(GET_METHOD_STRING, o, "o incorrect");
684 }
685
686 @Test
687 void testSize() {
688 final JexlEvalContext jc = new JexlEvalContext();
689 final JexlOptions options = jc.getEngineOptions();
690 options.setStrict(false);
691 jc.set("s", "five!");
692 jc.set("array", new Object[5]);
693
694 final Map<String, Integer> map = new HashMap<>();
695
696 map.put("1", Integer.valueOf(1));
697 map.put("2", Integer.valueOf(2));
698 map.put("3", Integer.valueOf(3));
699 map.put("4", Integer.valueOf(4));
700 map.put("5", Integer.valueOf(5));
701
702 jc.set("map", map);
703
704 final List<String> list = new ArrayList<>();
705
706 list.add("1");
707 list.add("2");
708 list.add("3");
709 list.add("4");
710 list.add("5");
711
712 jc.set("list", list);
713
714
715 final Set<String> set = new HashSet<>(list);
716 set.add("1");
717
718 jc.set("set", set);
719
720
721 final BitSet bitset = new BitSet(5);
722 jc.set("bitset", bitset);
723
724 assertExpression(jc, "size(s)", Integer.valueOf(5));
725 assertExpression(jc, "size(array)", Integer.valueOf(5));
726 assertExpression(jc, "size(list)", Integer.valueOf(5));
727 assertExpression(jc, "size(map)", Integer.valueOf(5));
728 assertExpression(jc, "size(set)", Integer.valueOf(5));
729 assertExpression(jc, "size(bitset)", Integer.valueOf(64));
730 assertExpression(jc, "list.size()", Integer.valueOf(5));
731 assertExpression(jc, "map.size()", Integer.valueOf(5));
732 assertExpression(jc, "set.size()", Integer.valueOf(5));
733 assertExpression(jc, "bitset.size()", Integer.valueOf(64));
734
735 assertExpression(jc, "list.get(size(list) - 1)", "5");
736 assertExpression(jc, "list[size(list) - 1]", "5");
737 assertExpression(jc, "list.get(list.size() - 1)", "5");
738 }
739
740 @Test
741 void testSizeAsProperty() {
742 final JexlContext jc = new MapContext();
743 final Map<String, Object> map = new HashMap<>();
744 map.put("size", "cheese");
745 map.put("si & ze", "cheese");
746 jc.set("map", map);
747 jc.set("foo", new Foo());
748
749 assertExpression(jc, "map['size']", "cheese");
750 assertExpression(jc, "map['si & ze']", "cheese");
751 assertExpression(jc, "map.'si & ze'", "cheese");
752 assertExpression(jc, "map.size()", 2);
753 assertExpression(jc, "size(map)", 2);
754 assertExpression(jc, "foo.getSize()", 22);
755 assertExpression(jc, "foo.'size'", 22);
756 }
757
758
759
760
761 @Test
762 void testStringConcatenation() {
763 final JexlContext jc = new MapContext();
764 jc.set("first", "Hello");
765 jc.set("second", "World");
766 assertExpression(jc, "first + ' ' + second", "Hello World");
767 }
768
769 @Test
770 void testStringLit() {
771
772
773
774 final JexlContext jc = new MapContext();
775 jc.set("foo", new Foo());
776 assertExpression(jc, "foo.repeat(\"woogie\")", "Repeat : woogie");
777 }
778
779
780
781
782 @Test
783 void testStringLiterals() {
784 final JexlContext jc = new MapContext();
785 jc.set("foo", "bar");
786
787 assertExpression(jc, "foo == \"bar\"", Boolean.TRUE);
788 assertExpression(jc, "foo == 'bar'", Boolean.TRUE);
789 }
790
791
792
793
794 @Test
795 void testStringQuoting() {
796 final JexlContext jc = new MapContext();
797 assertExpression(jc, "'\"Hello\"'", "\"Hello\"");
798 assertExpression(jc, "\"I'm testing\"", "I'm testing");
799 }
800
801 @Test
802 void testToString() {
803 final String code = "abcd";
804 final JexlExpression expr = JEXL.createExpression(code);
805 assertEquals(code, expr.toString(), "Bad expression value");
806 }
807
808 @Test
809 void testUnicodeSupport() {
810 final JexlContext jc = new MapContext();
811 assertExpression(jc, "'x' == '\\u0032?ytkownik'", Boolean.FALSE);
812 assertExpression(jc, "'c:\\some\\windows\\path'", "c:\\some\\windows\\path");
813 assertExpression(jc, "'foo\\u0020bar'", "foo\u0020bar");
814 assertExpression(jc, "'foo\\u0020\\u0020bar'", "foo\u0020\u0020bar");
815 assertExpression(jc, "'\\u0020foobar\\u0020'", "\u0020foobar\u0020");
816 }
817
818
819
820
821 @Test
822 void testVariableNames() {
823 final JexlContext jc = new MapContext();
824 jc.set("foo_bar", "123");
825
826 assertExpression(jc, "foo_bar", "123");
827 }
828 }