/**
* Copyright (C) 2010 dennis zhuang (killme2008@gmail.com)
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
**/
package com.googlecode.aviator.test.function;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.Expression;
import com.googlecode.aviator.Options;
import com.googlecode.aviator.exception.ExpressionRuntimeException;
public class FunctionTest {
@Test
public void testArithmeticExpression() {
assertEquals(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10, AviatorEvaluator.execute("1+2+3+4+5+6+7+8+9+10"));
assertEquals(0, AviatorEvaluator.execute("1+2-3"));
assertEquals(120, AviatorEvaluator.execute("1*2*3*4*5"));
assertEquals(-4, AviatorEvaluator.execute("1-2-3"));
assertEquals(2, AviatorEvaluator.execute("1-(2-3)"));
assertEquals(50, AviatorEvaluator.execute("100/2"));
assertEquals(33, AviatorEvaluator.execute("100/3"));
assertEquals(-49, AviatorEvaluator.execute("1-100/2"));
assertEquals(51, AviatorEvaluator.execute("1+100/2"));
assertEquals(6 - (4 / 2 - (4 + 5)) * 2 + 100 / (2 + 1) * 20 - 5 * 5 * 5 + (6 + 1) / (2 - 3 / (1 + 1)),
AviatorEvaluator.execute("6-(4/2-(4+5))*2+100/(2+1)*20-5*5*5+(6+1)/(2-3/(1+1))"));
assertEquals(62.8, AviatorEvaluator.execute("2*3.14*10"));
assertEquals(96.3, AviatorEvaluator.execute("100.3-4"));
assertEquals(-96.3, AviatorEvaluator.execute("4-100.3"));
assertEquals(100.3 / 4 - (4.0 / 2 + 5), AviatorEvaluator.execute("100.3/4-(4.0/2+5)"));
assertEquals(1, AviatorEvaluator.execute("100%3"));
assertEquals(0, AviatorEvaluator.execute("1-100%3"));
assertEquals(100 % 3 * 4.2 + (37 + 95) / (6 * 3 - 18.0),
(Double) AviatorEvaluator.execute("100%3*4.2+(37+95)/(6*3-18.0)"), 0.0001);
}
@Test
public void testArithmeticExpressionWithVariable() {
Map<String, Object> env = new HashMap<String, Object>();
int i = 100;
float pi = 3.14f;
double d = -3.9;
byte b = (byte) 4;
env.put("i", i);
env.put("pi", pi);
env.put("d", d);
env.put("b", b);
System.out.println(AviatorEvaluator.execute("i+pi", env).getClass());
System.setProperty("aviator.asm.trace", "true");
assertEquals(-100, AviatorEvaluator.execute("-i", env));
assertEquals(-103.4, AviatorEvaluator.execute("-i-pi", env));
assertEquals(2 * 3.14 * 10, (Double) AviatorEvaluator.execute("2*pi*10", env), 0.001);
assertEquals(3.14 * d * d, (Double) AviatorEvaluator.execute("pi*d*d", env), 0.001);
assertEquals((i + pi + d + b) / 4, AviatorEvaluator.execute("(i+pi+d+b)/4", env));
assertEquals(200, AviatorEvaluator.execute("i+100", env));
assertEquals(0, AviatorEvaluator.execute("i%4", env));
assertEquals(i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99,
AviatorEvaluator.execute("i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99", env));
}
@Test
public void testOperatorPrecedence() {
assertEquals(false,
AviatorEvaluator.execute("6.7-100>39.6 ? 5==5? 4+5:6-1 : !false ? 5-6>0&& false: 100%3<=5 || 67*40>=100"));
}
@Test
public void testLogicExpression() {
assertTrue((Boolean) AviatorEvaluator.execute("3+1==4"));
assertTrue((Boolean) AviatorEvaluator.execute("3+1>=4"));
assertTrue((Boolean) AviatorEvaluator.execute("3+1<=4"));
assertFalse((Boolean) AviatorEvaluator.execute("3+1>4"));
assertFalse((Boolean) AviatorEvaluator.execute("3+1<4"));
assertTrue((Boolean) AviatorEvaluator.execute("100/2-50==0"));
assertTrue((Boolean) AviatorEvaluator.execute("3-(1+2)==0"));
assertTrue((Boolean) AviatorEvaluator.execute("3-4/2==1"));
assertTrue((Boolean) AviatorEvaluator.execute("3<1 || -3-100<0 && !(100%3>100)"));
assertTrue((Boolean) AviatorEvaluator.execute("3>1 || -3-100<0 && !(100%3<100)"));
assertFalse((Boolean) AviatorEvaluator.execute("(3>1 || -3-100<0 )&& !(100%3<100)"));
assertFalse((Boolean) AviatorEvaluator.execute("3<1 || -3-100<0 && !(100%3<100)"));
}
@Test
public void testLogicExpressionWithVariable() {
Map<String, Object> env = new HashMap<String, Object>();
int i = 100;
float pi = 3.14f;
double d = -3.9;
byte b = (byte) 4;
env.put("i", i);
env.put("pi", pi);
env.put("d", d);
env.put("b", b);
env.put("bool", false);
assertEquals(false, AviatorEvaluator.execute("-i>=0", env));
assertEquals(true, AviatorEvaluator.execute("-i-pi<=-100", env));
assertEquals(true, AviatorEvaluator.execute("2*pi*10==2 * pi * 10", env));
assertEquals(true, AviatorEvaluator.execute("pi*d*d == pi* d *d", env));
assertEquals((i + pi + d + b) / 4 % 2 > 0, AviatorEvaluator.execute("(i+pi+d+b)/4%2>0", env));
assertEquals(true, AviatorEvaluator.execute("(i+100)%3!=1", env));
assertEquals(true, AviatorEvaluator.execute("i%4<=0", env));
assertEquals(
true,
AviatorEvaluator
.execute(
"i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99 ==i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99",
env));
}
@Test
public void testSystemFunction() {
AviatorEvaluator.setTrace(true);
try {
// sysdate()
Object date = AviatorEvaluator.execute("sysdate()");
assertNotNull(date);
assertTrue(date instanceof Date);
assertEquals(((Date) date).getMinutes(), new Date().getMinutes());
// now()
Object now = AviatorEvaluator.execute("now()");
assertNotNull(now);
assertTrue(now instanceof Long);
assertEquals((Long) now, System.currentTimeMillis(), 5L);
// rand()
Object rand1 = AviatorEvaluator.execute("rand()");
assertNotNull(rand1);
assertTrue(rand1 instanceof Double);
Object rand2 = AviatorEvaluator.execute("rand(100)");
assertTrue(rand2 instanceof Long);
assertTrue((Long) rand2 < 100);
Object rand3 = AviatorEvaluator.execute("rand()");
assertFalse(rand3.equals(rand1));
}
finally {
AviatorEvaluator.setTrace(false);
}
}
@Test
public void testSeqFunction() {
Map<String, Object> env = new HashMap<String, Object>();
Integer[] a = new Integer[10];
for (int i = 0; i < a.length; i++) {
a[i] = 9 - i;
}
List<String> list = new ArrayList<String>();
list.add("hello");
list.add("world");
env.put("a", a);
env.put("list", list);
final HashSet<Boolean> set = new HashSet<Boolean>();
set.add(true);
set.add(false);
env.put("set", set);
assertEquals(10, AviatorEvaluator.execute("count(a)", env));
assertEquals(2, AviatorEvaluator.execute("count(list)", env));
assertEquals(2, AviatorEvaluator.execute("count(set)", env));
assertTrue((Boolean) AviatorEvaluator.execute("include(set,true)", env));
assertTrue((Boolean) AviatorEvaluator.execute("include(set,false)", env));
assertFalse((Boolean) AviatorEvaluator.execute("include(set,'hello')", env));
assertFalse((Boolean) AviatorEvaluator.execute("include(set,10)", env));
for (int i = 0; i < a.length; i++) {
assertTrue((Boolean) AviatorEvaluator.execute("include(a,9-" + i + ")", env));
}
assertEquals(45, AviatorEvaluator.execute("reduce(a,+,0)", env));
assertEquals(0, AviatorEvaluator.execute("reduce(a,*,1)", env));
try {
assertEquals(0, AviatorEvaluator.execute("reduce(a,/,0)", env));
fail();
}
catch (ExpressionRuntimeException e) {
// ignore
}
assertEquals(-45, AviatorEvaluator.execute("reduce(a,-,0)", env));
assertEquals(5, AviatorEvaluator.execute("count(filter(a,seq.gt(4)))", env));
assertEquals(4, AviatorEvaluator.execute("count(filter(a,seq.lt(4)))", env));
assertEquals(5, AviatorEvaluator.execute("count(filter(a,seq.le(4)))", env));
assertEquals(1, AviatorEvaluator.execute("count(filter(a,seq.eq(4)))", env));
assertEquals(0, AviatorEvaluator.execute("count(filter(a,seq.gt(9)))", env));
assertEquals(0, AviatorEvaluator.execute("count(filter(a,seq.nil()))", env));
assertEquals(10, AviatorEvaluator.execute("count(filter(a,seq.exists()))", env));
//seq.and and seq.or
assertEquals(3, AviatorEvaluator.execute("count(filter(a, seq.and(seq.lt(8), seq.gt(4))))", env));
assertEquals(4, AviatorEvaluator.execute("count(filter(a, seq.and(seq.lt(8), seq.ge(4))))", env));
assertEquals(5, AviatorEvaluator.execute("count(filter(a, seq.and(seq.le(8), seq.ge(4))))", env));
assertEquals(5, AviatorEvaluator.execute("count(filter(a, seq.or(seq.gt(8), seq.lt(4))))", env));
assertEquals(6, AviatorEvaluator.execute("count(filter(a, seq.or(seq.gt(8), seq.le(4))))", env));
assertEquals(7, AviatorEvaluator.execute("count(filter(a, seq.or(seq.ge(8), seq.le(4))))", env));
assertEquals(1, AviatorEvaluator.execute("count(filter(set,seq.true()))", env));
assertTrue((Boolean) AviatorEvaluator.execute("include(filter(set,seq.true()),true)", env));
assertFalse((Boolean) AviatorEvaluator.execute("include(filter(set,seq.true()),false)", env));
assertEquals(1, AviatorEvaluator.execute("count(filter(set,seq.eq(true)))", env));
assertEquals(1, AviatorEvaluator.execute("count(filter(set,seq.false()))", env));
assertFalse((Boolean) AviatorEvaluator.execute("include(filter(set,seq.false()),true)", env));
assertTrue((Boolean) AviatorEvaluator.execute("include(filter(set,seq.false()),false)", env));
assertEquals(0, AviatorEvaluator.execute("count(filter(set,seq.nil()))", env));
assertEquals(2, AviatorEvaluator.execute("count(filter(set,seq.exists()))", env));
assertEquals(list, AviatorEvaluator.execute("sort(list)", env));
assertNotSame(list, AviatorEvaluator.execute("sort(list)", env));
try {
AviatorEvaluator.execute("sort(set)", env);
fail();
}
catch (ExpressionRuntimeException e) {
// ignore
}
assertEquals(9, a[0]);
assertFalse(Arrays.equals(a, (Object[]) AviatorEvaluator.execute("sort(a)", env)));
assertEquals(9, a[0]);
Arrays.sort(a);
assertEquals(0, a[0]);
assertTrue(Arrays.equals(a, (Object[]) AviatorEvaluator.execute("sort(a)", env)));
assertEquals(2, AviatorEvaluator.execute("count(map(list,string.length))", env));
assertTrue((Boolean) AviatorEvaluator.execute("include(map(list,string.length),5)", env));
}
@Test
public void testIssue2() {
assertEquals(100000000000000000000.0 / 3.0, AviatorEvaluator.execute("100000000000000000000.0/3.0"));
System.out.println(AviatorEvaluator.execute("100000000000000000000.0/3.0"));
// assertEquals(100000000000000000000/3,
// AviatorEvaluator.execute("100000000000000000000/3"));
}
@Test
public void testStringFunction() {
String s1 = "hello world";
String s2 = "just for fun";
String s3 = "aviator";
Map<String, Object> env = new HashMap<String, Object>();
env.put("s1", s1);
env.put("s2", s2);
env.put("s3", s3);
assertEquals("hello world aviator", AviatorEvaluator.execute("'hello'+' '+'world'+' '+'aviator'"));
assertEquals(4, AviatorEvaluator.execute("string.length(\"fuck\")"));
assertEquals(0, AviatorEvaluator.execute("string.length('')"));
assertEquals(19, AviatorEvaluator.execute("string.length('hello'+' '+'world'+' '+'aviator')"));
assertTrue((Boolean) AviatorEvaluator.execute("string.contains('hello','he')"));
assertFalse((Boolean) AviatorEvaluator.execute("string.contains('hello','c')"));
assertTrue((Boolean) AviatorEvaluator.execute("string.startsWith('hello','he')"));
assertFalse((Boolean) AviatorEvaluator.execute("string.startsWith('hello','llo')"));
assertFalse((Boolean) AviatorEvaluator.execute("string.endsWith('hello','he')"));
assertTrue((Boolean) AviatorEvaluator.execute("string.endsWith('hello','llo')"));
assertEquals("ello", AviatorEvaluator.execute("string.substring('hello',1)"));
assertEquals("el", AviatorEvaluator.execute("string.substring('hello',1,3)"));
// test with variable
assertEquals("hello world aviator", AviatorEvaluator.execute("s1+' '+s3", env));
assertEquals(19, AviatorEvaluator.execute("string.length(s1+' '+s3)", env));
assertFalse((Boolean) AviatorEvaluator.execute("string.startsWith(s1,'fuck')", env));
assertTrue((Boolean) AviatorEvaluator.execute("string.startsWith(s1,s1)", env));
assertTrue((Boolean) AviatorEvaluator.execute("string.endsWith(s1+s2,s2)", env));
assertTrue((Boolean) AviatorEvaluator.execute("string.contains(s1+s2,s1)", env));
assertTrue((Boolean) AviatorEvaluator.execute("string.contains(s1+s2,'world')", env));
assertFalse((Boolean) AviatorEvaluator.execute("string.contains(s1+s3,s2)", env));
assertTrue((Boolean) AviatorEvaluator.execute("string.contains(s1+s2+s3,s2)", env));
assertEquals("ello world", AviatorEvaluator.execute("string.substring(s1,1)", env));
assertEquals("el", AviatorEvaluator.execute("string.substring(s1,1,3)", env));
assertEquals("hello", ((String[]) AviatorEvaluator.exec("string.split('hello world',' ')"))[0]);
assertEquals("world", ((String[]) AviatorEvaluator.exec("string.split('hello world',' ')"))[1]);
}
@Test
public void testBitOperations() {
assertEquals(99 | 7, AviatorEvaluator.execute("99|7"));
assertEquals(99 | ~7, AviatorEvaluator.execute("99|~7"));
assertEquals(99 & 7, AviatorEvaluator.execute("99&7"));
assertEquals(99 ^ 7, AviatorEvaluator.execute("99^7"));
assertEquals(99 << 7, AviatorEvaluator.execute("99<<7"));
assertEquals(99 >> 7, AviatorEvaluator.execute("99>>7"));
assertEquals(99 >>> 7, AviatorEvaluator.execute("99>>>7"));
assertEquals(1 ^ 2 ^ 3 & 4 | 5 ^ ~2 | 5 & 4, AviatorEvaluator.execute("1^2^3&4|5^~2|5&4"));
assertEquals((1 ^ 2 ^ 3 & 4 | 5 ^ ~2 | 5 & 4) == 100, AviatorEvaluator.execute("(1^2^3&4|5^~2|5&4) == 100"));
assertEquals(
4 / 2 * 3 - 4 + (5 ^ 5 - 2 & 3) == 4000 ? !false && true ? 1 & 4 : 0 : 6L >> 2L * 2L / 4L
^ ~699L + 100L << 4L >> 5L >> 1000L,
AviatorEvaluator
.execute("4 / 2 * 3 - 4 + (5 ^ 5 - 2 & 3) == 4000 ? (!false && true ? 1 & 4 : 0) : 6 >> 2 * 2 / 4^ ~699 + 100 << 4 >> 5 >> 1000"));
assertEquals((99 & 7) == (99 & 7) && false, AviatorEvaluator.execute("(99&7)==(99&7)&&false "));
assertEquals((99 | 7) != (99 | 7) || false, AviatorEvaluator.execute("(99|7)!=(99|7)||false "));
}
@Test
public void testBitOperationsWithVariable() {
Map<String, Object> env = new HashMap<String, Object>();
long i = 100;
long j = -99;
long k = 7;
env.put("i", i);
env.put("j", j);
env.put("k", k);
assertEquals(i | j, AviatorEvaluator.execute("i|j", env));
assertEquals(99 | k, AviatorEvaluator.execute("99|k", env));
assertEquals(i & j, AviatorEvaluator.execute("i&j", env));
assertEquals(99 & k, AviatorEvaluator.execute("99&k", env));
assertEquals(i ^ j, AviatorEvaluator.execute("i^j", env));
assertEquals(99 ^ k, AviatorEvaluator.execute("99^k", env));
assertEquals(i | ~j, AviatorEvaluator.execute("i|~j", env));
assertEquals(99 | ~k, AviatorEvaluator.execute("99|~k", env));
assertEquals(j >>> i, AviatorEvaluator.execute("j>>>i", env));
assertEquals(i ^ j ^ k & i & j & k | i | j | k & 3 & 4 | 5 & ~i,
AviatorEvaluator.execute("i^j^k&i&j&k|i|j|k&3&4|5&~i", env));
assertEquals(
4 / 2 * 3 - 4 + (5 ^ 5 - 2 & 3) == 4000 ? !false && true ? 1 & 4 : 0 : i >> j * k / i
^ ~j + k << i >> j >> 1000L,
AviatorEvaluator
.execute(
"4 / 2 * 3 - 4 + (5 ^ 5 - 2 & 3) == 4000 ? (!false && true ? 1 & 4 : 0) :i >> j * k / i ^ ~j + k << i >> j >> 1000",
env));
assertEquals((i & 7) == (i & 7) && false, AviatorEvaluator.execute("(i & 7) == (i & 7) && false ", env));
assertEquals((j | k) != (j | k) || false, AviatorEvaluator.execute("(j | k) != (j | k) || false ", env));
}
@Test
public void testHexNumber() {
Map<String, Object> env = new HashMap<String, Object>();
long i = 100;
float j = -99;
int k = 7;
env.put("i", i);
env.put("j", j);
env.put("k", k);
assertEquals(0xA3, AviatorEvaluator.execute("0xA3", env));
assertEquals(0xA3 * 0x45 + 2, AviatorEvaluator.execute("0xA3 * 0x45+2", env));
assertEquals(0xFF == 0Xff, AviatorEvaluator.execute("0xFF==0Xff", env));
assertEquals(~0xFF == 0Xff, AviatorEvaluator.execute("~0xFF==0Xff", env));
assertEquals(~0xFF | k & 3 - 0X11, AviatorEvaluator.execute("~0xFF|k&3-0X11", env));
assertEquals(0x45 > i ? 0x11 - 0344 * 5 / 7 : k / 0xFF - j * 0x45,
AviatorEvaluator.execute("0x45>i?0x11-0344*5/7:k/0xFF-j*0x45 ", env));
}
@Test
public void testBitOp_BitMap() {
Map<String, Object> env = new HashMap<String, Object>();
int flag = 0;
env.put("flag", flag);
assertEquals(false, AviatorEvaluator.execute("(flag & 0x3E0) >> 5 ==15 ", env));
flag = flag & 0xFFFFC1F | 15 << 5;
env.put("flag", flag);
assertEquals(true, AviatorEvaluator.execute("(flag & 0x3E0) >> 5 ==15 ", env));
assertEquals(false, AviatorEvaluator.execute(" (flag & 0x400) >> 10 ==1 ", env));
flag = flag & 0xFFFFFBFF | 1 << 10;
env.put("flag", flag);
assertEquals(true, AviatorEvaluator.execute("(flag & 0x400) >> 10 ==1 ", env));
assertEquals(true, AviatorEvaluator.execute("(flag & 0x400) >> 10 ==1 && (flag & 0x3E0) >> 5 ==15", env));
assertEquals(false, AviatorEvaluator.execute("(flag & 0x400) >> 10 ==0 && (flag & 0x3E0) >> 5 ==15", env));
assertEquals(0L, AviatorEvaluator.execute(" ((flag & 0x1800) >> 11)", env));
flag = flag & 0xFFFFE7FF | 1 << 11;
env.put("flag", flag);
assertEquals(1L, AviatorEvaluator.execute(" ((flag & 0x1800) >> 11)", env));
flag = flag & 0xFFFFE7FF | 2 << 11;
env.put("flag", flag);
assertEquals(2L, AviatorEvaluator.execute(" ((flag & 0x1800) >> 11)", env));
assertEquals(flag & 0xFFFFE7FF | 3 << 11, AviatorEvaluator.execute(" flag & 0xFFFFE7FF | 3 << 11", env));
flag = flag & 0xFFFFE7FF | 3 << 11;
env.put("flag", flag);
assertEquals(3L, AviatorEvaluator.execute(" ((flag & 0x1800) >> 11)", env));
}
@Test
public void testMathFunction() {
assertEquals(Math.pow(10, 100.0), AviatorEvaluator.exec("math.pow(10,100)"));
assertEquals(Math.log(99), AviatorEvaluator.exec("math.log(99)"));
assertEquals(Math.log10(99), AviatorEvaluator.exec("math.log10(99)"));
assertEquals(Math.sin(99), AviatorEvaluator.exec("math.sin(99)"));
assertEquals(Math.cos(99), AviatorEvaluator.exec("math.cos(99)"));
assertEquals(Math.tan(99), AviatorEvaluator.exec("math.tan(99)"));
assertEquals(Math.sqrt(99), AviatorEvaluator.exec("math.sqrt(99)"));
assertEquals(Math.round(99.9), AviatorEvaluator.exec("math.round(99.9)"));
assertEquals(Math.round(99.1), AviatorEvaluator.exec("math.round(99.1)"));
}
@Test
public void testParseScientificNotations() {
assertEquals(1e5, AviatorEvaluator.exec("1e5"));
assertEquals(1E5, AviatorEvaluator.exec("1E5"));
assertEquals(1E-5, AviatorEvaluator.exec("1E-5"));
assertEquals(2e3 + 4e6, AviatorEvaluator.exec("2e3+4e6"));
assertEquals(2e3 - 4e6, AviatorEvaluator.exec("2e3-4e6"));
assertEquals(2e3 / 4e6, AviatorEvaluator.exec("2e3/4e6"));
assertEquals(2e3 % 4e6, AviatorEvaluator.exec("2e3%4e6"));
}
@Test
public void testParseBigNumbers() {
assertEquals(new BigInteger("99999999999999999999999999999999"),
AviatorEvaluator.exec("99999999999999999999999999999999"));
assertEquals(new BigInteger("99999999999999999999999999999999"),
AviatorEvaluator.exec("99999999999999999999999999999999N"));
assertEquals(new BigInteger("199999999999999999999999999999998"),
AviatorEvaluator.exec("99999999999999999999999999999999+99999999999999999999999999999999"));
assertEquals(new BigDecimal("99999999999999999999999999999999.99999999", AviatorEvaluator.getMathContext()),
AviatorEvaluator.exec("99999999999999999999999999999999.99999999M"));
}
@Test
public void testGetVariableNames() {
Expression expression = AviatorEvaluator.compile("b+a", true);
assertNotNull(expression);
List<String> vars = expression.getVariableNames();
assertNotNull(vars);
assertEquals(2, vars.size());
assertTrue(vars.contains("a"));
assertTrue(vars.contains("b"));
assertEquals("b", vars.get(0));
assertEquals("a", vars.get(1));
expression = AviatorEvaluator.compile("b==a || d>3 || e+c*d/2 <= 1000", true);
assertNotNull(expression);
vars = expression.getVariableNames();
assertNotNull(vars);
assertEquals(5, vars.size());
assertTrue(vars.contains("a"));
assertTrue(vars.contains("b"));
assertTrue(vars.contains("c"));
assertTrue(vars.contains("d"));
assertTrue(vars.contains("e"));
assertEquals("b", vars.get(0));
assertEquals("a", vars.get(1));
assertEquals("d", vars.get(2));
assertEquals("e", vars.get(3));
assertEquals("c", vars.get(4));
// Test map or list as variable
expression = AviatorEvaluator.compile("map.a>10 && list[0][1]<3 && bean.c == bean.x || bean.d == y", true);
assertNotNull(expression);
vars = expression.getVariableNames();
assertEquals(4, vars.size());
assertTrue(vars.contains("map"));
assertTrue(vars.contains("list"));
assertTrue(vars.contains("bean"));
assertTrue(vars.contains("y"));
assertEquals("map", vars.get(0));
assertEquals("list", vars.get(1));
assertEquals("bean", vars.get(2));
assertEquals("y", vars.get(3));
}
@Test
public void testArrayAccess() {
// AviatorEvaluator.setTrace(true);
Map<String, Object> env = new HashMap<String, Object>();
int[] a = new int[] { 1, 2, 3, 4 };
int[][] b = new int[][] { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
int[][][] c = new int[][][] { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } };
env.put("a", a);
env.put("b", b);
env.put("c", c);
assertEquals(a[0] + b[0][0] + c[0][0][0], AviatorEvaluator.execute("a[0]+b[0][0]+c[0][0][0]", env));
assertEquals(a[1] + b[0][2] * c[1][1][1], AviatorEvaluator.execute("a[1]+b[0][2]*c[1][1][1]", env));
assertEquals(a[1] + b[0][2] * c[1][1][1] / (a[2] * a[1] + 100 - c[0][1][1] * b[0][1]),
AviatorEvaluator.execute("a[1]+b[0][2]*c[1][1][1]/(a[2]*a[1]+100-c[0][1][1]*b[0][1])", env));
assertEquals(c[0][1][1] > b[1][0], AviatorEvaluator.execute("c[0][1][1]>b[1][0]", env));
assertEquals(c[0][1][1] <= b[1][0], AviatorEvaluator.execute("c[0][1] [1] <= b[1][0]", env));
assertEquals(c[0][1][1] > b[1][0] ? a[0] : a[2], AviatorEvaluator.execute("c[0][1][1]>b[1][0]? a[0]:a[2]", env));
assertEquals(b[0].length, AviatorEvaluator.execute("count(b[0])", env));
assertEquals(6, AviatorEvaluator.execute("reduce(b[0],+,0)", env));
Object[] rt = (Object[]) AviatorEvaluator.execute("filter(c[0][0],seq.gt(1))", env);
assertEquals(1, rt.length);
assertEquals(2, rt[0]);
AviatorEvaluator.execute("map(c[1][0],println)", env);
assertTrue((Boolean) AviatorEvaluator.execute("include(b[0],3)", env));
}
@Test
public void testBigNumber() {
// big int + long
assertEquals(new BigInteger("4"), AviatorEvaluator.exec("a+b", 1, new BigInteger("3")));
assertEquals(new BigInteger("4"), AviatorEvaluator.exec("a+3N", 1));
assertEquals(new BigInteger("4"), AviatorEvaluator.exec("1+b", new BigInteger("3")));
assertEquals(new BigInteger("4"), AviatorEvaluator.exec("3N+1"));
assertEquals(new BigInteger("300"), AviatorEvaluator.exec("3N*100"));
assertEquals(new BigInteger("100"), AviatorEvaluator.exec("400/4N"));
assertEquals(new BigInteger("-3"), AviatorEvaluator.exec("a-4N", 1));
// big int + double
assertEquals(4.1, AviatorEvaluator.exec("a+b", 1.1, new BigInteger("3")));
assertEquals(4.1, AviatorEvaluator.exec("a+3N", 1.1));
assertEquals(4.1, AviatorEvaluator.exec("1.1+b", new BigInteger("3")));
assertEquals(4.1, AviatorEvaluator.exec("3N+1.1"));
assertEquals(300.0, AviatorEvaluator.exec("3N*100.0"));
assertEquals(100.0, AviatorEvaluator.exec("400.0/4N"));
assertEquals(-2.9, AviatorEvaluator.exec("a-4N", 1.1));
// big int + big int
assertEquals(new BigInteger("4"), AviatorEvaluator.exec("a+b", new BigInteger("1"), new BigInteger("3")));
assertEquals(new BigInteger("4"), AviatorEvaluator.exec("a+3N", new BigInteger("1")));
assertEquals(new BigInteger("4"), AviatorEvaluator.exec("1+b", new BigInteger("3")));
assertEquals(new BigInteger("4"), AviatorEvaluator.exec("3N+1N"));
assertEquals(new BigInteger("300"), AviatorEvaluator.exec("3N*100N"));
assertEquals(new BigInteger("100"), AviatorEvaluator.exec("400N/4N"));
assertEquals(new BigInteger("-3"), AviatorEvaluator.exec("a-4N", new BigInteger("1")));
// big int + decimal
assertEquals(new BigDecimal("4.1"), AviatorEvaluator.exec("a+b", new BigDecimal("1.1"), new BigInteger("3")));
assertEquals(new BigDecimal("4.1"), AviatorEvaluator.exec("a+3N", new BigDecimal("1")));
assertEquals(new BigDecimal("4.1"), AviatorEvaluator.exec("1.1M+b", new BigInteger("3")));
assertEquals(new BigDecimal("4.1"), AviatorEvaluator.exec("3N+1.1M"));
assertEquals(new BigDecimal("301"), AviatorEvaluator.exec("3.01M*100N"));
assertEquals(new BigDecimal("100"), AviatorEvaluator.exec("400M/4N"));
assertEquals(new BigDecimal("-2.9"), AviatorEvaluator.exec("a-4N", new BigDecimal("1.1")));
// decimal + long
assertEquals(new BigDecimal("4.1"), AviatorEvaluator.exec("a+b", new BigDecimal("1.1"), 3));
assertEquals(new BigDecimal("4.1"), AviatorEvaluator.exec("a+3", new BigDecimal("1")));
assertEquals(new BigDecimal("4.1"), AviatorEvaluator.exec("1.1M+b", 3));
assertEquals(new BigDecimal("4.1"), AviatorEvaluator.exec("3+1.1M"));
assertEquals(new BigDecimal("301"), AviatorEvaluator.exec("3.01M*100"));
assertEquals(new BigDecimal("100"), AviatorEvaluator.exec("400M/4"));
assertEquals(new BigDecimal("-2.9"), AviatorEvaluator.exec("a-4", new BigDecimal("1.1")));
// decimal + double
assertEquals(4.1, AviatorEvaluator.exec("a+b", 1.1, new BigDecimal("3")));
assertEquals(4.1, AviatorEvaluator.exec("a+3.0M", 1.1));
assertEquals(4.1, AviatorEvaluator.exec("1.1+b", new BigDecimal("3")));
assertEquals(4.1, AviatorEvaluator.exec("3.00M+1.1"));
assertEquals(300.0, AviatorEvaluator.exec("3M*100.0"));
assertEquals(100.0, AviatorEvaluator.exec("400.0/4M"));
assertEquals(-2.9, AviatorEvaluator.exec("a-4.00M", 1.1));
}
@Test
public void testBigNumberNegative() {
assertEquals(new BigInteger("-1000000000000000000000000000000000"),
AviatorEvaluator.exec("-a", new BigInteger("1000000000000000000000000000000000")));
assertEquals(new BigDecimal("9999999999999999999999999999999999999.99999999999"),
AviatorEvaluator.exec("-a", new BigDecimal("-9999999999999999999999999999999999999.99999999999")));
assertEquals(new BigDecimal("9999999999999999999.999999999999"),
AviatorEvaluator.exec("-(-9999999999999999999.999999999999M)"));
assertEquals(new BigInteger("9999999999999999999"), AviatorEvaluator.exec("-(-9999999999999999999N)"));
}
@Test
public void testBigNumberBitOperations() {
assertEquals(
new BigInteger("1000000000000000000000000000000000").xor(new BigInteger("9999999999999999999999")),
AviatorEvaluator.exec("a^b", new BigInteger("1000000000000000000000000000000000"), new BigInteger(
"9999999999999999999999")));
assertEquals(
new BigInteger("1000000000000000000000000000000000").and(new BigInteger("9999999999999999999999")),
AviatorEvaluator.exec("a&b", new BigInteger("1000000000000000000000000000000000"), new BigInteger(
"9999999999999999999999")));
assertEquals(new BigInteger("1000000000000000000000000000000000").or(new BigInteger("9999999999999999999999")),
AviatorEvaluator.exec("a|b", new BigInteger("1000000000000000000000000000000000"), new BigInteger(
"9999999999999999999999")));
assertEquals(new BigInteger("1000000000000000000000000000000000").shiftLeft(2),
AviatorEvaluator.exec("a<<2", new BigInteger("1000000000000000000000000000000000")));
assertEquals(new BigInteger("1000000000000000000000000000000000").shiftRight(2),
AviatorEvaluator.exec("a>>2", new BigInteger("1000000000000000000000000000000000")));
assertEquals(new BigInteger("1000000000000000000000000000000000").shiftRight(2),
AviatorEvaluator.exec("a>>>2", new BigInteger("1000000000000000000000000000000000")));
}
@Test(expected = ExpressionRuntimeException.class)
public void testDecimalBitAnd() {
AviatorEvaluator.exec("3M< & 2M");
}
@Test
public void testAlwaysUseDoubleAsDecimal() {
AviatorEvaluator.setOption(Options.ALWAYS_USE_DOUBLE_AS_DECIMAL, true);
try {
Object val = AviatorEvaluator.execute("3.2");
assertTrue(val instanceof BigDecimal);
assertEquals(new BigDecimal("3.2"), val);
val = AviatorEvaluator.execute("3.2 + 4.3");
assertTrue(val instanceof BigDecimal);
assertEquals(new BigDecimal("7.5"), val);
Map<String, Object> env = new HashMap<String, Object>();
env.put("a", new BigDecimal("2.1"));
env.put("b", 4);
val = AviatorEvaluator.execute("3.2 + a * b ", env);
assertTrue(val instanceof BigDecimal);
assertEquals(new BigDecimal("11.6"), val);
}
finally {
AviatorEvaluator.setOption(Options.ALWAYS_USE_DOUBLE_AS_DECIMAL, false);
}
}
@Test
public void testOtherFunction() {
// AviatorEvaluator.setOptimize(AviatorEvaluator.EVAL);
// System.setProperty("aviator.asm.trace","true");
assertTrue((Boolean) AviatorEvaluator.execute("'A' == 'A' || 'B' == 'B' && 'ABCD' == t && 'A' == 'A'"));
}
}