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 org.apache.commons.jexl3.internal.Engine;
20 import org.apache.commons.jexl3.internal.introspection.Uberspect;
21
22 import java.util.HashMap;
23 import java.util.Map;
24 import org.junit.Assert;
25 import org.junit.Before;
26 import org.junit.Test;
27
28
29
30
31
32 @SuppressWarnings({"boxing", "UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
33 public class IssuesTest extends JexlTestCase {
34 public IssuesTest() {
35 super("IssuesTest", null);
36 }
37
38 @Before
39 @Override
40 public void setUp() throws Exception {
41
42 java.util.logging.Logger.getLogger(JexlEngine.class.getName()).setLevel(java.util.logging.Level.SEVERE);
43 }
44
45
46 @Test
47 public void test49() throws Exception {
48 final JexlEngine jexl = new Engine();
49 final Map<String, Object> vars = new HashMap<>();
50 final JexlContext ctxt = new MapContext(vars);
51 final String stmt = "a = 'b'; c = 'd';";
52 final JexlScript expr = jexl.createScript(stmt);
53 expr.execute(ctxt);
54 Assert.assertTrue("JEXL-49 is not fixed", vars.get("a").equals("b") && vars.get("c").equals("d"));
55 }
56
57
58 public static class Another {
59 public String name = "whatever";
60 private final Boolean foo = Boolean.TRUE;
61
62 public Boolean foo() {
63 return foo;
64 }
65
66 public int goo() {
67 return 100;
68 }
69 }
70
71 public static class Foo {
72 private final Another inner;
73
74 Foo() {
75 inner = new Another();
76 }
77
78 public Another getInner() {
79 return inner;
80 }
81 }
82
83 @Test
84 public void test48() throws Exception {
85 final JexlEngine jexl = new Engine();
86 final JexlEvalContext jc = new JexlEvalContext();
87 final JexlOptions options = jc.getEngineOptions();
88
89 options.setStrict(true);
90 options.setSilent(false);
91 try {
92 final String jexlExp = "(foo.getInner().foo() eq true) and (foo.getInner().goo() = (foo.getInner().goo()+1-1))";
93 final JexlExpression e = jexl.createExpression(jexlExp);
94 jc.set("foo", new Foo());
95 e.evaluate(jc);
96 Assert.fail("Should have failed due to invalid assignment");
97 } catch (final JexlException.Assignment xparse) {
98 final String dbg = xparse.toString();
99 } catch (final JexlException xjexl) {
100 Assert.fail("Should have thrown a parse exception");
101 }
102 }
103
104
105
106 @Test
107 public void test47() throws Exception {
108 final JexlEngine jexl = new Engine();
109 final JexlEvalContext ctxt = new JexlEvalContext();
110 final JexlOptions options = ctxt.getEngineOptions();
111
112 options.setSilent(false);
113
114 JexlExpression expr = jexl.createExpression("true//false\n");
115 Object value = expr.evaluate(ctxt);
116 Assert.assertTrue("should be true", (Boolean) value);
117
118 expr = jexl.createExpression("/*true*/false");
119 value = expr.evaluate(ctxt);
120 Assert.assertFalse("should be false", (Boolean) value);
121
122 expr = jexl.createExpression("/*\"true\"*/false");
123 value = expr.evaluate(ctxt);
124 Assert.assertFalse("should be false", (Boolean) value);
125 }
126
127
128
129 @Test
130 public void test42() throws Exception {
131 final JexlEngine jexl = new JexlBuilder().create();
132 final JxltEngine uel = jexl.createJxltEngine();
133
134
135 final JexlEvalContext ctxt = new JexlEvalContext();
136 final JexlOptions options = ctxt.getEngineOptions();
137 options.set(jexl);
138 options.setStrict(false);
139 options.setStrictArithmetic(false);
140 ctxt.set("ax", "ok");
141
142 final JxltEngine.Expression expr = uel.createExpression("${ax+(bx)}");
143 final Object value = expr.evaluate(ctxt);
144 Assert.assertEquals("should be ok", "ok", value);
145 }
146
147
148
149 public static abstract class Base {
150 public abstract boolean foo();
151 }
152
153 static class Derived extends Base {
154 @Override
155 public boolean foo() {
156 return true;
157 }
158 }
159
160 @Test
161 public void test40() throws Exception {
162 final JexlEngine jexl = new Engine();
163 final JexlEvalContext ctxt = new JexlEvalContext();
164 final JexlOptions options = ctxt.getEngineOptions();
165 options.set(jexl);
166
167 options.setSilent(false);
168
169 ctxt.set("derived", new Derived());
170
171 final JexlExpression expr = jexl.createExpression("derived.foo()");
172 final Object value = expr.evaluate(ctxt);
173 Assert.assertTrue("should be true", (Boolean) value);
174 }
175
176
177 @Test
178 public void test52base() throws Exception {
179 final Engine jexl = (Engine) createEngine(false);
180 final Uberspect uber = (Uberspect) jexl.getUberspect();
181
182 String[] names = uber.getMethodNames(Another.class);
183 Assert.assertTrue("should find methods", names.length > 0);
184 int found = 0;
185 for (final String name : names) {
186 if ("foo".equals(name) || "goo".equals(name)) {
187 found += 1;
188 }
189 }
190 Assert.assertEquals("should have foo & goo", 2, found);
191
192 names = uber.getFieldNames(Another.class);
193 Assert.assertTrue("should find fields", names.length > 0);
194 found = 0;
195 for (final String name : names) {
196 if ("name".equals(name)) {
197 found += 1;
198 }
199 }
200 Assert.assertEquals("should have name", 1, found);
201 }
202
203
204 @Test
205 public void test11() throws Exception {
206 final JexlEngine jexl = createEngine(false);
207 final JexlEvalContext ctxt = new JexlEvalContext();
208 final JexlOptions options = ctxt.getEngineOptions();
209
210 options.setSilent(false);
211 options.setStrict(true);
212
213 ctxt.set("a", null);
214
215 final String[] exprs = {
216
217
218
219 "a % b"
220
221 };
222 for (final String s : exprs) {
223 try {
224 final JexlExpression expr = jexl.createExpression(s);
225
226 expr.evaluate(ctxt);
227 Assert.fail(s + " : should have failed due to null argument");
228 } catch (final JexlException xjexl) {
229
230 }
231 }
232 }
233
234
235 @Test
236 public void test62() throws Exception {
237 final JexlEngine jexl = createEngine(false);
238 final MapContext vars = new MapContext();
239 final JexlEvalContext ctxt = new JexlEvalContext(vars);
240 final JexlOptions options = ctxt.getEngineOptions();
241 options.setStrict(true);
242 options.setSilent(true);
243
244 JexlScript jscript;
245
246 jscript = jexl.createScript("dummy.hashCode()");
247 Assert.assertNull(jscript.getSourceText(), jscript.execute(ctxt));
248
249 ctxt.set("dummy", "abcd");
250 Assert.assertEquals(jscript.getSourceText(), Integer.valueOf("abcd".hashCode()), jscript.execute(ctxt));
251
252 jscript = jexl.createScript("dummy.hashCode");
253 Assert.assertNull(jscript.getSourceText(), jscript.execute(ctxt));
254
255 JexlExpression jexpr;
256 vars.clear();
257 jexpr = jexl.createExpression("dummy.hashCode()");
258 Assert.assertNull(jexpr.toString(), jexpr.evaluate(ctxt));
259
260 ctxt.set("dummy", "abcd");
261 Assert.assertEquals(jexpr.toString(), Integer.valueOf("abcd".hashCode()), jexpr.evaluate(ctxt));
262
263 jexpr = jexl.createExpression("dummy.hashCode");
264 Assert.assertNull(jexpr.toString(), jexpr.evaluate(ctxt));
265 }
266
267
268 @Test
269 public void test87() throws Exception {
270 final JexlEngine jexl = createEngine(false);
271 final JexlEvalContext ctxt = new JexlEvalContext();
272 final JexlOptions options = ctxt.getEngineOptions();
273
274 options.setSilent(false);
275 final JexlExpression divide = jexl.createExpression("l / r");
276 final JexlExpression modulo = jexl.createExpression("l % r");
277
278 ctxt.set("l", java.math.BigInteger.valueOf(7));
279 ctxt.set("r", java.math.BigInteger.valueOf(2));
280 Assert.assertEquals(java.math.BigInteger.valueOf(3), divide.evaluate(ctxt));
281 Assert.assertTrue(jexl.getArithmetic().equals(1, modulo.evaluate(ctxt)));
282
283 ctxt.set("l", java.math.BigDecimal.valueOf(7));
284 ctxt.set("r", java.math.BigDecimal.valueOf(2));
285 Assert.assertEquals(java.math.BigDecimal.valueOf(3.5), divide.evaluate(ctxt));
286 Assert.assertTrue(jexl.getArithmetic().equals(1, modulo.evaluate(ctxt)));
287 }
288
289
290 @Test
291 public void test90() throws Exception {
292 final JexlEngine jexl = createEngine(false);
293 final JexlEvalContext ctxt = new JexlEvalContext();
294 final JexlOptions options = ctxt.getEngineOptions();
295
296 options.setSilent(false);
297
298 final String[] fexprs = {
299 "a=3 b=4",
300 "while(a) while(a)",
301 "1 2",
302 "if (true) 2; 3 {}",
303 "while (x) 1 if (y) 2 3"
304 };
305 for (final String fexpr : fexprs) {
306 try {
307 jexl.createScript(fexpr);
308 Assert.fail(fexpr + ": Should have failed in parse");
309 } catch (final JexlException xany) {
310
311 }
312 }
313
314 final String[] exprs = {
315 "if (x) {1} if (y) {2}",
316 "if (x) 1 if (y) 2",
317 "while (x) 1 if (y) 2 else 3",
318 "for(z : [3, 4, 5]) { z } y ? 2 : 1",
319 "for(z : [3, 4, 5]) { z } if (y) 2 else 1"
320 };
321 ctxt.set("x", Boolean.FALSE);
322 ctxt.set("y", Boolean.TRUE);
323 for (final String expr : exprs) {
324 final JexlScript s = jexl.createScript(expr);
325 Assert.assertEquals(Integer.valueOf(2), s.execute(ctxt));
326 }
327 debuggerCheck(jexl);
328 }
329
330
331 @Test
332 public void test44() throws Exception {
333 final JexlEngine jexl = createEngine(false);
334 final JexlEvalContext ctxt = new JexlEvalContext();
335 final JexlOptions options = ctxt.getEngineOptions();
336
337 options.setSilent(false);
338 JexlScript script;
339 script = jexl.createScript("'hello world!'//commented");
340 Assert.assertEquals("hello world!", script.execute(ctxt));
341 script = jexl.createScript("'hello world!';//commented\n'bye...'");
342 Assert.assertEquals("bye...", script.execute(ctxt));
343 script = jexl.createScript("'hello world!'## commented");
344 Assert.assertEquals("hello world!", script.execute(ctxt));
345 script = jexl.createScript("'hello world!';## commented\n'bye...'");
346 Assert.assertEquals("bye...", script.execute(ctxt));
347 }
348
349 @Test
350 public void test97() throws Exception {
351 final JexlEngine jexl = createEngine(false);
352 final JexlEvalContext ctxt = new JexlEvalContext();
353 final JexlOptions options = ctxt.getEngineOptions();
354
355 options.setSilent(false);
356 for (char v = 'a'; v <= 'z'; ++v) {
357 ctxt.set(Character.toString(v), 10);
358 }
359 final String input
360 = "(((((((((((((((((((((((((z+y)/x)*w)-v)*u)/t)-s)*r)/q)+p)-o)*n)-m)+l)*k)+j)/i)+h)*g)+f)/e)+d)-c)/b)+a)";
361
362 JexlExpression script;
363
364 final long start = System.nanoTime();
365 script = jexl.createExpression(input);
366 final Object value = script.evaluate(ctxt);
367 Assert.assertEquals(Integer.valueOf(11), value);
368 final long end = System.nanoTime();
369 final double millisec = (end - start) / 1e6;
370 final double limit = 200.0;
371 Assert.assertTrue("Expected parse to take less than " + limit + "ms, actual " + millisec, millisec < limit);
372 }
373
374 public static class fn98 {
375 public String replace(final String str, final String target, final String replacement) {
376 return str.replace(target, replacement);
377 }
378 }
379
380 @Test
381 public void test98() throws Exception {
382 final String[] exprs = {
383 "fn:replace('DOMAIN\\somename', '\\\\', '\\\\\\\\')",
384 "fn:replace(\"DOMAIN\\somename\", \"\\\\\", \"\\\\\\\\\")",
385 "fn:replace('DOMAIN\\somename', '\\u005c', '\\u005c\\u005c')"
386 };
387 final Map<String, Object> funcs = new HashMap<>();
388 funcs.put("fn", new fn98());
389 final JexlEngine jexl = new JexlBuilder().namespaces(funcs).create();
390 for (final String expr : exprs) {
391 final Object value = jexl.createExpression(expr).evaluate(null);
392 Assert.assertEquals(expr, "DOMAIN\\\\somename", value);
393 }
394 }
395
396 }