| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.commons.jexl3; |
| |
| import org.apache.commons.jexl3.internal.Engine; |
| import java.math.BigDecimal; |
| import java.math.MathContext; |
| import java.util.HashMap; |
| import java.util.Map; |
| import org.apache.commons.jexl3.internal.introspection.Uberspect; |
| import java.io.File; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.Set; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| //import org.apache.commons.beanutils.LazyDynaMap; |
| |
| /** |
| * Test cases for reported issue . |
| */ |
| @SuppressWarnings({"boxing", "UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"}) |
| public class IssuesTest extends JexlTestCase { |
| public IssuesTest() { |
| super("IssuesTest", null); |
| } |
| |
| @Before |
| @Override |
| public void setUp() throws Exception { |
| // ensure jul logging is only error to avoid warning in silent mode |
| java.util.logging.Logger.getLogger(JexlEngine.class.getName()).setLevel(java.util.logging.Level.SEVERE); |
| } |
| |
| // JEXL-49: blocks not parsed (fixed) |
| @Test |
| public void test49() throws Exception { |
| JexlEngine jexl = new Engine(); |
| Map<String, Object> vars = new HashMap<String, Object>(); |
| JexlContext ctxt = new MapContext(vars); |
| String stmt = "a = 'b'; c = 'd';"; |
| JexlScript expr = jexl.createScript(stmt); |
| /* Object value = */ expr.execute(ctxt); |
| Assert.assertTrue("JEXL-49 is not fixed", vars.get("a").equals("b") && vars.get("c").equals("d")); |
| } |
| |
| // JEXL-48: bad assignment detection |
| public static class Another { |
| public String name = "whatever"; |
| private final Boolean foo = Boolean.TRUE; |
| |
| public Boolean foo() { |
| return foo; |
| } |
| |
| public int goo() { |
| return 100; |
| } |
| } |
| |
| public static class Foo { |
| private final Another inner; |
| |
| Foo() { |
| inner = new Another(); |
| } |
| |
| public Another getInner() { |
| return inner; |
| } |
| } |
| |
| @Test |
| public void test48() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlEvalContext jc = new JexlEvalContext(); |
| // ensure errors will throw |
| jc.setStrict(true); |
| jc.setSilent(false); |
| try { |
| String jexlExp = "(foo.getInner().foo() eq true) and (foo.getInner().goo() = (foo.getInner().goo()+1-1))"; |
| JexlExpression e = jexl.createExpression(jexlExp); |
| jc.set("foo", new Foo()); |
| /* Object o = */ e.evaluate(jc); |
| Assert.fail("Should have failed due to invalid assignment"); |
| } catch (JexlException.Assignment xparse) { |
| String dbg = xparse.toString(); |
| } catch (JexlException xjexl) { |
| Assert.fail("Should have thrown a parse exception"); |
| } |
| } |
| |
| // JEXL-47: C style comments (single & multi line) (fixed in Parser.jjt) |
| // JEXL-44: comments dont allow double quotes (fixed in Parser.jjt) |
| @Test |
| public void test47() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlEvalContext ctxt = new JexlEvalContext(); |
| // ensure errors will throw |
| ctxt.setSilent(false); |
| |
| JexlExpression expr = jexl.createExpression("true//false\n"); |
| Object value = expr.evaluate(ctxt); |
| Assert.assertTrue("should be true", (Boolean) value); |
| |
| expr = jexl.createExpression("/*true*/false"); |
| value = expr.evaluate(ctxt); |
| Assert.assertFalse("should be false", (Boolean) value); |
| |
| expr = jexl.createExpression("/*\"true\"*/false"); |
| value = expr.evaluate(ctxt); |
| Assert.assertFalse("should be false", (Boolean) value); |
| } |
| |
| // JEXL-42: NullPointerException evaluating an expression |
| // fixed in JexlArithmetic by allowing add operator to deal with string, null |
| @Test |
| public void test42() throws Exception { |
| JexlEngine jexl = new JexlBuilder().create(); |
| JxltEngine uel = jexl.createJxltEngine(); |
| // ensure errors will throw |
| //jexl.setSilent(false); |
| JexlEvalContext ctxt = new JexlEvalContext(); |
| ctxt.setStrict(false); |
| ctxt.set("ax", "ok"); |
| |
| JxltEngine.Expression expr = uel.createExpression("${ax+(bx)}"); |
| Object value = expr.evaluate(ctxt); |
| Assert.assertTrue("should be ok", "ok".equals(value)); |
| } |
| |
| // JEXL-40: failed to discover all methods (non public class implements public method) |
| // fixed in ClassMap by taking newer version of populateCache from Velocity |
| public static abstract class Base { |
| public abstract boolean foo(); |
| } |
| |
| class Derived extends Base { |
| @Override |
| public boolean foo() { |
| return true; |
| } |
| } |
| |
| @Test |
| public void test40() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlEvalContext ctxt = new JexlEvalContext(); |
| // ensure errors will throw |
| ctxt.setSilent(false); |
| |
| ctxt.set("derived", new Derived()); |
| |
| JexlExpression expr = jexl.createExpression("derived.foo()"); |
| Object value = expr.evaluate(ctxt); |
| Assert.assertTrue("should be true", (Boolean) value); |
| } |
| |
| // JEXL-52: can be implemented by deriving Interpreter.{g,s}etAttribute; later |
| @Test |
| public void test52base() throws Exception { |
| Engine jexl = (Engine) createEngine(false); |
| Uberspect uber = (Uberspect) jexl.getUberspect(); |
| // most likely, call will be in an Interpreter, getUberspect |
| String[] names = uber.getMethodNames(Another.class); |
| Assert.assertTrue("should find methods", names.length > 0); |
| int found = 0; |
| for (String name : names) { |
| if ("foo".equals(name) || "goo".equals(name)) { |
| found += 1; |
| } |
| } |
| Assert.assertTrue("should have foo & goo", found == 2); |
| |
| names = uber.getFieldNames(Another.class); |
| Assert.assertTrue("should find fields", names.length > 0); |
| found = 0; |
| for (String name : names) { |
| if ("name".equals(name)) { |
| found += 1; |
| } |
| } |
| Assert.assertTrue("should have name", found == 1); |
| } |
| |
| // JEXL-10/JEXL-11: variable checking, null operand is error |
| @Test |
| public void test11() throws Exception { |
| JexlEngine jexl = createEngine(false); |
| JexlEvalContext ctxt = new JexlEvalContext(); |
| // ensure errors will throw |
| ctxt.setSilent(false); |
| ctxt.setStrict(true); |
| |
| ctxt.set("a", null); |
| |
| String[] exprs = { |
| //"10 + null", |
| //"a - 10", |
| //"b * 10", |
| "a % b"//, |
| //"1000 / a" |
| }; |
| for (int e = 0; e < exprs.length; ++e) { |
| try { |
| JexlExpression expr = jexl.createExpression(exprs[e]); |
| /* Object value = */ expr.evaluate(ctxt); |
| Assert.fail(exprs[e] + " : should have failed due to null argument"); |
| } catch (JexlException xjexl) { |
| // expected |
| } |
| } |
| } |
| |
| // JEXL-62 |
| @Test |
| public void test62() throws Exception { |
| JexlEngine jexl = createEngine(false); |
| MapContext vars = new MapContext(); |
| JexlEvalContext ctxt = new JexlEvalContext(vars); |
| ctxt.setStrict(true); |
| ctxt.setSilent(true);// to avoid throwing JexlException on null method call |
| |
| JexlScript jscript; |
| |
| jscript = jexl.createScript("dummy.hashCode()"); |
| Assert.assertEquals(jscript.getSourceText(), null, jscript.execute(ctxt)); // OK |
| |
| ctxt.set("dummy", "abcd"); |
| Assert.assertEquals(jscript.getSourceText(), Integer.valueOf("abcd".hashCode()), jscript.execute(ctxt)); // OK |
| |
| jscript = jexl.createScript("dummy.hashCode"); |
| Assert.assertEquals(jscript.getSourceText(), null, jscript.execute(ctxt)); // OK |
| |
| JexlExpression jexpr; |
| vars.clear(); |
| jexpr = jexl.createExpression("dummy.hashCode()"); |
| Assert.assertEquals(jexpr.toString(), null, jexpr.evaluate(ctxt)); // OK |
| |
| ctxt.set("dummy", "abcd"); |
| Assert.assertEquals(jexpr.toString(), Integer.valueOf("abcd".hashCode()), jexpr.evaluate(ctxt)); // OK |
| |
| jexpr = jexl.createExpression("dummy.hashCode"); |
| Assert.assertEquals(jexpr.toString(), null, jexpr.evaluate(ctxt)); // OK |
| } |
| |
| // JEXL-73 |
| @Test |
| public void test73() throws Exception { |
| JexlEngine jexl = createEngine(false); |
| JexlEvalContext ctxt = new JexlEvalContext(); |
| // ensure errors will throw |
| ctxt.setSilent(false); |
| ctxt.setStrict(true); |
| JexlExpression e; |
| e = jexl.createExpression("c.e"); |
| try { |
| /* Object o = */ e.evaluate(ctxt); |
| Assert.fail("c.e not declared as variable"); |
| } catch (JexlException.Variable xjexl) { |
| String msg = xjexl.getMessage(); |
| Assert.assertTrue(msg.indexOf("c.e") > 0); |
| } |
| |
| ctxt.set("c", "{ 'a' : 3, 'b' : 5}"); |
| ctxt.set("e", Integer.valueOf(2)); |
| try { |
| /* Object o = */ e.evaluate(ctxt); |
| Assert.fail("c.e not accessible as property"); |
| } catch (JexlException.Property xjexl) { |
| String msg = xjexl.getMessage(); |
| Assert.assertTrue(msg.indexOf("e") > 0); |
| } |
| |
| } |
| |
| // JEXL-87 |
| @Test |
| public void test87() throws Exception { |
| JexlEngine jexl = createEngine(false); |
| JexlEvalContext ctxt = new JexlEvalContext(); |
| // ensure errors will throw |
| ctxt.setSilent(false); |
| JexlExpression divide = jexl.createExpression("l / r"); |
| JexlExpression modulo = jexl.createExpression("l % r"); |
| |
| ctxt.set("l", java.math.BigInteger.valueOf(7)); |
| ctxt.set("r", java.math.BigInteger.valueOf(2)); |
| Assert.assertEquals(java.math.BigInteger.valueOf(3), divide.evaluate(ctxt)); |
| Assert.assertTrue(jexl.getArithmetic().equals(1, modulo.evaluate(ctxt))); |
| |
| ctxt.set("l", java.math.BigDecimal.valueOf(7)); |
| ctxt.set("r", java.math.BigDecimal.valueOf(2)); |
| Assert.assertEquals(java.math.BigDecimal.valueOf(3.5), divide.evaluate(ctxt)); |
| Assert.assertTrue(jexl.getArithmetic().equals(1, modulo.evaluate(ctxt))); |
| } |
| |
| // JEXL-90 |
| @Test |
| public void test90() throws Exception { |
| JexlEngine jexl = createEngine(false); |
| JexlEvalContext ctxt = new JexlEvalContext(); |
| // ensure errors will throw |
| ctxt.setSilent(false); |
| // ';' is necessary between expressions |
| String[] fexprs = { |
| "a=3 b=4", |
| "while(a) while(a)", |
| "1 2", |
| "if (true) 2; 3 {}", |
| "while (x) 1 if (y) 2 3" |
| }; |
| for (int f = 0; f < fexprs.length; ++f) { |
| try { |
| jexl.createScript(fexprs[f]); |
| Assert.fail(fexprs[f] + ": Should have failed in parse"); |
| } catch (JexlException xany) { |
| // expected to fail in createExpression |
| } |
| } |
| // ';' is necessary between expressions and only expressions |
| String[] exprs = { |
| "if (x) {1} if (y) {2}", |
| "if (x) 1 if (y) 2", |
| "while (x) 1 if (y) 2 else 3", |
| "for(z : [3, 4, 5]) { z } y ? 2 : 1", |
| "for(z : [3, 4, 5]) { z } if (y) 2 else 1" |
| }; |
| ctxt.set("x", Boolean.FALSE); |
| ctxt.set("y", Boolean.TRUE); |
| for (int e = 0; e < exprs.length; ++e) { |
| JexlScript s = jexl.createScript(exprs[e]); |
| Assert.assertEquals(Integer.valueOf(2), s.execute(ctxt)); |
| } |
| debuggerCheck(jexl); |
| } |
| |
| // JEXL-44 |
| @Test |
| public void test44() throws Exception { |
| JexlEngine jexl = createEngine(false); |
| JexlEvalContext ctxt = new JexlEvalContext(); |
| // ensure errors will throw |
| ctxt.setSilent(false); |
| JexlScript script; |
| script = jexl.createScript("'hello world!'//commented"); |
| Assert.assertEquals("hello world!", script.execute(ctxt)); |
| script = jexl.createScript("'hello world!';//commented\n'bye...'"); |
| Assert.assertEquals("bye...", script.execute(ctxt)); |
| script = jexl.createScript("'hello world!'## commented"); |
| Assert.assertEquals("hello world!", script.execute(ctxt)); |
| script = jexl.createScript("'hello world!';## commented\n'bye...'"); |
| Assert.assertEquals("bye...", script.execute(ctxt)); |
| } |
| |
| @Test |
| public void test97() throws Exception { |
| JexlEngine jexl = createEngine(false); |
| JexlEvalContext ctxt = new JexlEvalContext(); |
| // ensure errors will throw |
| ctxt.setSilent(false); |
| for (char v = 'a'; v <= 'z'; ++v) { |
| ctxt.set(Character.toString(v), 10); |
| } |
| String input |
| = "(((((((((((((((((((((((((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)"; |
| |
| JexlExpression script; |
| // Make sure everything is loaded... |
| long start = System.nanoTime(); |
| script = jexl.createExpression(input); |
| Object value = script.evaluate(ctxt); |
| Assert.assertEquals(Integer.valueOf(11), value); |
| long end = System.nanoTime(); |
| double millisec = (end - start) / 1e6; |
| double limit = 200.0; // Allow plenty of slack |
| Assert.assertTrue("Expected parse to take less than " + limit + "ms, actual " + millisec, millisec < limit); |
| } |
| |
| public static class fn98 { |
| public String replace(String str, String target, String replacement) { |
| return str.replace(target, replacement); |
| } |
| } |
| |
| @Test |
| public void test98() throws Exception { |
| String[] exprs = { |
| "fn:replace('DOMAIN\\somename', '\\\\', '\\\\\\\\')", |
| "fn:replace(\"DOMAIN\\somename\", \"\\\\\", \"\\\\\\\\\")", |
| "fn:replace('DOMAIN\\somename', '\\u005c', '\\u005c\\u005c')" |
| }; |
| Map<String, Object> funcs = new HashMap<String, Object>(); |
| funcs.put("fn", new fn98()); |
| JexlEngine jexl = new JexlBuilder().namespaces(funcs).create(); |
| for (String expr : exprs) { |
| Object value = jexl.createExpression(expr).evaluate(null); |
| Assert.assertEquals(expr, "DOMAIN\\\\somename", value); |
| } |
| } |
| |
| @Test |
| public void test100() throws Exception { |
| JexlEngine jexl = new JexlBuilder().cache(4).create(); |
| JexlContext ctxt = new MapContext(); |
| int[] foo = {42}; |
| ctxt.set("foo", foo); |
| Object value; |
| for (int l = 0; l < 2; ++l) { |
| value = jexl.createExpression("foo[0]").evaluate(ctxt); |
| Assert.assertEquals(42, value); |
| value = jexl.createExpression("foo[0] = 43").evaluate(ctxt); |
| Assert.assertEquals(43, value); |
| value = jexl.createExpression("foo.0").evaluate(ctxt); |
| Assert.assertEquals(43, value); |
| value = jexl.createExpression("foo.0 = 42").evaluate(ctxt); |
| Assert.assertEquals(42, value); |
| } |
| } |
| |
| // A's class definition |
| public static class A105 { |
| String nameA; |
| String propA; |
| |
| public A105(String nameA, String propA) { |
| this.nameA = nameA; |
| this.propA = propA; |
| } |
| |
| @Override |
| public String toString() { |
| return "A [nameA=" + nameA + ", propA=" + propA + "]"; |
| } |
| |
| public String getNameA() { |
| return nameA; |
| } |
| |
| public String getPropA() { |
| return propA; |
| } |
| |
| public String uppercase(String str) { |
| return str.toUpperCase(); |
| } |
| } |
| |
| @Test |
| public void test105() throws Exception { |
| JexlContext context = new MapContext(); |
| JexlExpression selectExp = new Engine().createExpression("[a.propA]"); |
| context.set("a", new A105("a1", "p1")); |
| Object[] r = (Object[]) selectExp.evaluate(context); |
| Assert.assertEquals("p1", r[0]); |
| |
| //selectExp = new Engine().createExpression("[a.propA]"); |
| context.set("a", new A105("a2", "p2")); |
| r = (Object[]) selectExp.evaluate(context); |
| Assert.assertEquals("p2", r[0]); |
| } |
| |
| @Test |
| public void test106() throws Exception { |
| JexlEvalContext context = new JexlEvalContext(); |
| context.setStrict(true, true); |
| context.set("a", new BigDecimal(1)); |
| context.set("b", new BigDecimal(3)); |
| JexlEngine jexl = new Engine(); |
| try { |
| Object value = jexl.createExpression("a / b").evaluate(context); |
| Assert.assertNotNull(value); |
| } catch (JexlException xjexl) { |
| Assert.fail("should not occur"); |
| } |
| context.setMathContext(MathContext.UNLIMITED); |
| context.setMathScale(2); |
| try { |
| jexl.createExpression("a / b").evaluate(context); |
| Assert.fail("should fail"); |
| } catch (JexlException xjexl) { |
| //ok to fail |
| } |
| } |
| |
| @Test |
| public void test107() throws Exception { |
| String[] exprs = { |
| "'Q4'.toLowerCase()", "q4", |
| "(Q4).toLowerCase()", "q4", |
| "(4).toString()", "4", |
| "(1 + 3).toString()", "4", |
| "({ 'q' : 'Q4'}).get('q').toLowerCase()", "q4", |
| "{ 'q' : 'Q4'}.get('q').toLowerCase()", "q4", |
| "({ 'q' : 'Q4'})['q'].toLowerCase()", "q4", |
| "(['Q4'])[0].toLowerCase()", "q4" |
| }; |
| |
| JexlContext context = new MapContext(); |
| context.set("Q4", "Q4"); |
| JexlEngine jexl = new Engine(); |
| for (int e = 0; e < exprs.length; e += 2) { |
| JexlExpression expr = jexl.createExpression(exprs[e]); |
| Object expected = exprs[e + 1]; |
| Object value = expr.evaluate(context); |
| Assert.assertEquals(expected, value); |
| expr = jexl.createExpression(expr.getParsedText()); |
| value = expr.evaluate(context); |
| Assert.assertEquals(expected, value); |
| } |
| } |
| |
| @Test |
| public void test108() throws Exception { |
| JexlScript expr; |
| Object value; |
| JexlEngine jexl = new Engine(); |
| expr = jexl.createScript("size([])"); |
| value = expr.execute(null); |
| Assert.assertEquals(0, value); |
| expr = jexl.createScript(expr.getParsedText()); |
| value = expr.execute(null); |
| Assert.assertEquals(0, value); |
| |
| expr = jexl.createScript("if (true) { [] } else { {:} }"); |
| value = expr.execute(null); |
| Assert.assertTrue(value.getClass().isArray()); |
| expr = jexl.createScript(expr.getParsedText()); |
| value = expr.execute(null); |
| Assert.assertTrue(value.getClass().isArray()); |
| |
| expr = jexl.createScript("size({:})"); |
| value = expr.execute(null); |
| Assert.assertEquals(0, value); |
| expr = jexl.createScript(expr.getParsedText()); |
| value = expr.execute(null); |
| Assert.assertEquals(0, value); |
| |
| expr = jexl.createScript("if (false) { [] } else { {:} }"); |
| value = expr.execute(null); |
| Assert.assertTrue(value instanceof Map<?, ?>); |
| expr = jexl.createScript(expr.getParsedText()); |
| value = expr.execute(null); |
| Assert.assertTrue(value instanceof Map<?, ?>); |
| } |
| |
| @Test |
| public void test109() throws Exception { |
| JexlEngine jexl = new Engine(); |
| Object value; |
| JexlContext context = new MapContext(); |
| context.set("foo.bar", 40); |
| value = jexl.createExpression("foo.bar + 2").evaluate(context); |
| Assert.assertEquals(42, value); |
| } |
| |
| @Test |
| public void test110() throws Exception { |
| JexlEngine jexl = new Engine(); |
| String[] names = {"foo"}; |
| Object value; |
| JexlContext context = new MapContext(); |
| value = jexl.createScript("foo + 2", names).execute(context, 40); |
| Assert.assertEquals(42, value); |
| context.set("frak.foo", -40); |
| value = jexl.createScript("frak.foo - 2", names).execute(context, 40); |
| Assert.assertEquals(-42, value); |
| } |
| |
| static public class RichContext extends ObjectContext<A105> { |
| RichContext(JexlEngine jexl, A105 a105) { |
| super(jexl, a105); |
| } |
| } |
| |
| @Test |
| public void testRichContext() throws Exception { |
| A105 a105 = new A105("foo", "bar"); |
| JexlEngine jexl = new Engine(); |
| Object value; |
| JexlContext context = new RichContext(jexl, a105); |
| value = jexl.createScript("uppercase(nameA + propA)").execute(context); |
| Assert.assertEquals("FOOBAR", value); |
| } |
| |
| @Test |
| public void test111() throws Exception { |
| JexlEngine jexl = new Engine(); |
| Object value; |
| JexlContext context = new MapContext(); |
| String strExpr = "((x>0)?\"FirstValue=\"+(y-x):\"SecondValue=\"+x)"; |
| JexlExpression expr = jexl.createExpression(strExpr); |
| |
| context.set("x", 1); |
| context.set("y", 10); |
| value = expr.evaluate(context); |
| Assert.assertEquals("FirstValue=9", value); |
| |
| context.set("x", 1.0d); |
| context.set("y", 10.0d); |
| value = expr.evaluate(context); |
| Assert.assertEquals("FirstValue=9.0", value); |
| |
| context.set("x", 1); |
| context.set("y", 10.0d); |
| value = expr.evaluate(context); |
| Assert.assertEquals("FirstValue=9.0", value); |
| |
| context.set("x", 1.0d); |
| context.set("y", 10); |
| value = expr.evaluate(context); |
| Assert.assertEquals("FirstValue=9.0", value); |
| |
| context.set("x", -10); |
| context.set("y", 1); |
| value = expr.evaluate(context); |
| Assert.assertEquals("SecondValue=-10", value); |
| |
| context.set("x", -10.0d); |
| context.set("y", 1.0d); |
| value = expr.evaluate(context); |
| Assert.assertEquals("SecondValue=-10.0", value); |
| |
| context.set("x", -10); |
| context.set("y", 1.0d); |
| value = expr.evaluate(context); |
| Assert.assertEquals("SecondValue=-10", value); |
| |
| context.set("x", -10.0d); |
| context.set("y", 1); |
| value = expr.evaluate(context); |
| Assert.assertEquals("SecondValue=-10.0", value); |
| } |
| |
| @Test |
| public void testScaleIssue() throws Exception { |
| JexlEngine jexlX = new Engine(); |
| String expStr1 = "result == salary/month * work.percent/100.00"; |
| JexlExpression exp1 = jexlX.createExpression(expStr1); |
| JexlEvalContext ctx = new JexlEvalContext(); |
| ctx.set("result", new BigDecimal("9958.33")); |
| ctx.set("salary", new BigDecimal("119500.00")); |
| ctx.set("month", new BigDecimal("12.00")); |
| ctx.set("work.percent", new BigDecimal("100.00")); |
| |
| // will fail because default scale is 5 |
| Assert.assertFalse((Boolean) exp1.evaluate(ctx)); |
| |
| // will succeed with scale = 2 |
| ctx.setMathScale(2); |
| Assert.assertTrue((Boolean) exp1.evaluate(ctx)); |
| } |
| |
| @Test |
| public void test112() throws Exception { |
| Object result; |
| JexlEngine jexl = new Engine(); |
| result = jexl.createScript(Integer.toString(Integer.MAX_VALUE)).execute(null); |
| Assert.assertEquals(Integer.MAX_VALUE, result); |
| result = jexl.createScript(Integer.toString(Integer.MIN_VALUE + 1)).execute(null); |
| Assert.assertEquals(Integer.MIN_VALUE + 1, result); |
| result = jexl.createScript(Integer.toString(Integer.MIN_VALUE)).execute(null); |
| Assert.assertEquals(Integer.MIN_VALUE, result); |
| } |
| |
| @Test |
| public void test117() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlExpression e = jexl.createExpression("TIMESTAMP > 20100102000000"); |
| JexlContext ctx = new MapContext(); |
| ctx.set("TIMESTAMP", new Long("20100103000000")); |
| Object result = e.evaluate(ctx); |
| Assert.assertTrue((Boolean) result); |
| } |
| |
| public static class Foo125 { |
| public String method() { |
| return "OK"; |
| } |
| |
| public String total(String tt) { |
| return "total " + tt; |
| } |
| } |
| |
| public static class Foo125Context extends ObjectContext<Foo125> { |
| public Foo125Context(JexlEngine engine, Foo125 wrapped) { |
| super(engine, wrapped); |
| } |
| } |
| |
| @Test |
| public void test125() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlExpression e = jexl.createExpression("method()"); |
| JexlContext jc = new Foo125Context(jexl, new Foo125()); |
| Assert.assertEquals("OK", e.evaluate(jc)); |
| } |
| |
| @Test |
| public void test130a() throws Exception { |
| String myName = "Test.Name"; |
| Object myValue = "Test.Value"; |
| |
| JexlEngine myJexlEngine = new Engine(); |
| MapContext myMapContext = new MapContext(); |
| myMapContext.set(myName, myValue); |
| |
| Object myObjectWithTernaryConditional = myJexlEngine.createScript(myName + "?:null").execute(myMapContext); |
| Assert.assertEquals(myValue, myObjectWithTernaryConditional); |
| } |
| |
| @Test |
| public void test130b() throws Exception { |
| String myName = "Test.Name"; |
| Object myValue = new Object() { |
| @Override |
| public String toString() { |
| return "Test.Value"; |
| } |
| }; |
| |
| JexlEngine myJexlEngine = new Engine(); |
| MapContext myMapContext = new MapContext(); |
| myMapContext.set(myName, myValue); |
| |
| Object myObjectWithTernaryConditional = myJexlEngine.createScript(myName + "?:null").execute(myMapContext); |
| Assert.assertEquals(myValue, myObjectWithTernaryConditional); |
| } |
| |
| @Test |
| public void test135() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlContext jc = new MapContext(); |
| JexlScript script; |
| Object result; |
| Map<Integer, Object> foo = new HashMap<Integer, Object>(); |
| foo.put(3, 42); |
| jc.set("state", foo); |
| |
| script = jexl.createScript("var y = state[3]; y"); |
| result = script.execute(jc, foo); |
| Assert.assertEquals(42, result); |
| |
| jc.set("a", 3); |
| script = jexl.createScript("var y = state[a]; y"); |
| result = script.execute(jc, foo); |
| Assert.assertEquals(42, result); |
| |
| jc.set("a", 2); |
| script = jexl.createScript("var y = state[a + 1]; y"); |
| result = script.execute(jc, foo); |
| Assert.assertEquals(42, result); |
| |
| jc.set("a", 2); |
| jc.set("b", 1); |
| script = jexl.createScript("var y = state[a + b]; y"); |
| result = script.execute(jc, foo); |
| Assert.assertEquals(42, result); |
| |
| script = jexl.createScript("var y = state[3]; y", "state"); |
| result = script.execute(null, foo, 3); |
| Assert.assertEquals(42, result); |
| |
| script = jexl.createScript("var y = state[a]; y", "state", "a"); |
| result = script.execute(null, foo, 3); |
| Assert.assertEquals(42, result); |
| |
| script = jexl.createScript("var y = state[a + 1]; y", "state", "a"); |
| result = script.execute(null, foo, 2); |
| Assert.assertEquals(42, result); |
| |
| script = jexl.createScript("var y = state[a + b]; y", "state", "a", "b"); |
| result = script.execute(null, foo, 2, 1); |
| Assert.assertEquals(42, result); |
| } |
| |
| @Test |
| public void test136() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlContext jc = new MapContext(); |
| JexlScript script; |
| JexlExpression expr; |
| Object result; |
| |
| script = jexl.createScript("var x = $TAB[idx]; return x;", "idx"); |
| jc.set("fn01", script); |
| |
| script = jexl.createScript("$TAB = { 1:11, 2:22, 3:33}; IDX=2;"); |
| script.execute(jc); |
| |
| expr = jexl.createExpression("fn01(IDX)"); |
| result = expr.evaluate(jc); |
| Assert.assertEquals("EXPR01 result", 22, result); |
| } |
| |
| // @Test public void test138() throws Exception { |
| // MapContext ctxt = new MapContext(); |
| // ctxt.set("tz", java.util.TimeZone.class); |
| // String source = "" |
| // + "var currentDate = new('java.util.Date');" |
| // + "var gmt = tz.getTimeZone('GMT');" |
| // + "var cet = tz.getTimeZone('CET');" |
| // + "var calendarGMT = new('java.util.GregorianCalendar' , gmt);" |
| // + "var calendarCET = new('java.util.GregorianCalendar', cet);" |
| // + "var diff = calendarCET.getTime() - calendarGMT.getTime();" |
| // + "return diff"; |
| // |
| // JexlEngine jexl = new Engine(); |
| // JexlScript script = jexl.createScript(source); |
| // Object result = script.execute(ctxt); |
| // Assert.Assert.assertNotNull(result); |
| // } |
| @Test |
| public void test143() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlContext jc = new MapContext(); |
| JexlScript script; |
| Object result; |
| |
| script = jexl.createScript("var total = 10; total = (total - ((x < 3)? y : z)) / (total / 10); total", "x", "y", "z"); |
| result = script.execute(jc, 2, 2, 1); |
| Assert.assertEquals(8, result); |
| script = jexl.createScript("var total = 10; total = (total - ((x < 3)? y : 1)) / (total / 10); total", "x", "y", "z"); |
| result = script.execute(jc, 2, 2, 1); |
| Assert.assertEquals(8, result); |
| } |
| |
| @Test |
| public void test144() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlContext jc = new MapContext(); |
| JexlScript script; |
| Object result; |
| script = jexl.createScript("var total = 10; total('tt')"); |
| try { |
| result = script.execute(jc); |
| Assert.fail("total() is not solvable"); |
| } catch (JexlException.Method ambiguous) { |
| Assert.assertEquals("total", ambiguous.getMethod()); |
| } |
| } |
| |
| /** |
| * Test cases for empty array assignment. |
| */ |
| public static class Quux144 { |
| String[] arr; |
| String[] arr2; |
| |
| public Quux144() { |
| } |
| |
| public String[] getArr() { |
| return arr; |
| } |
| |
| public String[] getArr2() { |
| return arr2; |
| } |
| |
| public void setArr(String[] arr) { |
| this.arr = arr; |
| } |
| |
| public void setArr2(String[] arr2) { |
| this.arr2 = arr2; |
| } |
| |
| // Overloaded setter with different argument type. |
| public void setArr2(Integer[] arr2) { |
| } |
| } |
| |
| @Test |
| public void test144a() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlContext jc = new MapContext(); |
| jc.set("quuxClass", Quux144.class); |
| JexlExpression create = jexl.createExpression("quux = new(quuxClass)"); |
| JexlExpression assignArray = jexl.createExpression("quux.arr = [ 'hello', 'world' ]"); |
| JexlExpression checkArray = jexl.createExpression("quux.arr"); |
| |
| // test with a string |
| Quux144 quux = (Quux144) create.evaluate(jc); |
| Assert.assertNotNull("quux is null", quux); |
| |
| // test with a nonempty string array |
| Object o = assignArray.evaluate(jc); |
| Assert.assertEquals("Result is not a string array", String[].class, o.getClass()); |
| o = checkArray.evaluate(jc); |
| Assert.assertEquals("The array elements are equal", Arrays.asList("hello", "world"), Arrays.asList((String[]) o)); |
| |
| // test with a null array |
| assignArray = jexl.createExpression("quux.arr = null"); |
| o = assignArray.evaluate(jc); |
| Assert.assertNull("Result is not null", o); |
| o = checkArray.evaluate(jc); |
| Assert.assertNull("Result is not null", o); |
| |
| // test with an empty array |
| assignArray = jexl.createExpression("quux.arr = [ ]"); |
| o = assignArray.evaluate(jc); |
| Assert.assertNotNull("Result is null", o); |
| o = checkArray.evaluate(jc); |
| Assert.assertEquals("The array elements are not equal", Arrays.asList(new String[0]), Arrays.asList((String[]) o)); |
| Assert.assertEquals("The array size is not zero", 0, ((String[]) o).length); |
| |
| // test with an empty array on the overloaded setter for different types. |
| // so, the assignment should fail with logging 'The ambiguous property, arr2, should have failed.' |
| try { |
| assignArray = jexl.createExpression("quux.arr2 = [ ]"); |
| o = assignArray.evaluate(jc); |
| Assert.fail("The arr2 property shouldn't be set due to its ambiguity (overloaded setters with different types)."); |
| } catch (JexlException.Property e) { |
| //System.out.println("Expected ambiguous property setting exception: " + e); |
| } |
| Assert.assertNull("The arr2 property value should remain as null, not an empty array.", quux.arr2); |
| } |
| |
| @Test |
| public void test147b() throws Exception { |
| String[] scripts = {"var x = new ('java.util.HashMap'); x.one = 1; x.two = 2; x.one", // results to 1 |
| "x = new ('java.util.HashMap'); x.one = 1; x.two = 2; x.one",// results to 1 |
| "x = new ('java.util.HashMap'); x.one = 1; x.two = 2; x['one']",//results to 1 |
| "var x = new ('java.util.HashMap'); x.one = 1; x.two = 2; x['one']"// result to null? |
| }; |
| |
| JexlEngine jexl = new Engine(); |
| JexlContext jc = new MapContext(); |
| for (String s : scripts) { |
| Object o = jexl.createScript(s).execute(jc); |
| Assert.assertEquals(1, o); |
| } |
| } |
| |
| @Test |
| public void test147c() throws Exception { |
| String[] scripts = { |
| "var x = new ('java.util.HashMap'); x.one = 1; x.two = 2; x.one", |
| "x = new ('java.util.HashMap'); x.one = 1; x.two = 2; x.one", |
| "x = new ('java.util.HashMap'); x.one = 1; x.two = 2; x['one']", |
| "var x = new ('java.util.HashMap'); x.one = 1; x.two = 2; x['one']" |
| }; |
| JexlEngine jexl = new Engine(); |
| for (String s : scripts) { |
| JexlContext jc = new MapContext(); |
| Object o = jexl.createScript(s).execute(jc); |
| Assert.assertEquals(1, o); |
| } |
| } |
| |
| @Test |
| public void test5115a() throws Exception { |
| String str = "{\n" |
| + " var x = \"A comment\";\n" |
| + " var y = \"A comment\";\n" |
| + "}"; |
| try { |
| JexlEngine jexl = new Engine(); |
| JexlScript s = jexl.createScript(str); |
| } catch (JexlException.Parsing xparse) { |
| throw xparse; |
| } |
| } |
| |
| @Test |
| public void test5115b() throws Exception { |
| String str = "{\n" |
| + " var x = \"A comment\";\n" |
| + "}"; |
| try { |
| JexlEngine jexl = new Engine(); |
| JexlScript s = jexl.createScript(str); |
| } catch (JexlException.Parsing xparse) { |
| throw xparse; |
| } |
| } |
| |
| static final String TESTA = "src/test/scripts/testA.jexl"; |
| |
| @Test |
| public void test5115c() throws Exception { |
| URL testUrl = new File(TESTA).toURI().toURL(); |
| try { |
| JexlEngine jexl = new Engine(); |
| JexlScript s = jexl.createScript(testUrl); |
| } catch (JexlException.Parsing xparse) { |
| throw xparse; |
| } |
| } |
| |
| public static class Utils { |
| public <T> List<T> asList(T[] array) { |
| return Arrays.asList(array); |
| } |
| |
| public List<Integer> asList(int[] array) { |
| List<Integer> l = new ArrayList<Integer>(array.length); |
| for (int i : array) { |
| l.add(i); |
| } |
| return l; |
| } |
| } |
| |
| @Test |
| public void test148a() throws Exception { |
| JexlEngine jexl = new Engine(); |
| JexlContext jc = new MapContext(); |
| jc.set("u", new Utils()); |
| |
| String src = "u.asList(['foo', 'bar'])"; |
| JexlScript e = jexl.createScript(src); |
| Object o = e.execute(jc); |
| Assert.assertTrue(o instanceof List); |
| Assert.assertEquals(Arrays.asList("foo", "bar"), o); |
| |
| src = "u.asList([1, 2])"; |
| e = jexl.createScript(src); |
| o = e.execute(jc); |
| Assert.assertTrue(o instanceof List); |
| Assert.assertEquals(Arrays.asList(1, 2), o); |
| } |
| |
| @Test |
| public void test155() throws Exception { |
| JexlEngine jexlEngine = new Engine(); |
| JexlExpression jexlExpresssion = jexlEngine.createExpression("first.second.name"); |
| JexlContext jc = new MapContext(); |
| jc.set("first.second.name", "RIGHT"); |
| jc.set("name", "WRONG"); |
| Object value = jexlExpresssion.evaluate(jc); |
| Assert.assertEquals("RIGHT", value.toString()); |
| } |
| |
| public static class Question42 extends MapContext { |
| public String functionA(String arg) { |
| return "a".equals(arg) ? "A" : ""; |
| } |
| |
| public String functionB(String arg) { |
| return "b".equals(arg) ? "B" : ""; |
| } |
| |
| public String functionC(String arg) { |
| return "c".equals(arg) ? "C" : ""; |
| } |
| |
| public String functionD(String arg) { |
| return "d".equals(arg) ? "D" : ""; |
| } |
| } |
| |
| public static class Arithmetic42 extends JexlArithmetic { |
| public Arithmetic42() { |
| super(false); |
| } |
| |
| public Object and(String lhs, String rhs) { |
| if (rhs.isEmpty()) { |
| return ""; |
| } |
| if (lhs.isEmpty()) { |
| return ""; |
| } |
| return lhs + rhs; |
| } |
| |
| public Object or(String lhs, String rhs) { |
| if (rhs.isEmpty()) { |
| return lhs; |
| } |
| if (lhs.isEmpty()) { |
| return rhs; |
| } |
| return lhs + rhs; |
| } |
| } |
| |
| @Test |
| public void testQuestion42() throws Exception { |
| JexlEngine jexl = new JexlBuilder().arithmetic(new Arithmetic42()).create(); |
| JexlContext jc = new Question42(); |
| |
| String str0 = "(functionA('z') | functionB('b')) & (functionC('c') | functionD('d') ) "; |
| JexlExpression expr0 = jexl.createExpression(str0); |
| Object value0 = expr0.evaluate(jc); |
| Assert.assertEquals("BCD", value0); |
| |
| String str1 = "(functionA('z') & functionB('b')) | (functionC('c') & functionD('d') ) "; |
| JexlExpression expr1 = jexl.createExpression(str1); |
| Object value1 = expr1.evaluate(jc); |
| Assert.assertEquals("CD", value1); |
| } |
| |
| @Test |
| public void test179() throws Exception { |
| JexlContext jc = new MapContext(); |
| JexlEngine jexl = new JexlBuilder().create(); |
| String src = "x = new ('java.util.HashSet'); x.add(1); x"; |
| JexlScript e = jexl.createScript(src); |
| Object o = e.execute(jc); |
| Assert.assertTrue(o instanceof Set); |
| Assert.assertTrue(((Set) o).contains(1)); |
| } |
| |
| public static class C192 { |
| public C192() { |
| } |
| |
| public static Integer callme(Integer n) { |
| if (n == null) { |
| return null; |
| } else { |
| return n >= 0 ? 42 : -42; |
| } |
| } |
| |
| public static Object kickme() { |
| return C192.class; |
| } |
| } |
| |
| @Test |
| public void test192() throws Exception { |
| JexlContext jc = new MapContext(); |
| jc.set("x.y.z", C192.class); |
| JexlEngine jexl = new JexlBuilder().create(); |
| JexlExpression js0 = jexl.createExpression("x.y.z.callme(t)"); |
| jc.set("t", null); |
| Assert.assertNull(js0.evaluate(jc)); |
| jc.set("t", 10); |
| Assert.assertEquals(42, js0.evaluate(jc)); |
| jc.set("t", -10); |
| Assert.assertEquals(-42, js0.evaluate(jc)); |
| jc.set("t", null); |
| Assert.assertNull(js0.evaluate(jc)); |
| js0 = jexl.createExpression("x.y.z.kickme().callme(t)"); |
| jc.set("t", null); |
| Assert.assertNull(js0.evaluate(jc)); |
| jc.set("t", 10); |
| Assert.assertEquals(42, js0.evaluate(jc)); |
| jc.set("t", -10); |
| Assert.assertEquals(-42, js0.evaluate(jc)); |
| jc.set("t", null); |
| Assert.assertNull(js0.evaluate(jc)); |
| } |
| |
| @Test |
| public void test199() throws Exception { |
| JexlContext jc = new MapContext(); |
| JexlEngine jexl = new JexlBuilder().arithmetic(new JexlArithmetic(false)).create(); |
| |
| JexlScript e = jexl.createScript("(x, y)->{ x + y }"); |
| Object r = e.execute(jc, true, "EURT"); |
| Assert.assertEquals("trueEURT", r); |
| r = e.execute(jc, "ELSAF", false); |
| Assert.assertEquals("ELSAFfalse", r); |
| } |
| |
| public static class Eval { |
| private JexlEngine jexl; |
| |
| public JexlScript fn(String src) { |
| return jexl.createScript(src); |
| } |
| |
| void setJexl(JexlEngine je) { |
| jexl = je; |
| } |
| } |
| |
| @Test |
| public void test200() throws Exception { |
| JexlContext jc = new MapContext(); |
| Map<String, Object> funcs = new HashMap<String, Object>(); |
| Eval eval = new Eval(); |
| funcs.put(null, eval); |
| JexlEngine jexl = new JexlBuilder().namespaces(funcs).create(); |
| eval.setJexl(jexl); |
| String src = "var f = fn(\'(x)->{x + 42}\'); f(y)"; |
| JexlScript s200 = jexl.createScript(src, "y"); |
| Assert.assertEquals(142, s200.execute(jc, 100)); |
| Assert.assertEquals(52, s200.execute(jc, 10)); |
| } |
| |
| @Test |
| public void test200b() throws Exception { |
| JexlContext jc = new MapContext(); |
| JexlEngine jexl = new JexlBuilder().create(); |
| JexlScript e = jexl.createScript("var x = 0; var f = (y)->{ x = y; }; f(42); x"); |
| Object r = e.execute(jc); |
| Assert.assertEquals(0, r); |
| } |
| } |