package org.nutz.el;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import org.junit.Before;
import org.junit.Test;
import org.nutz.conf.NutConf;
import org.nutz.el.issue.Issue293;
import org.nutz.el.issue.Issue303;
import org.nutz.el.issue.Issue314;
import org.nutz.el.speed.SimpleSpeedTest;
import org.nutz.lang.Lang;
import org.nutz.lang.Maths;
import org.nutz.lang.Mirror;
import org.nutz.lang.Strings;
import org.nutz.lang.util.Context;
public class El2Test {
El el;
@Before
public void setUp() {
el = new El();
}
@Test
public void notCalculateOneNumber() {
assertEquals(1, El.eval("1"));
assertEquals(0.1, El.eval(".1"));
assertEquals(0.1d, El.eval("0.1"));
assertEquals(0.1f, El.eval("0.1f"));
assertEquals(0.1d, El.eval("0.1d"));
assertEquals(true, El.eval("true"));
assertEquals(false, El.eval("false"));
assertEquals("jk", El.eval("'jk'"));
}
@Test
public void simpleCalculate() {
// 加
assertEquals(2, El.eval("1+1"));
assertEquals(2.2, El.eval("1.1+1.1"));
// 减
assertEquals(1, El.eval("2-1"));
// 乘
assertEquals(9, El.eval("3*3"));
assertEquals(0, El.eval("3*0"));
// 除
assertEquals(3, El.eval("9/3"));
assertEquals(2.2, El.eval("4.4/2"));
assertEquals(9.9 / 3, El.eval("9.9/3"));
// 取余
assertEquals(1, El.eval("5%2"));
assertEquals(1.0 % 0.1, El.eval("1.0%0.1"));
}
/**
* 位运算
*/
@Test
public void bit() {
assertEquals(-40, El.eval("-5<<3"));
assertEquals(-1, El.eval("-5>>3"));
assertEquals(5, El.eval("5>>>32"));
assertEquals(-5, El.eval("-5>>>32"));
assertEquals(1, El.eval("5&3"));
assertEquals(7, El.eval("5|3"));
assertEquals(-6, El.eval("~5"));
assertEquals(6, El.eval("5^3"));
}
/**
* 多级运算
*/
@Test
public void multiStageOperation() {
assertEquals(3, El.eval("1 + 1 + 1"));
assertEquals(1, El.eval("1+1-1"));
assertEquals(-1, El.eval("1-1-1"));
assertEquals(1, El.eval("1-(1-1)"));
assertEquals(7, El.eval("1+2*3"));
assertEquals(2 * 4 + 2 * 3 + 4 * 5, El.eval("2*4+2*3+4*5"));
assertEquals(9 + 8 * 7 + (6 + 5) * ((4 - 1 * 2 + 3)), El.eval("9+8*7+(6+5)*((4-1*2+3))"));
assertEquals(.3 + .2 * .5, El.eval(".3+.2*.5"));
assertEquals((.5 + 0.1) * .9, El.eval("(.5 + 0.1)*.9"));
}
/**
* 空格
*/
@Test
public void sikpSpace() {
// 空格检测
assertEquals(3, El.eval(" 1 + 2 "));
}
@Test
public void testNull() {
assertEquals(null, El.eval("null"));
assertTrue((Boolean) El.eval("null == null"));
}
/**
* 逻辑运算
*/
@Test
public void logical() {
assertEquals(true, El.eval("2 > 1"));
assertEquals(false, El.eval("2 < 1"));
assertEquals(true, El.eval("2 >= 2"));
assertEquals(true, El.eval("2 <= 2"));
assertEquals(true, El.eval("2 == 2 "));
assertEquals(true, El.eval("1 != 2"));
assertEquals(true, El.eval("!(1 == 2)"));
assertEquals(true, El.eval("!false"));
assertEquals(true, El.eval("true || false"));
assertEquals(false, El.eval("true && false"));
assertEquals(false, El.eval("false || true && false"));
}
/**
* 三元运算 ?:
*/
@Test
public void threeTernary() {
assertEquals(2, El.eval("1>0?2:3"));
assertEquals(2, El.eval("1>0&&1<2?2:3"));
}
/**
* 字符串测试
*/
@Test
public void stringTest() {
assertEquals("jk", El.eval("'jk'"));
assertEquals(2, El.eval("'jk'.length()"));
assertEquals(2, El.eval("\"jk\".length()"));
assertEquals("jk", El.eval("\" jk \".trim()"));
assertEquals("j\\n\\tk", El.eval("\"j\\n\\tk\""));
}
@Test
public void test_issue_397_3() {
int expect = 1 / 1 + 10 * (1400 - 1400) / 400;
Object val = El.eval("1/1+10*(1400-1400)/400");
assertEquals(expect, val);
}
/**
* 带负数的运算
*/
@Test
public void negative() {
assertEquals(-1, El.eval("-1"));
assertEquals(0, El.eval("-1+1"));
assertEquals(-1 - -1, El.eval("-1 - -1"));
assertEquals(9 + 8 * 7 + (6 + 5) * (-(4 - 1 * 2 + 3)), El.eval("9+8*7+(6+5)*(-(4-1*2+3))"));
}
/**
* 方法调用
*/
@Test
public void callMethod() {
assertEquals('j', El.eval("'jk'.charAt(0)"));
assertEquals("cde", El.eval("\"abcde\".substring(2)"));
assertEquals("b", El.eval("\"abcde\".substring(1,2)"));
assertEquals(true, El.eval("\"abcd\".regionMatches(2,\"ccd\",1,2)"));
assertEquals("bbbb", El.eval("' abab '.replace('a','b').trim()"));
}
/**
* 参数
*/
@Test
public void test_simple_condition() {
Context context = Lang.context();
context.set("a", 10);
assertEquals(10, El.eval(context, "a"));
assertEquals(20, El.eval(context, "a + a"));
context.set("b", "abc");
assertEquals(25, El.eval(context, "a + 2 +a+ b.length()"));
String s = "a>5?'GT 5':'LTE 5'";
assertEquals("GT 5", El.eval(context, s));
context.set("a", 5);
assertEquals("LTE 5", El.eval(context, s));
assertEquals("jk", El.eval("\"j\"+\"k\""));
}
@Test
public void context() {
Context context = Lang.context();
List<String> list = new ArrayList<String>();
list.add("jk");
context.set("a", list);
assertEquals("jk", El.eval(context, "a.get((1-1))"));
assertEquals("jk", El.eval(context, "a.get(1-1)"));
assertEquals("jk", El.eval(context, "a.get(0)"));
assertTrue((Boolean) El.eval(Lang.context(), "a==null"));
try {
assertTrue((Boolean) El.eval(Lang.context(), "a.a"));
fail();
}
catch (Exception e) {}
}
/**
* 数组测试
*/
@Test
public void array() {
Context context = Lang.context();
String[] str = new String[]{"a", "b", "c"};
String[][] bb = new String[][]{{"a", "b"}, {"c", "d"}};
context.set("a", str);
context.set("b", bb);
assertEquals("b", El.eval(context, "a[1]"));
assertEquals("b", El.eval(context, "a[1].toString()"));
assertEquals("b", El.eval(context, "a[2-1]"));
assertEquals("d", El.eval(context, "b[1][1]"));
}
/**
* 属性测试
*/
@Test
public void field() {
class abc {
@SuppressWarnings("unused")
public String name = "jk";
}
Context context = Lang.context();
context.set("a", new abc());
assertEquals("jk", El.eval(context, "a.name"));
// 这个功能放弃
// assertFalse((Boolean)El.eval("java.lang.Boolean.FALSE"));
// assertFalse((Boolean)El.eval("Boolean.FALSE"));
}
/**
* 自定义函数
*/
@Test
public void custom() {
assertEquals(2, El.eval("max(1, 2)"));
assertEquals(1, El.eval("min(1, 2)"));
assertEquals("jk", El.eval("trim(' jk ')"));
}
@Test
public void speed() {
SimpleSpeedTest z = new SimpleSpeedTest();
int num = 4988;
String elstr = "num + (i - 1 + 2 - 3 + 4 - 5 + 6 - 7)-z.abc(i)";
int i = 5000;
Context con = Lang.context();
con.set("num", num);
con.set("i", i);
con.set("z", z);
assertEquals(num + (i - 1 + 2 - 3 + 4 - 5 + 6 - 7) - z.abc(i), El.eval(con, elstr));
}
@Test
public void lssue_486() {
assertEquals(2 + (-3), El.eval("2+(-3)"));
assertEquals(2 + -3, El.eval("2+-3"));
assertEquals(2 * -3, El.eval("2*-3"));
assertEquals(-2 * -3, El.eval("-2*-3"));
assertEquals(2 / -3, El.eval("2/-3"));
assertEquals(2 % -3, El.eval("2%-3"));
}
/**
* map测试
*/
@Test
public void map() {
Context context = Lang.context();
context.set("a", Lang.map("{x:10,y:50,txt:'Hello'}"));
assertEquals(100, El.eval(context, "a.get('x')*10"));
assertEquals(100, El.eval(context, "a.x*10"));
assertEquals(100, El.eval(context, "a['x']*10"));
assertEquals("Hello-40", El.eval(context, "a.get('txt')+(a.get('x')-a.get('y'))"));
}
/**
* list测试
*/
@Test
public void list() {
Context context = Lang.context();
List<String> list = new ArrayList<String>();
context.set("b", list);
assertEquals(0, El.eval(context, "b.size()"));
list.add("");
assertEquals(1, El.eval(context, "b.size()"));
El.eval(context, "b.add('Q\nQ')");
assertEquals(2, El.eval(context, "b.size()"));
}
@SuppressWarnings("unused")
@Test
public void complexOperation() {
assertEquals(1000
+ 100.0
* 99
- (600 - 3 * 15)
% (((68 - 9) - 3) * 2 - 100)
+ 10000
% 7
* 71, El.eval("1000+100.0*99-(600-3*15)%(((68-9)-3)*2-100)+10000%7*71"));
assertEquals(6.7 - 100 > 39.6 ? true ? 4 + 5 : 6 - 1 : !(100 % 3 - 39.0 < 27) ? 8 * 2 - 199
: 100 % 3,
El.eval("6.7-100>39.6 ? 5==5? 4+5:6-1 : !(100%3-39.0<27) ? 8*2-199: 100%3"));
Context vars = Lang.context();
vars.set("i", 100);
vars.set("pi", 3.14f);
vars.set("d", -3.9);
vars.set("b", (byte) 4);
vars.set("bool", false);
vars.set("t", "");
String t = "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";
// t =
// "i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) % 99";
assertEquals(true, El.eval(vars, t));
// assertEquals('A' == ('A') || 'B' == 'B' && "ABCD" == "" && 'A' ==
// 'A', el.eval(vars,
// "'A' == 'A' || 'B' == 'B' && 'ABCD' == t && 'A' == 'A'"));
assertEquals(true || true && false && true,
El.eval(vars, "'A' == 'A' || 'B' == 'B' && 'ABCD' == t && 'A' == 'A'"));
}
@Test
public void testIssues87() {
Context context = Lang.context();
context.set("a", new BigDecimal("7"));
context.set("b", new BigDecimal("3"));
assertEquals(10, El.eval(context, "a.add(b).intValue()"));
}
@Test
public void testIssue168() {
assertEquals(El.eval("0.1354*((70-8)%70)*100"), 0.1354 * ((70 - 8) % 70) * 100);
assertEquals(El.eval("0.1354*((70d-8)/70)*100"), 0.1354 * ((70d - 8) / 70) * 100);
assertEquals(El.eval("0.5006*(70/600*100)"), 0.5006 * (70 / 600 * 100));
}
@Test
public void testIssue277() {
Context context = Lang.context();
context.set("strings", Strings.class);
assertEquals("a", El.eval(context, "strings.trim(\" a \")"));
}
@Test
public void testIssue277_2() {
Context context = Lang.context();
context.set("math", Maths.class);
assertEquals(2, El.eval(context, "math.max(1, 2)"));
}
@Test
public void testIssue279() throws InterruptedException {
Context context = Lang.context();
context.set("math", Maths.class);
System.out.println(Maths.class.toString());
assertEquals("class org.nutz.lang.Maths", El.eval(context, "math.toString()"));
NutConf.load("org/nutz/el/issue279/279.js");
assertEquals(El.eval("uuuid(false)"), "abc");
assertEquals(El.eval("uuuid()"), "abc");
}
@Test
public void testIssue292() {
Context context = Lang.context();
context.set("a", 123);
context.set("b", 20);
Object o = El.eval(context, "a>b?a:b");
assertEquals(123, o);
}
@Test
public void testIssue293() {
Context context = Lang.context();
context.set("static", new Issue293());
context.set("a", Issue293.class);
assertEquals("xxx", El.eval(context, "a.printParam(a.info)"));
}
@Test
public void testIssue303() {
Context context = Lang.context();
Issue303 item = new Issue303("item");
item.child = new Issue303("child");
context.set("item", item);
assertEquals("child", El.eval(context, "item.child.getName()"));
assertEquals(0, El.eval(context, "item.list.size()"));
}
@Test
public void testIssue306() throws InterruptedException {
int size = 100;
final CountDownLatch count = new CountDownLatch(size);
final List<Integer> error = new ArrayList<Integer>();
for (int index = 0; index < size; index++) {
new Thread() {
public void run() {
try {
El.eval("1+1");
}
catch (Exception e) {
error.add(1);
}
finally {
count.countDown();
}
}
}.start();
}
count.await();
if (error.size() > 0) {
fail();
}
}
@Test
public void testIssue307(){
Context context = Lang.context();
List<String> list = new ArrayList<String>();
list.add("jk");
context.set("list", list);
context.set("System", System.class);
El.eval(context, "list.add(list.get(0))");
assertEquals(2, list.size());
}
@Test
public void testIssue308(){
Context context = Lang.context();
List<String> list = new ArrayList<String>();
list.add("jk");
context.set("list", list);
context.set("System", System.class);
El.eval(context, "System.getenv('PATH').getClass().getName()");
assertEquals("1", Mirror.me(String.class).invoke(String.class, "valueOf", 1));
assertEquals("jk", Mirror.me(String.class).invoke(String.class, "valueOf", "jk"));
}
@Test
public void test_issue314() {
Context context = Lang.context();
context.set("String", String.class);
Issue314 i314 = new Issue314();
List<String> list = new ArrayList<String>();
list.add("123");
i314.setList(list);
context.set("map", i314);
assertEquals("123", El.eval(context, "String.valueOf(123)"));
assertEquals("123", El.eval(context, "map.list.get(0)"));
}
@Test
public void test_issue411(){
El el=new El("a[0].b.isPass('')?'1':'2'");
Context ctx = Lang.context();
ctx.set("a",new Object[]{new org.nutz.el.issue411.Issue411.A()} );
assertEquals("1", el.eval(ctx));
}
}