blob: 99295e8c2a09282e7ced028b5f3592613e0abc34 [file] [log] [blame]
/*
* 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.junit.Asserter;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
@SuppressWarnings({"UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
public class ArithmeticTest extends JexlTestCase {
/** A small delta to compare doubles. */
private static final double EPSILON = 1.e-6;
private final Asserter asserter;
public ArithmeticTest() {
super("ArithmeticTest");
asserter = new Asserter(JEXL);
}
@Before
@Override
public void setUp() {
}
@Test
public void testUndefinedVar() throws Exception {
asserter.failExpression("objects[1].status", ".* undefined variable objects.*");
}
@Test
public void testLeftNullOperand() throws Exception {
asserter.setVariable("left", null);
asserter.setVariable("right", Integer.valueOf(8));
asserter.setStrict(true);
asserter.failExpression("left + right", ".*null.*");
asserter.failExpression("left - right", ".*null.*");
asserter.failExpression("left * right", ".*null.*");
asserter.failExpression("left / right", ".*null.*");
asserter.failExpression("left % right", ".*null.*");
asserter.failExpression("left & right", ".*null.*");
asserter.failExpression("left | right", ".*null.*");
asserter.failExpression("left ^ right", ".*null.*");
}
@Test
public void testRightNullOperand() throws Exception {
asserter.setVariable("left", Integer.valueOf(9));
asserter.setVariable("right", null);
asserter.failExpression("left + right", ".*null.*");
asserter.failExpression("left - right", ".*null.*");
asserter.failExpression("left * right", ".*null.*");
asserter.failExpression("left / right", ".*null.*");
asserter.failExpression("left % right", ".*null.*");
asserter.failExpression("left & right", ".*null.*");
asserter.failExpression("left | right", ".*null.*");
asserter.failExpression("left ^ right", ".*null.*");
}
@Test
public void testNullOperands() throws Exception {
asserter.setVariable("left", null);
asserter.setVariable("right", null);
asserter.failExpression("left + right", ".*null.*");
asserter.failExpression("left - right", ".*null.*");
asserter.failExpression("left * right", ".*null.*");
asserter.failExpression("left / right", ".*null.*");
asserter.failExpression("left % right", ".*null.*");
asserter.failExpression("left & right", ".*null.*");
asserter.failExpression("left | right", ".*null.*");
asserter.failExpression("left ^ right", ".*null.*");
}
@Test
public void testNullOperand() throws Exception {
asserter.setVariable("right", null);
asserter.failExpression("~right", ".*null.*");
}
@Test
public void testBigDecimal() throws Exception {
asserter.setVariable("left", new BigDecimal(2));
asserter.setVariable("right", new BigDecimal(6));
asserter.assertExpression("left + right", new BigDecimal(8));
asserter.assertExpression("right - left", new BigDecimal(4));
asserter.assertExpression("right * left", new BigDecimal(12));
asserter.assertExpression("right / left", new BigDecimal(3));
asserter.assertExpression("right % left", new BigDecimal(0));
}
@Test
public void testBigInteger() throws Exception {
asserter.setVariable("left", new BigInteger("2"));
asserter.setVariable("right", new BigInteger("6"));
asserter.assertExpression("left + right", new BigInteger("8"));
asserter.assertExpression("right - left", new BigInteger("4"));
asserter.assertExpression("right * left", new BigInteger("12"));
asserter.assertExpression("right / left", new BigInteger("3"));
asserter.assertExpression("right % left", new BigInteger("0"));
}
/**
* test some simple mathematical calculations
*/
@Test
public void testUnaryMinus() throws Exception {
asserter.setVariable("aByte", new Byte((byte) 1));
asserter.setVariable("aShort", new Short((short) 2));
asserter.setVariable("anInteger", new Integer(3));
asserter.setVariable("aLong", new Long(4));
asserter.setVariable("aFloat", new Float(5.5));
asserter.setVariable("aDouble", new Double(6.6));
asserter.setVariable("aBigInteger", new BigInteger("7"));
asserter.setVariable("aBigDecimal", new BigDecimal("8.8"));
asserter.assertExpression("-3", new Integer("-3"));
asserter.assertExpression("-3.0", new Double("-3.0"));
asserter.assertExpression("-aByte", new Byte((byte) -1));
asserter.assertExpression("-aShort", new Short((short) -2));
asserter.assertExpression("-anInteger", new Integer(-3));
asserter.assertExpression("-aLong", new Long(-4));
asserter.assertExpression("-aFloat", new Float(-5.5));
asserter.assertExpression("-aDouble", new Double(-6.6));
asserter.assertExpression("-aBigInteger", new BigInteger("-7"));
asserter.assertExpression("-aBigDecimal", new BigDecimal("-8.8"));
}
/**
* test some simple mathematical calculations
*/
@Test
public void testCalculations() throws Exception {
asserter.setStrict(true, false);
/*
* test new null coersion
*/
asserter.setVariable("imanull", null);
asserter.assertExpression("imanull + 2", new Integer(2));
asserter.assertExpression("imanull + imanull", new Integer(0));
asserter.setVariable("foo", new Integer(2));
asserter.assertExpression("foo + 2", new Integer(4));
asserter.assertExpression("3 + 3", new Integer(6));
asserter.assertExpression("3 + 3 + foo", new Integer(8));
asserter.assertExpression("3 * 3", new Integer(9));
asserter.assertExpression("3 * 3 + foo", new Integer(11));
asserter.assertExpression("3 * 3 - foo", new Integer(7));
/*
* test parenthesized exprs
*/
asserter.assertExpression("(4 + 3) * 6", new Integer(42));
asserter.assertExpression("(8 - 2) * 7", new Integer(42));
/*
* test some floaty stuff
*/
asserter.assertExpression("3 * \"3.0\"", new Double(9));
asserter.assertExpression("3 * 3.0", new Double(9));
/*
* test / and %
*/
asserter.setStrict(false, false);
asserter.assertExpression("6 / 3", new Integer(6 / 3));
asserter.assertExpression("6.4 / 3", new Double(6.4 / 3));
asserter.assertExpression("0 / 3", new Integer(0 / 3));
asserter.assertExpression("3 / 0", new Double(0));
asserter.assertExpression("4 % 3", new Integer(1));
asserter.assertExpression("4.8 % 3", new Double(4.8 % 3));
}
@Test
public void testCoercions() throws Exception {
asserter.assertExpression("1", new Integer(1)); // numerics default to Integer
asserter.assertExpression("5L", new Long(5));
asserter.setVariable("I2", new Integer(2));
asserter.setVariable("L2", new Long(2));
asserter.setVariable("L3", new Long(3));
asserter.setVariable("B10", BigInteger.TEN);
// Integer & Integer => Integer
asserter.assertExpression("I2 + 2", new Integer(4));
asserter.assertExpression("I2 * 2", new Integer(4));
asserter.assertExpression("I2 - 2", new Integer(0));
asserter.assertExpression("I2 / 2", new Integer(1));
// Integer & Long => Long
asserter.assertExpression("I2 * L2", new Long(4));
asserter.assertExpression("I2 / L2", new Long(1));
// Long & Long => Long
asserter.assertExpression("L2 + 3", new Long(5));
asserter.assertExpression("L2 + L3", new Long(5));
asserter.assertExpression("L2 / L2", new Long(1));
asserter.assertExpression("L2 / 2", new Long(1));
// BigInteger
asserter.assertExpression("B10 / 10", BigInteger.ONE);
asserter.assertExpression("B10 / I2", new BigInteger("5"));
asserter.assertExpression("B10 / L2", new BigInteger("5"));
}
// JEXL-24: long integers (and doubles)
@Test
public void testLongLiterals() throws Exception {
JexlEvalContext ctxt = new JexlEvalContext();
ctxt.setStrictArithmetic(true);
String stmt = "{a = 10L; b = 10l; c = 42.0D; d = 42.0d; e=56.3F; f=56.3f; g=63.5; h=0x10; i=010; j=0x10L; k=010l}";
JexlScript expr = JEXL.createScript(stmt);
/* Object value = */ expr.execute(ctxt);
Assert.assertEquals(10L, ctxt.get("a"));
Assert.assertEquals(10l, ctxt.get("b"));
Assert.assertEquals(42.0D, ctxt.get("c"));
Assert.assertEquals(42.0d, ctxt.get("d"));
Assert.assertEquals(56.3f, ctxt.get("e"));
Assert.assertEquals(56.3f, ctxt.get("f"));
Assert.assertEquals(63.5d, ctxt.get("g"));
Assert.assertEquals(0x10, ctxt.get("h"));
Assert.assertEquals(010, ctxt.get("i"));
Assert.assertEquals(0x10L, ctxt.get("j"));
Assert.assertEquals(010l, ctxt.get("k"));
}
@Test
public void testBigLiteralValue() throws Exception {
JexlEvalContext ctxt = new JexlEvalContext();
ctxt.setStrictArithmetic(true);
JexlExpression e = JEXL.createExpression("9223372036854775806.5B");
String res = String.valueOf(e.evaluate(ctxt));
Assert.assertEquals("9223372036854775806.5", res);
}
@Test
public void testBigdOp() throws Exception {
BigDecimal sevendot475 = new BigDecimal("7.475");
BigDecimal SO = new BigDecimal("325");
JexlContext jc = new MapContext();
jc.set("SO", SO);
String expr = "2.3*SO/100";
Object evaluate = JEXL.createExpression(expr).evaluate(jc);
Assert.assertEquals(sevendot475, (BigDecimal) evaluate);
}
// JEXL-24: big integers and big decimals
@Test
public void testBigLiterals() throws Exception {
JexlEvalContext ctxt = new JexlEvalContext();
ctxt.setStrictArithmetic(true);
String stmt = "{a = 10H; b = 10h; c = 42.0B; d = 42.0b;}";
JexlScript expr = JEXL.createScript(stmt);
/* Object value = */ expr.execute(ctxt);
Assert.assertEquals(new BigInteger("10"), ctxt.get("a"));
Assert.assertEquals(new BigInteger("10"), ctxt.get("b"));
Assert.assertEquals(new BigDecimal("42.0"), ctxt.get("c"));
Assert.assertEquals(new BigDecimal("42.0"), ctxt.get("d"));
}
// JEXL-24: big decimals with exponent
@Test
public void testBigExponentLiterals() throws Exception {
JexlEvalContext ctxt = new JexlEvalContext();
ctxt.setStrictArithmetic(true);
String stmt = "{a = 42.0e1B; b = 42.0E+2B; c = 42.0e-1B; d = 42.0E-2b; e=4242.4242e1b}";
JexlScript expr = JEXL.createScript(stmt);
/* Object value = */ expr.execute(ctxt);
Assert.assertEquals(new BigDecimal("42.0e+1"), ctxt.get("a"));
Assert.assertEquals(new BigDecimal("42.0e+2"), ctxt.get("b"));
Assert.assertEquals(new BigDecimal("42.0e-1"), ctxt.get("c"));
Assert.assertEquals(new BigDecimal("42.0e-2"), ctxt.get("d"));
Assert.assertEquals(new BigDecimal("4242.4242e1"), ctxt.get("e"));
}
// JEXL-24: doubles with exponent
public void test2DoubleLiterals() throws Exception {
JexlEvalContext ctxt = new JexlEvalContext();
ctxt.setStrictArithmetic(true);
String stmt = "{a = 42.0e1D; b = 42.0E+2D; c = 42.0e-1d; d = 42.0E-2d;}";
JexlScript expr = JEXL.createScript(stmt);
/* Object value = */ expr.execute(ctxt);
Assert.assertEquals(Double.valueOf("42.0e+1"), ctxt.get("a"));
Assert.assertEquals(Double.valueOf("42.0e+2"), ctxt.get("b"));
Assert.assertEquals(Double.valueOf("42.0e-1"), ctxt.get("c"));
Assert.assertEquals(Double.valueOf("42.0e-2"), ctxt.get("d"));
}
/**
*
* if silent, all arith exception return 0.0
* if not silent, all arith exception throw
* @throws Exception
*/
@Test
public void testDivideByZero() throws Exception {
Map<String, Object> vars = new HashMap<String, Object>();
JexlEvalContext context = new JexlEvalContext(vars);
vars.put("aByte", new Byte((byte) 1));
vars.put("aShort", new Short((short) 2));
vars.put("aInteger", new Integer(3));
vars.put("aLong", new Long(4));
vars.put("aFloat", new Float(5.5));
vars.put("aDouble", new Double(6.6));
vars.put("aBigInteger", new BigInteger("7"));
vars.put("aBigDecimal", new BigDecimal("8.8"));
vars.put("zByte", new Byte((byte) 0));
vars.put("zShort", new Short((short) 0));
vars.put("zInteger", new Integer(0));
vars.put("zLong", new Long(0));
vars.put("zFloat", new Float(0));
vars.put("zDouble", new Double(0));
vars.put("zBigInteger", new BigInteger("0"));
vars.put("zBigDecimal", new BigDecimal("0"));
String[] tnames = {
"Byte", "Short", "Integer", "Long",
"Float", "Double",
"BigInteger", "BigDecimal"
};
// number of permutations this will generate
final int PERMS = tnames.length * tnames.length;
JexlEngine jexl = JEXL;
// for non-silent, silent...
for (int s = 0; s < 2; ++s) {
boolean strict = Boolean.valueOf(s != 0);
context.setStrict(true, strict);
int zthrow = 0;
int zeval = 0;
// for vars of all types...
for (String vname : tnames) {
// for zeros of all types...
for (String zname : tnames) {
// divide var by zero
String expr = "a" + vname + " / " + "z" + zname;
try {
JexlExpression zexpr = jexl.createExpression(expr);
Object nan = zexpr.evaluate(context);
// check we have a zero & incremement zero count
if (nan instanceof Number) {
double zero = ((Number) nan).doubleValue();
if (zero == 0.0) {
zeval += 1;
}
}
} catch (Exception any) {
// increment the exception count
zthrow += 1;
}
}
}
if (strict) {
Assert.assertTrue("All expressions should have thrown " + zthrow + "/" + PERMS,
zthrow == PERMS);
} else {
Assert.assertTrue("All expressions should have zeroed " + zeval + "/" + PERMS,
zeval == PERMS);
}
}
debuggerCheck(jexl);
}
@Test
public void testNaN() throws Exception {
Map<String, Object> ns = new HashMap<String, Object>();
ns.put("double", Double.class);
JexlEngine jexl = new JexlBuilder().namespaces(ns).create();
JexlScript script;
Object result;
script = jexl.createScript("#NaN");
result = script.execute(null);
Assert.assertTrue(Double.isNaN((Double) result));
script = jexl.createScript("NaN");
result = script.execute(null);
Assert.assertTrue(Double.isNaN((Double) result));
script = jexl.createScript("double:isNaN(#NaN)");
result = script.execute(null);
Assert.assertTrue((Boolean) result);
script = jexl.createScript("double:isNaN(NaN)");
result = script.execute(null);
Assert.assertTrue((Boolean) result);
}
@Test
/**
* JEXL-156.
*/
public void testMultClass() throws Exception {
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
Object ra = jexl.createExpression("463.0d * 0.1").evaluate(jc);
Assert.assertEquals(Double.class, ra.getClass());
Object r0 = jexl.createExpression("463.0B * 0.1").evaluate(jc);
Assert.assertEquals(java.math.BigDecimal.class, r0.getClass());
Object r1 = jexl.createExpression("463.0B * 0.1B").evaluate(jc);
Assert.assertEquals(java.math.BigDecimal.class, r1.getClass());
}
public void testDivClass() throws Exception {
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
Object ra = jexl.createExpression("463.0d / 0.1").evaluate(jc);
Assert.assertEquals(Double.class, ra.getClass());
Object r0 = jexl.createExpression("463.0B / 0.1").evaluate(jc);
Assert.assertEquals(java.math.BigDecimal.class, r0.getClass());
Object r1 = jexl.createExpression("463.0B / 0.1B").evaluate(jc);
Assert.assertEquals(java.math.BigDecimal.class, r1.getClass());
}
public void testPlusClass() throws Exception {
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
Object ra = jexl.createExpression("463.0d + 0.1").evaluate(jc);
Assert.assertEquals(Double.class, ra.getClass());
Object r0 = jexl.createExpression("463.0B + 0.1").evaluate(jc);
Assert.assertEquals(java.math.BigDecimal.class, r0.getClass());
Object r1 = jexl.createExpression("463.0B + 0.1B").evaluate(jc);
Assert.assertEquals(java.math.BigDecimal.class, r1.getClass());
}
public void testMinusClass() throws Exception {
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
Object ra = jexl.createExpression("463.0d - 0.1").evaluate(jc);
Assert.assertEquals(Double.class, ra.getClass());
Object r0 = jexl.createExpression("463.0B - 0.1").evaluate(jc);
Assert.assertEquals(java.math.BigDecimal.class, r0.getClass());
Object r1 = jexl.createExpression("463.0B - 0.1B").evaluate(jc);
Assert.assertEquals(java.math.BigDecimal.class, r1.getClass());
}
@Test
public void testAddWithStringsLenient() throws Exception {
JexlEngine jexl = new JexlBuilder().arithmetic(new JexlArithmetic(false)).create();
JexlScript script;
Object result;
script = jexl.createScript("'a' + 0");
result = script.execute(null);
Assert.assertEquals("a0", result);
script = jexl.createScript("0 + 'a' ");
result = script.execute(null);
Assert.assertEquals("0a", result);
script = jexl.createScript("0 + '1.2' ");
result = script.execute(null);
Assert.assertEquals(1.2d, (Double) result, EPSILON);
script = jexl.createScript("'1.2' + 1.2 ");
result = script.execute(null);
Assert.assertEquals(2.4d, (Double) result, EPSILON);
script = jexl.createScript("1.2 + 1.2 ");
result = script.execute(null);
Assert.assertEquals(2.4d, (Double) result, EPSILON);
script = jexl.createScript("1.2 + '1.2' ");
result = script.execute(null);
Assert.assertEquals(2.4d, (Double) result, EPSILON);
script = jexl.createScript("'1.2' + 0 ");
result = script.execute(null);
Assert.assertEquals(1.2d, (Double) result, EPSILON);
script = jexl.createScript("'1.2' + '1.2' ");
result = script.execute(null);
Assert.assertEquals("1.21.2", result);
}
@Test
public void testAddWithStringsStrict() throws Exception {
JexlEngine jexl = new JexlBuilder().arithmetic(new JexlArithmetic(true)).create();
JexlScript script;
Object result;
script = jexl.createScript("'a' + 0");
result = script.execute(null);
Assert.assertEquals("a0", result);
script = jexl.createScript("0 + 'a' ");
result = script.execute(null);
Assert.assertEquals("0a", result);
script = jexl.createScript("0 + '1.2' ");
result = script.execute(null);
Assert.assertEquals("01.2", result);
script = jexl.createScript("'1.2' + 1.2 ");
result = script.execute(null);
Assert.assertEquals("1.21.2", result);
script = jexl.createScript("1.2 + 1.2 ");
result = script.execute(null);
Assert.assertEquals(2.4d, (Double) result, EPSILON);
script = jexl.createScript("1.2 + '1.2' ");
result = script.execute(null);
Assert.assertEquals("1.21.2", result);
script = jexl.createScript("'1.2' + 0 ");
result = script.execute(null);
Assert.assertEquals("1.20", result);
script = jexl.createScript("'1.2' + '1.2' ");
result = script.execute(null);
Assert.assertEquals("1.21.2", result);
}
@Test
public void testOption() throws Exception {
Map<String, Object> vars = new HashMap<String, Object>();
JexlEvalContext context = new JexlEvalContext(vars);
JexlScript script = JEXL.createScript("0 + '1.2' ");
Object result;
context.setStrictArithmetic(true);
result = script.execute(context);
Assert.assertEquals("01.2", result);
context.setStrictArithmetic(false);
result = script.execute(context);
Assert.assertEquals(1.2d, (Double) result, EPSILON);
}
@Test
public void testIsFloatingPointPattern() throws Exception {
JexlArithmetic ja = new JexlArithmetic(true);
Assert.assertFalse(ja.isFloatingPointNumber("floating point"));
Assert.assertFalse(ja.isFloatingPointNumber("a1."));
Assert.assertFalse(ja.isFloatingPointNumber("b1.2"));
Assert.assertFalse(ja.isFloatingPointNumber("-10.2a-34"));
Assert.assertFalse(ja.isFloatingPointNumber("+10.2a+34"));
Assert.assertFalse(ja.isFloatingPointNumber("0"));
Assert.assertFalse(ja.isFloatingPointNumber("1"));
Assert.assertFalse(ja.isFloatingPointNumber("12A"));
Assert.assertFalse(ja.isFloatingPointNumber("2F3"));
Assert.assertFalse(ja.isFloatingPointNumber("23"));
Assert.assertFalse(ja.isFloatingPointNumber("+3"));
Assert.assertFalse(ja.isFloatingPointNumber("+34"));
Assert.assertFalse(ja.isFloatingPointNumber("+3-4"));
Assert.assertFalse(ja.isFloatingPointNumber("+3.-4"));
Assert.assertFalse(ja.isFloatingPointNumber("3ee4"));
Assert.assertTrue(ja.isFloatingPointNumber("0."));
Assert.assertTrue(ja.isFloatingPointNumber("1."));
Assert.assertTrue(ja.isFloatingPointNumber("1.2"));
Assert.assertTrue(ja.isFloatingPointNumber("1.2e3"));
Assert.assertTrue(ja.isFloatingPointNumber("2e3"));
Assert.assertTrue(ja.isFloatingPointNumber("+2e-3"));
Assert.assertTrue(ja.isFloatingPointNumber("+23E-34"));
Assert.assertTrue(ja.isFloatingPointNumber("+23.E-34"));
Assert.assertTrue(ja.isFloatingPointNumber("-23.4E+45"));
Assert.assertTrue(ja.isFloatingPointNumber("1.2e34"));
Assert.assertTrue(ja.isFloatingPointNumber("10.2e34"));
Assert.assertTrue(ja.isFloatingPointNumber("+10.2e34"));
Assert.assertTrue(ja.isFloatingPointNumber("-10.2e34"));
Assert.assertTrue(ja.isFloatingPointNumber("10.2e-34"));
Assert.assertTrue(ja.isFloatingPointNumber("10.2e+34"));
Assert.assertTrue(ja.isFloatingPointNumber("-10.2e-34"));
Assert.assertTrue(ja.isFloatingPointNumber("+10.2e+34"));
Assert.assertTrue(ja.isFloatingPointNumber("-10.2E-34"));
Assert.assertTrue(ja.isFloatingPointNumber("+10.2E+34"));
}
public static class EmptyTestContext extends MapContext implements JexlContext.NamespaceResolver {
public static int log(Object fmt, Object... arr) {
//System.out.println(String.format(fmt.toString(), arr));
return arr == null ? 0 : arr.length;
}
public static int log(Object fmt, int... arr) {
//System.out.println(String.format(fmt.toString(), arr));
return arr == null ? 0 : arr.length;
}
@Override
public Object resolveNamespace(String name) {
return this;
}
}
@Test
public void testEmpty() throws Exception {
Object[] SCRIPTS = {
"var x = null; log('x = %s', x);", 0,
"var x = 'abc'; log('x = %s', x);", 1,
"var x = 333; log('x = %s', x);", 1,
"var x = [1, 2]; log('x = %s', x);", 2,
"var x = ['a', 'b']; log('x = %s', x);", 2,
"var x = {1:'A', 2:'B'}; log('x = %s', x);", 1,
"var x = null; return empty(x);", true,
"var x = ''; return empty(x);", true,
"var x = 'abc'; return empty(x);", false,
"var x = 0; return empty(x);", true,
"var x = 333; return empty(x);", false,
"var x = []; return empty(x);", true,
"var x = [1, 2]; return empty(x);", false,
"var x = ['a', 'b']; return empty(x);", false,
"var x = {:}; return empty(x);", true,
"var x = {1:'A', 2:'B'}; return empty(x);", false
};
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new EmptyTestContext();
JexlScript script;
for (int e = 0; e < SCRIPTS.length; e += 2) {
String stext = (String) SCRIPTS[e];
Object expected = SCRIPTS[e + 1];
script = jexl.createScript(stext);
Object result = script.execute(jc);
Assert.assertEquals("failed on " + stext, expected, result);
}
}
public static class Var {
int value;
Var(int v) {
value = v;
}
@Override
public String toString() {
return Integer.toString(value);
}
}
// an arithmetic that know how to subtract strings
public static class ArithmeticPlus extends JexlArithmetic {
public ArithmeticPlus(boolean strict) {
super(strict);
}
public boolean equals(Var lhs, Var rhs) {
return lhs.value == rhs.value;
}
public boolean lessThan(Var lhs, Var rhs) {
return lhs.value < rhs.value;
}
public boolean lessThanOrEqual(Var lhs, Var rhs) {
return lhs.value <= rhs.value;
}
public boolean greaterThan(Var lhs, Var rhs) {
return lhs.value > rhs.value;
}
public boolean greaterThanOrEqual(Var lhs, Var rhs) {
return lhs.value >= rhs.value;
}
public Var add(Var lhs, Var rhs) {
return new Var(lhs.value + rhs.value);
}
public Var subtract(Var lhs, Var rhs) {
return new Var(lhs.value - rhs.value);
}
public Var divide(Var lhs, Var rhs) {
return new Var(lhs.value / rhs.value);
}
public Var multiply(Var lhs, Var rhs) {
return new Var(lhs.value * rhs.value);
}
public Var mod(Var lhs, Var rhs) {
return new Var(lhs.value / rhs.value);
}
public Var negate(Var arg) {
return new Var(-arg.value);
}
public Var and(Var lhs, Var rhs) {
return new Var(lhs.value & rhs.value);
}
public Var or(Var lhs, Var rhs) {
return new Var(lhs.value | rhs.value);
}
public Var xor(Var lhs, Var rhs) {
return new Var(lhs.value ^ rhs.value);
}
public Boolean contains(Var lhs, Var rhs) {
return lhs.toString().contains(rhs.toString());
}
public Boolean startsWith(Var lhs, Var rhs) {
return lhs.toString().startsWith(rhs.toString());
}
public Boolean endsWith(Var lhs, Var rhs) {
return lhs.toString().endsWith(rhs.toString());
}
public Var complement(Var arg) {
return new Var(~arg.value);
}
public Object subtract(String x, String y) {
int ix = x.indexOf(y);
if (ix < 0) {
return x;
}
StringBuilder strb = new StringBuilder(x.substring(0, ix));
strb.append(x.substring(ix + y.length()));
return strb.toString();
}
public Object negate(final String str) {
final int length = str.length();
StringBuilder strb = new StringBuilder(str.length());
for (int c = length - 1; c >= 0; --c) {
strb.append(str.charAt(c));
}
return strb.toString();
}
public Object not(Var x) {
throw new NullPointerException("make it fail");
}
}
@Test
public void testArithmeticPlus() throws Exception {
JexlEngine jexl = new JexlBuilder().cache(64).arithmetic(new ArithmeticPlus(false)).create();
JexlContext jc = new EmptyTestContext();
runOverload(jexl, jc);
runOverload(jexl, jc);
}
@Test
public void testArithmeticPlusNoCache() throws Exception {
JexlEngine jexl = new JexlBuilder().cache(0).arithmetic(new ArithmeticPlus(false)).create();
JexlContext jc = new EmptyTestContext();
runOverload(jexl, jc);
}
protected void runOverload(JexlEngine jexl, JexlContext jc) {
JexlScript script;
Object result;
script = jexl.createScript("(x, y)->{ x < y }");
result = script.execute(jc, 42, 43);
Assert.assertEquals(true, result);
result = script.execute(jc, new Var(42), new Var(43));
Assert.assertEquals(true, result);
result = script.execute(jc, new Var(42), new Var(43));
Assert.assertEquals(true, result);
result = script.execute(jc, 43, 42);
Assert.assertEquals(false, result);
result = script.execute(jc, new Var(43), new Var(42));
Assert.assertEquals(false, result);
script = jexl.createScript("(x, y)->{ x <= y }");
result = script.execute(jc, 42, 43);
Assert.assertEquals(true, result);
result = script.execute(jc, new Var(42), new Var(43));
Assert.assertEquals(true, result);
result = script.execute(jc, new Var(41), new Var(44));
Assert.assertEquals(true, result);
result = script.execute(jc, 43, 42);
Assert.assertEquals(false, result);
result = script.execute(jc, new Var(45), new Var(40));
Assert.assertEquals(false, result);
script = jexl.createScript("(x, y)->{ x > y }");
result = script.execute(jc, 42, 43);
Assert.assertEquals(false, result);
result = script.execute(jc, new Var(42), new Var(43));
Assert.assertEquals(false, result);
result = script.execute(jc, new Var(42), new Var(43));
Assert.assertEquals(false, result);
result = script.execute(jc, 43, 42);
Assert.assertEquals(true, result);
result = script.execute(jc, new Var(43), new Var(42));
Assert.assertEquals(true, result);
script = jexl.createScript("(x, y)->{ x >= y }");
result = script.execute(jc, 42, 43);
Assert.assertEquals(false, result);
result = script.execute(jc, new Var(42), new Var(43));
Assert.assertEquals(false, result);
result = script.execute(jc, new Var(41), new Var(44));
Assert.assertEquals(false, result);
result = script.execute(jc, 43, 42);
Assert.assertEquals(true, result);
result = script.execute(jc, new Var(45), new Var(40));
Assert.assertEquals(true, result);
script = jexl.createScript("(x, y)->{ x == y }");
result = script.execute(jc, 42, 43);
Assert.assertEquals(false, result);
result = script.execute(jc, new Var(42), new Var(43));
Assert.assertEquals(false, result);
result = script.execute(jc, new Var(41), new Var(44));
Assert.assertEquals(false, result);
result = script.execute(jc, 43, 42);
Assert.assertEquals(false, result);
result = script.execute(jc, new Var(45), new Var(40));
Assert.assertEquals(false, result);
script = jexl.createScript("(x, y)->{ x != y }");
result = script.execute(jc, 42, 43);
Assert.assertEquals(true, result);
result = script.execute(jc, new Var(42), new Var(43));
Assert.assertEquals(true, result);
result = script.execute(jc, new Var(44), new Var(44));
Assert.assertEquals(false, result);
result = script.execute(jc, 44, 44);
Assert.assertEquals(false, result);
result = script.execute(jc, new Var(45), new Var(40));
Assert.assertEquals(true, result);
script = jexl.createScript("(x, y)->{ x % y }");
result = script.execute(jc, 4242, 100);
Assert.assertEquals(42, result);
result = script.execute(jc, new Var(4242), new Var(100));
Assert.assertEquals(42, ((Var) result).value);
script = jexl.createScript("(x, y)->{ x * y }");
result = script.execute(jc, 6, 7);
Assert.assertEquals(42, result);
result = script.execute(jc, new Var(6), new Var(7));
Assert.assertEquals(42, ((Var) result).value);
script = jexl.createScript("(x, y)->{ x + y }");
result = script.execute(jc, 35, 7);
Assert.assertEquals(42, result);
result = script.execute(jc, new Var(35), new Var(7));
Assert.assertEquals(42, ((Var) result).value);
script = jexl.createScript("(x, y)->{ x - y }");
result = script.execute(jc, 49, 7);
Assert.assertEquals(42, result);
result = script.execute(jc, "foobarquux", "bar");
Assert.assertEquals("fooquux", result);
result = script.execute(jc, 50, 8);
Assert.assertEquals(42, result);
result = script.execute(jc, new Var(50), new Var(8));
Assert.assertEquals(42, ((Var) result).value);
script = jexl.createScript("(x)->{ -x }");
result = script.execute(jc, -42);
Assert.assertEquals(42, result);
result = script.execute(jc, new Var(-42));
Assert.assertEquals(42, ((Var) result).value);
result = script.execute(jc, "pizza");
Assert.assertEquals("azzip", result);
result = script.execute(jc, -142);
Assert.assertEquals(142, result);
script = jexl.createScript("(x)->{ ~x }");
result = script.execute(jc, -1);
Assert.assertEquals(0L, result);
result = script.execute(jc, new Var(-1));
Assert.assertEquals(0L, ((Var) result).value);
result = script.execute(jc, new Var(-42));
Assert.assertEquals(41, ((Var) result).value);
script = jexl.createScript("(x, y)->{ x ^ y }");
result = script.execute(jc, 35, 7);
Assert.assertEquals(36L, result);
result = script.execute(jc, new Var(35), new Var(7));
Assert.assertEquals(36L, ((Var) result).value);
script = jexl.createScript("(x, y)->{ x & y }");
result = script.execute(jc, 35, 7);
Assert.assertEquals(3L, result);
result = script.execute(jc, new Var(35), new Var(7));
Assert.assertEquals(3L, ((Var) result).value);
script = jexl.createScript("(x, y)->{ x =^ y }");
result = script.execute(jc, 3115, 31);
Assert.assertFalse((Boolean) result);
result = script.execute(jc, new Var(3115), new Var(31));
Assert.assertTrue((Boolean) result);
script = jexl.createScript("(x, y)->{ x !^ y }");
result = script.execute(jc, 3115, 31);
Assert.assertTrue((Boolean) result);
result = script.execute(jc, new Var(3115), new Var(31));
Assert.assertFalse((Boolean) result);
script = jexl.createScript("(x, y)->{ x =$ y }");
result = script.execute(jc, 3115, 15);
Assert.assertFalse((Boolean) result);
result = script.execute(jc, new Var(3115), new Var(15));
Assert.assertTrue((Boolean) result);
script = jexl.createScript("(x, y)->{ x !$ y }");
result = script.execute(jc, 3115, 15);
Assert.assertTrue((Boolean) result);
result = script.execute(jc, new Var(3115), new Var(15));
Assert.assertFalse((Boolean) result);
script = jexl.createScript("(x, y)->{ x =~ y }");
result = script.execute(jc, 3155, 15);
Assert.assertFalse((Boolean) result);
result = script.execute(jc, new Var(3155), new Var(15));
Assert.assertFalse((Boolean) result);
result = script.execute(jc, new Var(15), new Var(3155));
Assert.assertTrue((Boolean) result);
script = jexl.createScript("(x, y)->{ x !~ y }");
result = script.execute(jc, 3115, 15);
Assert.assertTrue((Boolean) result);
result = script.execute(jc, new Var(3155), new Var(15));
Assert.assertTrue((Boolean) result);
result = script.execute(jc, new Var(15), new Var(3155));
Assert.assertFalse((Boolean) result);
script = jexl.createScript("(x)->{ !x }");
try {
result = script.execute(jc, new Var(-42));
Assert.fail("should fail");
} catch (JexlException xany) {
Assert.assertTrue(xany instanceof JexlException.Operator);
}
}
public class Callable173 {
public Object call(String... arg) {
return 42;
}
public Object call(Integer... arg) {
return arg[0] * arg[1];
}
}
@Test
public void testJexl173() throws Exception {
JexlEngine jexl = new JexlBuilder().create();
JexlContext jc = new MapContext();
Callable173 c173 = new Callable173();
JexlScript e = jexl.createScript( "c173(9, 6)", "c173" );
Object result = e.execute(jc, c173);
Assert.assertEquals(54, result);
e = jexl.createScript( "c173('fourty', 'two')", "c173" );
result = e.execute(jc, c173);
Assert.assertEquals(42, result);
}
public static class Arithmetic132 extends JexlArithmetic {
public Arithmetic132() {
super(false);
}
protected double divideZero(BigDecimal x) {
int ls = x.signum();
if (ls < 0) {
return Double.NEGATIVE_INFINITY;
} else if (ls > 0) {
return Double.POSITIVE_INFINITY;
} else {
return Double.NaN;
}
}
protected double divideZero(BigInteger x) {
int ls = x.signum();
if (ls < 0) {
return Double.NEGATIVE_INFINITY;
} else if (ls > 0) {
return Double.POSITIVE_INFINITY;
} else {
return Double.NaN;
}
}
@Override
public Object divide(Object left, Object right) {
if (left == null && right == null) {
return controlNullNullOperands();
}
// if either are bigdecimal use that type
if (left instanceof BigDecimal || right instanceof BigDecimal) {
BigDecimal l = toBigDecimal(left);
BigDecimal r = toBigDecimal(right);
if (BigDecimal.ZERO.equals(r)) {
return divideZero(l);
}
BigDecimal result = l.divide(r, getMathContext());
return narrowBigDecimal(left, right, result);
}
// if either are floating point (double or float) use double
if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
double l = toDouble(left);
double r = toDouble(right);
return new Double(l / r);
}
// otherwise treat as integers
BigInteger l = toBigInteger(left);
BigInteger r = toBigInteger(right);
if (BigInteger.ZERO.equals(r)) {
return divideZero(l);
}
BigInteger result = l.divide(r);
return narrowBigInteger(left, right, result);
}
@Override
public Object mod(Object left, Object right) {
if (left == null && right == null) {
return controlNullNullOperands();
}
// if either are bigdecimal use that type
if (left instanceof BigDecimal || right instanceof BigDecimal) {
BigDecimal l = toBigDecimal(left);
BigDecimal r = toBigDecimal(right);
if (BigDecimal.ZERO.equals(r)) {
return divideZero(l);
}
BigDecimal remainder = l.remainder(r, getMathContext());
return narrowBigDecimal(left, right, remainder);
}
// if either are floating point (double or float) use double
if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
double l = toDouble(left);
double r = toDouble(right);
return new Double(l % r);
}
// otherwise treat as integers
BigInteger l = toBigInteger(left);
BigInteger r = toBigInteger(right);
BigInteger result = l.mod(r);
if (BigInteger.ZERO.equals(r)) {
return divideZero(l);
}
return narrowBigInteger(left, right, result);
}
}
@Test
public void testInfiniteArithmetic() throws Exception {
Map<String, Object> ns = new HashMap<String, Object>();
ns.put("math", Math.class);
JexlEngine jexl = new JexlBuilder().arithmetic(new Arithmetic132()).namespaces(ns).create();
Object evaluate = jexl.createExpression("1/0").evaluate(null);
Assert.assertTrue(Double.isInfinite((Double) evaluate));
evaluate = jexl.createExpression("-1/0").evaluate(null);
Assert.assertTrue(Double.isInfinite((Double) evaluate));
evaluate = jexl.createExpression("1.0/0.0").evaluate(null);
Assert.assertTrue(Double.isInfinite((Double) evaluate));
evaluate = jexl.createExpression("-1.0/0.0").evaluate(null);
Assert.assertTrue(Double.isInfinite((Double) evaluate));
evaluate = jexl.createExpression("math:abs(-42)").evaluate(null);
Assert.assertEquals(42, evaluate);
}
private static Document getDocument(String xml) throws Exception {
DocumentBuilder xmlBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputStream stringInputStream = new ByteArrayInputStream(xml.getBytes("UTF-8"));
return xmlBuilder.parse(stringInputStream);
}
public static class XmlArithmetic extends JexlArithmetic {
public XmlArithmetic(boolean lenient) {
super(lenient);
}
public boolean empty(org.w3c.dom.Element elt) {
return !elt.hasAttributes() && !elt.hasChildNodes();
}
public int size(org.w3c.dom.Element elt) {
return elt.getChildNodes().getLength();
}
}
@Test
/**
* Inspired by JEXL-16{1,2}.
*/
public void testXmlArithmetic() throws Exception {
JexlEngine jexl = new JexlBuilder().arithmetic(new XmlArithmetic(false)).create();
JexlScript e0 = jexl.createScript("x.empty()", "x");
JexlScript e1 = jexl.createScript("empty(x)", "x");
JexlScript s0 = jexl.createScript("x.size()", "x");
JexlScript s1 = jexl.createScript("size(x)", "x");
Document xml;
Node x;
Boolean empty;
int size;
xml = getDocument("<node info='123'/>");
x = xml.getLastChild();
empty = (Boolean) e0.execute(null, x);
Assert.assertFalse(empty);
empty = (Boolean) e1.execute(null, x);
Assert.assertFalse(empty);
size = (Integer) s0.execute(null, x);
Assert.assertEquals(0, size);
size = (Integer) s1.execute(null, x);
Assert.assertEquals(0, size);
xml = getDocument("<node><a/><b/></node>");
x = xml.getLastChild();
empty = (Boolean) e0.execute(null, x);
Assert.assertFalse(empty);
empty = (Boolean) e1.execute(null, x);
Assert.assertFalse(empty);
size = (Integer) s0.execute(null, x);
Assert.assertEquals(2, size);
size = (Integer) s1.execute(null, x);
Assert.assertEquals(2, size);
xml = getDocument("<node/>");
x = xml.getLastChild();
empty = (Boolean) e0.execute(null, x);
Assert.assertTrue(empty);
empty = (Boolean) e1.execute(null, x);
Assert.assertTrue(empty);
size = (Integer) s0.execute(null, x);
Assert.assertEquals(0, size);
size = (Integer) s1.execute(null, x);
Assert.assertEquals(0, size);
xml = getDocument("<node info='123'/>");
NamedNodeMap nnm = xml.getLastChild().getAttributes();
Attr info = (Attr) nnm.getNamedItem("info");
Assert.assertEquals("123", info.getValue());
// JEXL-161
JexlContext jc = new MapContext();
jc.set("x", xml.getLastChild());
final String y = "456";
jc.set("y", y);
JexlScript s = jexl.createScript("x.attribute.info = y");
Object r = s.execute(jc);
nnm = xml.getLastChild().getAttributes();
info = (Attr) nnm.getNamedItem("info");
Assert.assertEquals(y, r);
Assert.assertEquals(y, info.getValue());
}
@Test
public void testEmptyLong() throws Exception {
Object x;
x = JEXL.createScript("new('java.lang.Long', 4294967296)").execute(null);
Assert.assertEquals(4294967296L, ((Long) x).longValue());
x = JEXL.createScript("new('java.lang.Long', '4294967296')").execute(null);
Assert.assertEquals(4294967296L, ((Long) x).longValue());
x = JEXL.createScript("4294967296l").execute(null);
Assert.assertEquals(4294967296L, ((Long) x).longValue());
x = JEXL.createScript("4294967296L").execute(null);
Assert.assertEquals(4294967296L, ((Long) x).longValue());
checkEmpty(x, false);
x = JEXL.createScript("0L").execute(null);
Assert.assertEquals(0, ((Long) x).longValue());
checkEmpty(x, true);
}
@Test
public void testEmptyFloat() throws Exception {
Object x;
x = JEXL.createScript("4294967296.f").execute(null);
Assert.assertEquals(4294967296.0f, (Float) x, EPSILON);
checkEmpty(x, false);
x = JEXL.createScript("4294967296.0f").execute(null);
Assert.assertEquals(4294967296.0f, (Float) x, EPSILON);
checkEmpty(x, false);
x = JEXL.createScript("0.0f").execute(null);
Assert.assertEquals(0.0f, (Float) x, EPSILON);
checkEmpty(x, true);
x = Float.NaN;
checkEmpty(x, true);
}
@Test
public void testEmptyDouble() throws Exception {
Object x;
x = JEXL.createScript("4294967296.d").execute(null);
Assert.assertEquals(4294967296.0d, (Double) x, EPSILON);
checkEmpty(x, false);
x = JEXL.createScript("4294967296.0d").execute(null);
Assert.assertEquals(4294967296.0d, (Double) x, EPSILON);
checkEmpty(x, false);
x = JEXL.createScript("0.0d").execute(null);
Assert.assertEquals(0.0d, (Double) x, EPSILON);
checkEmpty(x, true);
x = Double.NaN;
checkEmpty(x, true);
}
void checkEmpty(Object x, boolean expect) {
JexlScript s0 = JEXL.createScript("empty(x)", "x");
boolean empty = (Boolean) s0.execute(null, x);
Assert.assertEquals(expect, empty);
JexlScript s1 = JEXL.createScript("empty x", "x");
empty = (Boolean) s1.execute(null, x);
Assert.assertEquals(expect, empty);
JexlScript s2 = JEXL.createScript("x.empty()", "x");
empty = (Boolean) s2.execute(null, x);
Assert.assertEquals(expect, empty);
}
@Test
public void testCoerceInteger() throws Exception {
JexlArithmetic ja = JEXL.getArithmetic();
JexlEvalContext ctxt = new JexlEvalContext();
ctxt.setStrictArithmetic(true);
String stmt = "a = 34L; b = 45.0D; c=56.0F; d=67B; e=78H;";
JexlScript expr = JEXL.createScript(stmt);
/* Object value = */ expr.execute(ctxt);
Assert.assertEquals(34, ja.toInteger(ctxt.get("a")));
Assert.assertEquals(45, ja.toInteger(ctxt.get("b")));
Assert.assertEquals(56, ja.toInteger(ctxt.get("c")));
Assert.assertEquals(67, ja.toInteger(ctxt.get("d")));
Assert.assertEquals(78, ja.toInteger(ctxt.get("e")));
Assert.assertEquals(10, ja.toInteger("10"));
Assert.assertEquals(1, ja.toInteger(true));
Assert.assertEquals(0, ja.toInteger(false));
}
@Test
public void testCoerceLong() throws Exception {
JexlArithmetic ja = JEXL.getArithmetic();
JexlEvalContext ctxt = new JexlEvalContext();
ctxt.setStrictArithmetic(true);
String stmt = "a = 34L; b = 45.0D; c=56.0F; d=67B; e=78H;";
JexlScript expr = JEXL.createScript(stmt);
/* Object value = */ expr.execute(ctxt);
Assert.assertEquals(34L, ja.toLong(ctxt.get("a")));
Assert.assertEquals(45L, ja.toLong(ctxt.get("b")));
Assert.assertEquals(56L, ja.toLong(ctxt.get("c")));
Assert.assertEquals(67L, ja.toLong(ctxt.get("d")));
Assert.assertEquals(78L, ja.toLong(ctxt.get("e")));
Assert.assertEquals(10L, ja.toLong("10"));
Assert.assertEquals(1L, ja.toLong(true));
Assert.assertEquals(0L, ja.toLong(false));
}
@Test
public void testCoerceDouble() throws Exception {
JexlArithmetic ja = JEXL.getArithmetic();
JexlEvalContext ctxt = new JexlEvalContext();
ctxt.setStrictArithmetic(true);
String stmt = "{a = 34L; b = 45.0D; c=56.0F; d=67B; e=78H; }";
JexlScript expr = JEXL.createScript(stmt);
/* Object value = */ expr.execute(ctxt);
Assert.assertEquals(34, ja.toDouble(ctxt.get("a")), EPSILON);
Assert.assertEquals(45, ja.toDouble(ctxt.get("b")), EPSILON);
Assert.assertEquals(56, ja.toDouble(ctxt.get("c")), EPSILON);
Assert.assertEquals(67, ja.toDouble(ctxt.get("d")), EPSILON);
Assert.assertEquals(78, ja.toDouble(ctxt.get("e")), EPSILON);
Assert.assertEquals(10d, ja.toDouble("10"), EPSILON);
Assert.assertEquals(1.D, ja.toDouble(true), EPSILON);
Assert.assertEquals(0.D, ja.toDouble(false), EPSILON);
}
@Test
public void testCoerceBigInteger() throws Exception {
JexlArithmetic ja = JEXL.getArithmetic();
JexlEvalContext ctxt = new JexlEvalContext();
ctxt.setStrictArithmetic(true);
String stmt = "{a = 34L; b = 45.0D; c=56.0F; d=67B; e=78H; }";
JexlScript expr = JEXL.createScript(stmt);
/* Object value = */ expr.execute(ctxt);
Assert.assertEquals(BigInteger.valueOf(34), ja.toBigInteger(ctxt.get("a")));
Assert.assertEquals(BigInteger.valueOf(45), ja.toBigInteger(ctxt.get("b")));
Assert.assertEquals(BigInteger.valueOf(56), ja.toBigInteger(ctxt.get("c")));
Assert.assertEquals(BigInteger.valueOf(67), ja.toBigInteger(ctxt.get("d")));
Assert.assertEquals(BigInteger.valueOf(78), ja.toBigInteger(ctxt.get("e")));
Assert.assertEquals(BigInteger.valueOf(10), ja.toBigInteger("10"));
Assert.assertEquals(BigInteger.valueOf(1), ja.toBigInteger(true));
Assert.assertEquals(BigInteger.valueOf(0), ja.toBigInteger(false));
}
@Test
public void testCoerceBigDecimal() throws Exception {
JexlArithmetic ja = JEXL.getArithmetic();
JexlEvalContext ctxt = new JexlEvalContext();
ctxt.setStrictArithmetic(true);
String stmt = "{a = 34L; b = 45.0D; c=56.0F; d=67B; e=78H; }";
JexlScript expr = JEXL.createScript(stmt);
/* Object value = */ expr.execute(ctxt);
Assert.assertEquals(BigDecimal.valueOf(34), ja.toBigDecimal(ctxt.get("a")));
Assert.assertEquals(BigDecimal.valueOf(45.), ja.toBigDecimal(ctxt.get("b")));
Assert.assertEquals(BigDecimal.valueOf(56.), ja.toBigDecimal(ctxt.get("c")));
Assert.assertEquals(BigDecimal.valueOf(67), ja.toBigDecimal(ctxt.get("d")));
Assert.assertEquals(BigDecimal.valueOf(78), ja.toBigDecimal(ctxt.get("e")));
Assert.assertEquals(BigDecimal.valueOf(10), ja.toBigDecimal("10"));
Assert.assertEquals(BigDecimal.valueOf(1.), ja.toBigDecimal(true));
Assert.assertEquals(BigDecimal.valueOf(0.), ja.toBigDecimal(false));
}
@Test
public void testAtomicBoolean() throws Exception {
// in a condition
JexlScript e = JEXL.createScript("if (x) 1 else 2;", "x");
JexlContext jc = new MapContext();
AtomicBoolean ab = new AtomicBoolean(false);
Object o;
o = e.execute(jc, ab);
Assert.assertEquals("Result is not 2", new Integer(2), o);
ab.set(true);
o = e.execute(jc, ab);
Assert.assertEquals("Result is not 1", new Integer(1), o);
// in a binary logical op
e = JEXL.createScript("x && y", "x", "y");
ab.set(true);
o = e.execute(jc, ab, Boolean.FALSE);
Assert.assertFalse((Boolean) o);
ab.set(true);
o = e.execute(jc, ab, Boolean.TRUE);
Assert.assertTrue((Boolean) o);
ab.set(false);
o = e.execute(jc, ab, Boolean.FALSE);
Assert.assertFalse((Boolean) o);
ab.set(false);
o = e.execute(jc, ab, Boolean.FALSE);
Assert.assertFalse((Boolean) o);
// in arithmetic op
e = JEXL.createScript("x + y", "x", "y");
ab.set(true);
o = e.execute(jc, ab, 10);
Assert.assertEquals(11, o);
o = e.execute(jc, 10, ab);
Assert.assertEquals(11, o);
o = e.execute(jc, ab, 10.d);
Assert.assertEquals(11.d, (Double) o, EPSILON);
o = e.execute(jc, 10.d, ab);
Assert.assertEquals(11.d, (Double) o, EPSILON);
BigInteger bi10 = BigInteger.TEN;
ab.set(false);
o = e.execute(jc, ab, bi10);
Assert.assertEquals(bi10, o);
o = e.execute(jc, bi10, ab);
Assert.assertEquals(bi10, o);
BigDecimal bd10 = BigDecimal.TEN;
ab.set(false);
o = e.execute(jc, ab, bd10);
Assert.assertEquals(bd10, o);
o = e.execute(jc, bd10, ab);
Assert.assertEquals(bd10, o);
// in a (the) monadic op
e = JEXL.createScript("!x", "x");
ab.set(true);
o = e.execute(jc, ab);
Assert.assertFalse((Boolean) o);
ab.set(false);
o = e.execute(jc, ab);
Assert.assertTrue((Boolean) o);
// in a (the) monadic op
e = JEXL.createScript("-x", "x");
ab.set(true);
o = e.execute(jc, ab);
Assert.assertFalse((Boolean) o);
ab.set(false);
o = e.execute(jc, ab);
Assert.assertTrue((Boolean) o);
}
}