/** * 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.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import junit.framework.Assert; import org.junit.Test; import com.googlecode.aviator.AviatorEvaluator; import com.googlecode.aviator.exception.CompileExpressionErrorException; import com.googlecode.aviator.exception.ExpressionRuntimeException; import com.googlecode.aviator.exception.ExpressionSyntaxErrorException; /** * Aviator grammar test * * @author dennis * */ public class GrammarUnitTest { /** * 类型测试 */ @Test public void testType() { assertTrue(AviatorEvaluator.execute("1") instanceof Long); assertTrue(AviatorEvaluator.execute("3.2") instanceof Double); assertTrue(AviatorEvaluator.execute(Long.MAX_VALUE + "") instanceof Long); assertTrue(AviatorEvaluator.execute("3.14159265") instanceof Double); assertEquals("hello world", AviatorEvaluator.execute("'hello world'")); assertEquals("hello world", AviatorEvaluator.execute("\"hello world\"")); assertEquals("hello \" world", AviatorEvaluator.execute("'hello \" world'")); assertEquals("hello 'world'", AviatorEvaluator.execute("\"hello 'world'\"")); assertEquals("hello 'world' 'dennis'", AviatorEvaluator.execute("\"hello 'world' 'dennis'\"")); assertTrue((Boolean) AviatorEvaluator.execute("true")); assertFalse((Boolean) AviatorEvaluator.execute("false")); assertEquals("/\\w+\\d?\\..*/", AviatorEvaluator.execute("/\\w+\\d?\\..*/")); Map<String, Object> env = new HashMap<String, Object>(); env.put("_a", 3); assertEquals(3, AviatorEvaluator.execute("_a", env)); long now = System.currentTimeMillis(); env.put("currentTime", now); assertEquals(now, AviatorEvaluator.execute("currentTime", env)); } public class Foo { int a; public Foo() { } public Foo(int a) { super(); this.a = a; } public int getA() { return this.a; } public void setA(int a) { this.a = a; } } public class Bar extends Foo { int b; public Bar() { } public Bar(int a, int b) { super(a); this.b = b; } public int getB() { return this.b; } public void setB(int b) { this.b = b; } } /** * 类型转换 */ @Test public void testTypeConversation() { Map<String, Object> env = new HashMap<String, Object>(); env.put("foo", new Foo(100)); env.put("bar", new Bar(99, 999)); env.put("date", new Date()); Map<String, Object> map = new HashMap<String, Object>(); map.put("key", "aviator"); env.put("tmap", map); env.put("bool", Boolean.FALSE); // long op long=long assertTrue(AviatorEvaluator.execute("3+3") instanceof Long); assertTrue(AviatorEvaluator.execute("3+3/2") instanceof Long); assertTrue(AviatorEvaluator.execute("foo.a+bar.a", env) instanceof Long); assertEquals(1098L, AviatorEvaluator.execute("bar.a+bar.b", env)); // double op double=double assertTrue(AviatorEvaluator.execute("3.2+3.3") instanceof Double); assertTrue(AviatorEvaluator.execute("3.01+3.1/2.1") instanceof Double); assertTrue(AviatorEvaluator.execute("3.19+3.1/2.9-1.0/(6.0002*7.7+8.9)") instanceof Double); // double + long=double assertTrue(AviatorEvaluator.execute("3+0.02") instanceof Double); assertTrue(AviatorEvaluator.execute("3+0.02-100") instanceof Double); assertTrue(AviatorEvaluator.execute("3+3/2-1/(6*7+8.0)") instanceof Double); assertTrue(AviatorEvaluator.execute("foo.a+3.2-1000", env) instanceof Double); // object + string =string assertEquals("hello world", AviatorEvaluator.execute("'hello '+ 'world'")); assertEquals("hello aviator", AviatorEvaluator.execute("'hello '+tmap.key", env)); assertEquals("true aviator", AviatorEvaluator.execute("true+' '+tmap.key", env)); assertEquals("100aviator", AviatorEvaluator.execute("foo.a+tmap.key", env)); assertEquals("\\d+hello", AviatorEvaluator.execute("/\\d+/+'hello'")); assertEquals("3.2aviator", AviatorEvaluator.execute("3.2+tmap.key", env)); assertEquals("false is false", AviatorEvaluator.execute("bool+' is false'", env)); } @Test public void testNotOperandLimit() { Map<String, Object> env = new HashMap<String, Object>(); env.put("bool", false); assertFalse((Boolean) AviatorEvaluator.execute("!true")); assertTrue((Boolean) AviatorEvaluator.execute("!bool", env)); try { AviatorEvaluator.execute("!3"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("!3.3"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("!/\\d+/"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("!'hello'"); Assert.fail(); } catch (ExpressionRuntimeException e) { } } @Test public void testNegOperandLimit() { Map<String, Object> env = new HashMap<String, Object>(); env.put("d", -3.3); assertEquals(-3L, AviatorEvaluator.execute("-3")); assertEquals(3.3, (Double) AviatorEvaluator.execute("-d", env), 0.001); try { AviatorEvaluator.execute("-true"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("-'hello'"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("-/\\d+/"); Assert.fail(); } catch (ExpressionRuntimeException e) { } } @Test public void testAddOperandsLimit() { Map<String, Object> env = this.createEnv(); assertEquals(6, AviatorEvaluator.execute("1+2+3")); assertEquals(2.7, (Double) AviatorEvaluator.execute("6+d", env), 0.001); assertEquals("hello aviator", AviatorEvaluator.execute("'hello '+s", env)); assertEquals("-3.3aviator", AviatorEvaluator.execute("d+s", env)); assertEquals("trueaviator", AviatorEvaluator.execute("bool+s", env)); assertEquals("1aviator3", AviatorEvaluator.execute("1+s+3", env)); Foo foo = new Foo(2); env.put("foo", foo); assertEquals(6, AviatorEvaluator.execute("1+foo.a+3", env)); try { AviatorEvaluator.execute("foo+s", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("d+bool", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("1+bool+3", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("/\\d+/+100", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } } @Test public void testSubOperandsLimit() { Map<String, Object> env = this.createEnv(); assertEquals(3, AviatorEvaluator.execute("6-1-2", env)); assertEquals(2.86, (Double) AviatorEvaluator.execute("6-3.14"), 0.001); assertEquals(4.3, (Double) AviatorEvaluator.execute("1-d", env), 0.001); assertEquals(0.0, (Double) AviatorEvaluator.execute("d-d", env), 0.001); assertEquals(1003.3, (Double) AviatorEvaluator.execute("a-d", env), 0.001); this.doArithOpIllegalOperands("-"); } @Test public void testMultOperandsLimit() { Map<String, Object> env = this.createEnv(); assertEquals(300, AviatorEvaluator.execute("100*3", env)); assertEquals(18.84, (Double) AviatorEvaluator.execute("6*3.14"), 0.001); assertEquals(-9.9, (Double) AviatorEvaluator.execute("d*3", env), 0.001); assertEquals(10.89, (Double) AviatorEvaluator.execute("d*d", env), 0.001); assertEquals(-3300, (Double) AviatorEvaluator.execute("a*d", env), 0.001); this.doArithOpIllegalOperands("*"); } @Test public void testDivOperandsLimit() { Map<String, Object> env = this.createEnv(); assertEquals(33, AviatorEvaluator.execute("100/3", env)); assertEquals(1.9108, (Double) AviatorEvaluator.execute("6/3.14"), 0.001); assertEquals(-1.1, (Double) AviatorEvaluator.execute("d/3", env), 0.001); assertEquals(1.0, (Double) AviatorEvaluator.execute("d/d", env), 0.001); assertEquals(-303.030, (Double) AviatorEvaluator.execute("a/d", env), 0.001); this.doArithOpIllegalOperands("/"); } @Test public void testModOperandsLimit() { Map<String, Object> env = this.createEnv(); assertEquals(1, AviatorEvaluator.execute("100%3", env)); assertEquals(2.86, (Double) AviatorEvaluator.execute("6%3.14"), 0.001); assertEquals(-0.29999, (Double) AviatorEvaluator.execute("d%3", env), 0.001); assertEquals(0.0, (Double) AviatorEvaluator.execute("d%d", env), 0.001); assertEquals(1000 % -3.3, (Double) AviatorEvaluator.execute("a%d", env), 0.001); this.doArithOpIllegalOperands("%"); } private void doArithOpIllegalOperands(String op) { try { AviatorEvaluator.execute("1" + op + "/\\d+/"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("true" + op + "true"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("'hello world'" + op + "'hello'"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("1" + op + "s"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("bool" + op + "d"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("a" + op + "s"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("s" + op + "1000"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("bool" + op + "90.0"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("/hello/" + op + "/good/"); Assert.fail(); } catch (ExpressionRuntimeException e) { } } @Test public void testMatch() { assertTrue((Boolean) AviatorEvaluator.execute("'10'=~/^\\d+$/")); assertTrue((Boolean) AviatorEvaluator.execute("'99'=~/^\\d+$/")); assertTrue((Boolean) AviatorEvaluator.execute("'0'=~/^\\d+$/")); assertFalse((Boolean) AviatorEvaluator.execute("'-3'=~/^\\d+$/")); assertFalse((Boolean) AviatorEvaluator.execute("'-0'=~/^\\d+$/")); assertFalse((Boolean) AviatorEvaluator.execute("'aviator'=~/^\\d+$/")); assertTrue((Boolean) AviatorEvaluator.execute("'10'=~/^[0-9]*[1-9][0-9]*$/")); assertTrue((Boolean) AviatorEvaluator.execute("'1'=~/^[0-9]*[1-9][0-9]*$/")); assertFalse((Boolean) AviatorEvaluator.execute("'0'=~/^[0-9]*[1-9][0-9]*$/")); assertFalse((Boolean) AviatorEvaluator.execute("'-3'=~/^[0-9]*[1-9][0-9]*$/")); assertFalse((Boolean) AviatorEvaluator.execute("'aviator'=~/^[0-9]*[1-9][0-9]*$/")); assertTrue((Boolean) AviatorEvaluator.execute("'-10'=~/^((-\\d+)|(0+))$/")); assertTrue((Boolean) AviatorEvaluator.execute("'-99'=~/^((-\\d+)|(0+))$/")); assertFalse((Boolean) AviatorEvaluator.execute("'99'=~/^((-\\d+)|(0+))$/")); assertFalse((Boolean) AviatorEvaluator.execute("'1'=~/^((-\\d+)|(0+))$/")); assertFalse((Boolean) AviatorEvaluator.execute("'aviator'=~/^((-\\d+)|(0+))$/")); // ^-?\d+$ assertTrue((Boolean) AviatorEvaluator.execute("'-10'=~/^-?\\d+$/")); assertTrue((Boolean) AviatorEvaluator.execute("'0'=~/^-?\\d+$/")); assertTrue((Boolean) AviatorEvaluator.execute("'10'=~/^-?\\d+$/")); assertFalse((Boolean) AviatorEvaluator.execute("'aviator'=~/^-?\\d+$/")); assertTrue((Boolean) AviatorEvaluator.execute("'abc'=~/^[A-Za-z]+$/")); assertTrue((Boolean) AviatorEvaluator.execute("'ABC'=~/^[A-Za-z]+$/")); assertFalse((Boolean) AviatorEvaluator.execute("'123'=~/^[A-Za-z]+$/")); assertFalse((Boolean) AviatorEvaluator.execute("'abc'=~/^[A-Z]+$/")); assertTrue((Boolean) AviatorEvaluator.execute("'ABC'=~/^[A-Z]+$/")); assertTrue((Boolean) AviatorEvaluator.execute("'abc'=~/^[a-z]+$/")); assertFalse((Boolean) AviatorEvaluator.execute("'ABC'=~/^[a-z]+$/")); assertTrue((Boolean) AviatorEvaluator .execute("'0595-97357355'=~/^((\\+?[0-9]{2,4}\\-[0-9]{3,4}\\-)|([0-9]{3,4}\\-))?([0-9]{7,8})(\\-[0-9]+)?$/")); assertTrue((Boolean) AviatorEvaluator .execute("'0595-3749306-020'=~/^((\\+?[0-9]{2,4}\\-[0-9]{3,4}\\-)|([0-9]{3,4}\\-))?([0-9]{7,8})(\\-[0-9]+)?$/")); assertFalse((Boolean) AviatorEvaluator .execute("'0595-abc'=~/^((\\+?[0-9]{2,4}\\-[0-9]{3,4}\\-)|([0-9]{3,4}\\-))?([0-9]{7,8})(\\-[0-9]+)?$/")); assertTrue((Boolean) AviatorEvaluator.execute("'455729032'=~/^[1-9]*[1-9][0-9]*$/")); assertFalse((Boolean) AviatorEvaluator.execute("'45d729032'=~/^[1-9]*[1-9][0-9]*$/")); assertTrue((Boolean) AviatorEvaluator.execute("'<html>hello</html>'=~/<(.*)>.*<\\/\\1>|<(.*) \\/>/")); assertTrue((Boolean) AviatorEvaluator .execute("'127.0.0.1'=~/^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5]).(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5]).(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5]).(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$/")); assertFalse((Boolean) AviatorEvaluator .execute("'127.0.0.'=~/^(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5]).(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5]).(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5]).(\\d{1,2}|1\\d\\d|2[0-4]\\d|25[0-5])$/")); } @Test public void testMatchWithFlags() { assertTrue((Boolean) AviatorEvaluator.execute("'abc'=~/(?i)^[a-z]+$/")); assertTrue((Boolean) AviatorEvaluator.execute("'ABC'=~/(?i)^[a-z]+$/")); } @Test public void testComparePattern() { Map<String, Object> env = this.createEnv(); assertTrue((Boolean) AviatorEvaluator.execute("p1==p1", env)); assertTrue((Boolean) AviatorEvaluator.execute("p1>=p1", env)); assertTrue((Boolean) AviatorEvaluator.execute("p1<=p1", env)); assertTrue((Boolean) AviatorEvaluator.execute("p1<p2", env)); assertTrue((Boolean) AviatorEvaluator.execute("p2>p1", env)); assertFalse((Boolean) AviatorEvaluator.execute("p1>=p2", env)); assertFalse((Boolean) AviatorEvaluator.execute("p2<=p1", env)); assertTrue((Boolean) AviatorEvaluator.execute("/aviator/>/abc/", env)); assertFalse((Boolean) AviatorEvaluator.execute("/aviator/</abc/", env)); try { AviatorEvaluator.execute("3>/abc/"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("'abc'!=/abc/"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("3.999==p1", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("false==p1", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("p2<=bool", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } } @Test public void testCompareString() { Map<String, Object> env = this.createEnv(); assertTrue((Boolean) AviatorEvaluator.execute("'b'>'a'")); assertTrue((Boolean) AviatorEvaluator.execute("'b'>='a'")); assertTrue((Boolean) AviatorEvaluator.execute("'b'!='a'")); assertFalse((Boolean) AviatorEvaluator.execute("'b'<'a'")); assertFalse((Boolean) AviatorEvaluator.execute("'b'<='a'")); assertTrue((Boolean) AviatorEvaluator.execute("s==s", env)); assertTrue((Boolean) AviatorEvaluator.execute("s>'abc'", env)); assertFalse((Boolean) AviatorEvaluator.execute("s<'abc'", env)); assertFalse((Boolean) AviatorEvaluator.execute("s<='abc'", env)); assertTrue((Boolean) AviatorEvaluator.execute("s!='abc'", env)); assertTrue((Boolean) AviatorEvaluator.execute("s>'abc'", env)); assertTrue((Boolean) AviatorEvaluator.execute("s==s", env)); try { AviatorEvaluator.execute("bool>s", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("true<'abc'"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("s>bool", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("100=='hello'"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("s!=d", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("/\\d+/<=s", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("'hello'==/[a-zA-Z]/"); Assert.fail(); } catch (ExpressionRuntimeException e) { } } @Test public void testCompareNumber() { Map<String, Object> env = this.createEnv(); assertTrue((Boolean) AviatorEvaluator.execute("3>1")); assertTrue((Boolean) AviatorEvaluator.execute("3>=1")); assertTrue((Boolean) AviatorEvaluator.execute("3!=1")); assertFalse((Boolean) AviatorEvaluator.execute("3<1")); assertFalse((Boolean) AviatorEvaluator.execute("3<=1")); assertFalse((Boolean) AviatorEvaluator.execute("3==1")); assertTrue((Boolean) AviatorEvaluator.execute("3>=3")); assertTrue((Boolean) AviatorEvaluator.execute("3<=3")); assertTrue((Boolean) AviatorEvaluator.execute("d<0", env)); assertTrue((Boolean) AviatorEvaluator.execute("a>3", env)); assertTrue((Boolean) AviatorEvaluator.execute("d>=d", env)); assertFalse((Boolean) AviatorEvaluator.execute("d>0", env)); assertFalse((Boolean) AviatorEvaluator.execute("d>=0", env)); assertFalse((Boolean) AviatorEvaluator.execute("a<3", env)); assertFalse((Boolean) AviatorEvaluator.execute("d>=3", env)); assertFalse((Boolean) AviatorEvaluator.execute("a<=3", env)); assertTrue((Boolean) AviatorEvaluator.execute("a>=a", env)); assertTrue((Boolean) AviatorEvaluator.execute("a>d", env)); assertTrue((Boolean) AviatorEvaluator.execute("d<a", env)); try { AviatorEvaluator.execute("bool>3", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("true<100"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("d>bool", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("100=='hello'"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("'good'>a", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("/\\d+/>3"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("4.9==/[a-zA-Z]/"); Assert.fail(); } catch (ExpressionRuntimeException e) { } } @Test public void testLogicOr() { assertTrue((Boolean) AviatorEvaluator.execute("true||true")); assertTrue((Boolean) AviatorEvaluator.execute("true||false")); assertTrue((Boolean) AviatorEvaluator.execute("false||true")); assertFalse((Boolean) AviatorEvaluator.execute("false||false")); Map<String, Object> env = new HashMap<String, Object>(); env.put("a", Boolean.FALSE); env.put("b", Boolean.TRUE); env.put("s", "hello"); env.put("c", 3.3); assertTrue((Boolean) AviatorEvaluator.execute("b||b", env)); assertTrue((Boolean) AviatorEvaluator.execute("b||a", env)); assertTrue((Boolean) AviatorEvaluator.execute("a||b", env)); assertFalse((Boolean) AviatorEvaluator.execute("a||a", env)); try { AviatorEvaluator.execute("3 || true"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("false || 3"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("c || 3", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("false || c", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("false || s", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("c || s", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("/test/ || s", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } // 测试短路 assertTrue((Boolean) AviatorEvaluator.execute("true || s")); assertTrue((Boolean) AviatorEvaluator.execute("true || c")); assertTrue((Boolean) AviatorEvaluator.execute("true || 3")); assertTrue((Boolean) AviatorEvaluator.execute("true || /hello/")); } @Test public void testLogicAnd() { assertTrue((Boolean) AviatorEvaluator.execute("true&&true")); assertFalse((Boolean) AviatorEvaluator.execute("true&&false")); assertFalse((Boolean) AviatorEvaluator.execute("false && true")); assertFalse((Boolean) AviatorEvaluator.execute("false &&false")); Map<String, Object> env = new HashMap<String, Object>(); env.put("a", Boolean.FALSE); env.put("b", Boolean.TRUE); env.put("s", "hello"); env.put("c", 3.3); assertTrue((Boolean) AviatorEvaluator.execute("b&& b", env)); assertFalse((Boolean) AviatorEvaluator.execute("b &&a", env)); assertFalse((Boolean) AviatorEvaluator.execute("a&&b", env)); assertFalse((Boolean) AviatorEvaluator.execute("a && a", env)); try { AviatorEvaluator.execute("3 && true"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("true && 3"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("c && 3", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("true && c", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("true && s", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("c&& s", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("/test/ && s", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } // 测试短路 assertFalse((Boolean) AviatorEvaluator.execute("false && s")); assertFalse((Boolean) AviatorEvaluator.execute("false && c")); assertFalse((Boolean) AviatorEvaluator.execute("false && 3")); assertFalse((Boolean) AviatorEvaluator.execute("false && /hello/")); } /* * 测试三元表达式 */ @Test public void testTernaryOperator() { Map<String, Object> env = new HashMap<String, Object>(); int i = 0; float f = 3.14f; String email = "killme2008@gmail.com"; char ch = 'a'; boolean t = true; env.put("i", i); env.put("f", f); env.put("email", email); env.put("ch", ch); env.put("t", t); assertEquals(1, AviatorEvaluator.execute("2>1?1:0")); assertEquals(0, AviatorEvaluator.execute("2<1?1:0")); assertEquals(f, (Float) AviatorEvaluator.execute("false?i:f", env), 0.001); assertEquals(i, AviatorEvaluator.execute("true?i:f", env)); assertEquals("killme2008", AviatorEvaluator.execute("email=~/([\\w0-9]+)@\\w+\\.\\w+/ ? $1:'unknow'", env)); assertEquals(f, (Float) AviatorEvaluator.execute("ch!='a'?i:f", env), 0.001); assertEquals(i, AviatorEvaluator.execute("ch=='a'?i:f", env)); assertEquals(email, AviatorEvaluator.execute("t?email:ch", env)); // 多层嵌套 assertEquals(ch, AviatorEvaluator.execute("t? i>0? f:ch : email", env)); assertEquals(email, AviatorEvaluator.execute("!t? i>0? f:ch : f>3?email:ch", env)); // 使用括号 assertEquals(email, AviatorEvaluator.execute("!t? (i>0? f:ch) :( f>3?email:ch)", env)); // 测试错误情况 try { AviatorEvaluator.execute("f?1:0", env); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("'hello'?1:0"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("/test/?1:0"); Assert.fail(); } catch (ExpressionRuntimeException e) { } try { AviatorEvaluator.execute("!t? (i>0? f:ch) : f>3?email:ch)", env); Assert.fail(); } catch (ExpressionSyntaxErrorException e) { } try { AviatorEvaluator.execute("!t? (i>0? f:ch : (f>3?email:ch)", env); Assert.fail(); } catch (ExpressionSyntaxErrorException e) { } } /** * 测试nil */ @Test public void testNilObject() { assertTrue((Boolean) AviatorEvaluator.execute("a==nil")); assertTrue((Boolean) AviatorEvaluator.execute("nil==a")); assertFalse((Boolean) AviatorEvaluator.execute("3==nil")); assertTrue((Boolean) AviatorEvaluator.execute("3!=nil")); assertFalse((Boolean) AviatorEvaluator.execute("3.5==nil")); assertTrue((Boolean) AviatorEvaluator.execute("3.5!=nil")); assertFalse((Boolean) AviatorEvaluator.execute("true==nil")); assertTrue((Boolean) AviatorEvaluator.execute("true!=nil")); assertFalse((Boolean) AviatorEvaluator.execute("false==nil")); assertTrue((Boolean) AviatorEvaluator.execute("false!=nil")); assertTrue((Boolean) AviatorEvaluator.execute("nil==nil")); assertFalse((Boolean) AviatorEvaluator.execute("nil!=nil")); assertFalse((Boolean) AviatorEvaluator.execute("'a'==nil")); assertTrue((Boolean) AviatorEvaluator.execute("'a'!=nil")); assertFalse((Boolean) AviatorEvaluator.execute("/\\d+/==nil")); assertTrue((Boolean) AviatorEvaluator.execute("/\\d+/!=nil")); Map<String, Object> env = this.createEnv(); assertFalse((Boolean) AviatorEvaluator.execute("p1==nil", env)); assertTrue((Boolean) AviatorEvaluator.execute("p1>nil", env)); assertFalse((Boolean) AviatorEvaluator.execute("d==nil", env)); assertTrue((Boolean) AviatorEvaluator.execute("d>nil", env)); assertFalse((Boolean) AviatorEvaluator.execute("s==nil", env)); assertTrue((Boolean) AviatorEvaluator.execute("s>nil", env)); assertFalse((Boolean) AviatorEvaluator.execute("bool==nil", env)); assertTrue((Boolean) AviatorEvaluator.execute("bool>nil", env)); assertFalse((Boolean) AviatorEvaluator.execute("a==nil", env)); assertTrue((Boolean) AviatorEvaluator.execute("a>nil", env)); // null == null assertTrue((Boolean) AviatorEvaluator.execute("a==b")); assertFalse((Boolean) AviatorEvaluator.execute("'s'==a")); assertTrue((Boolean) AviatorEvaluator.execute("'s'>=a")); assertTrue((Boolean) AviatorEvaluator.execute("'s'>a")); assertTrue((Boolean) AviatorEvaluator.execute("bool>unknow", env)); } @Test public void testIndex() { Map<String, Object> env = new HashMap<String, Object>(); Integer[] a = new Integer[10]; for (int i = 0; i < a.length; i++) { a[i] = i; } List<String> list = new ArrayList<String>(); list.add("hello"); list.add("world"); env.put("a", a); env.put("list", list); final HashSet<Integer> set = new HashSet<Integer>(); set.add(99); env.put("set", set); for (int i = 0; i < a.length; i++) { assertEquals(a[i], AviatorEvaluator.execute("a[" + i + "]", env)); assertEquals(a[i] + i, AviatorEvaluator.execute("a[" + i + "]+" + i, env)); assertEquals(a[i] + i, AviatorEvaluator.execute("a[a[a[" + i + "]-10+10]]+" + i, env)); } assertEquals("hello", AviatorEvaluator.execute("list[0]", env)); assertEquals(5, AviatorEvaluator.execute("string.length(list[0])", env)); assertEquals("world", AviatorEvaluator.execute("list[1]", env)); assertEquals("hello world", AviatorEvaluator.execute("list[0]+' '+list[1]", env)); try { AviatorEvaluator.execute("set[0]+' '+set[0]", env); fail(); } catch (ExpressionRuntimeException e) { // e.printStackTrace(); } } @Test public void testArrayIndexAccessWithMethod() { assertEquals("a", AviatorEvaluator.exec("string.split('a,b,c,d',',')[0]")); assertEquals("b", AviatorEvaluator.exec("string.split('a,b,c,d',',')[1]")); assertEquals("c", AviatorEvaluator.exec("string.split('a,b,c,d',',')[2]")); assertEquals("d", AviatorEvaluator.exec("string.split('a,b,c,d',',')[3]")); try { AviatorEvaluator.exec("string.split('a,b,c,d',',')[4]"); fail(); } catch (ExpressionRuntimeException e) { } assertEquals("a", AviatorEvaluator.exec("string.split(s,',')[0]", "a,b,c,d")); assertEquals("b", AviatorEvaluator.exec("string.split(s,',')[1]", "a,b,c,d")); assertEquals("c", AviatorEvaluator.exec("string.split(s,',')[2]", "a,b,c,d")); assertEquals("d", AviatorEvaluator.exec("string.split(s,',')[3]", "a,b,c,d")); } @Test public void testArrayIndexAccessWithMethodAndBracket() { assertEquals("a", AviatorEvaluator.exec("(string.split('a,b,c,d',','))[0]")); assertEquals("b", AviatorEvaluator.exec("(string.split('a,b,c,d',','))[1]")); assertEquals("c", AviatorEvaluator.exec("(string.split('a,b,c,d',','))[2]")); assertEquals("d", AviatorEvaluator.exec("(string.split('a,b,c,d',','))[3]")); try { AviatorEvaluator.exec("(string.split('a,b,c,d',','))[4]"); fail(); } catch (ExpressionRuntimeException e) { } assertEquals("a", AviatorEvaluator.exec("(string.split(s,','))[0]", "a,b,c,d")); assertEquals("b", AviatorEvaluator.exec("(string.split(s,','))[1]", "a,b,c,d")); assertEquals("c", AviatorEvaluator.exec("(string.split(s,','))[2]", "a,b,c,d")); assertEquals("d", AviatorEvaluator.exec("(string.split(s,','))[3]", "a,b,c,d")); } @Test(expected = CompileExpressionErrorException.class) public void testIllegalArrayIndexAccessWithMethod1(){ AviatorEvaluator.exec("string.split('a,b,c,d',',')[0"); } @Test(expected = CompileExpressionErrorException.class) public void testIllegalArrayIndexAccessWithMethod2(){ AviatorEvaluator.exec("string.split('a,b,c,d',','[0]"); } @Test public void testFunctionCall() { Map<String, Object> env = this.createEnv(); assertEquals(10, AviatorEvaluator.execute(" string.length('hello') + string.length('hello') ")); assertEquals(3.0, (Double) AviatorEvaluator.execute(" string.length('hello')>5? math.abs(d):math.log10(a) ", env), 0.001); assertEquals(3.3, (Double) AviatorEvaluator.execute(" string.length('hello')==5? math.abs(d):math.log10(a) ", env), 0.001); assertEquals(3.3, (Double) AviatorEvaluator.execute( "string.contains(p1,'A-Z')? d<0? math.abs(d): math.sqrt(a) : string.length(p2) ", env), 0.001); Date date = new Date(111, 8, 11); env.put("date", date); assertEquals("2011-09-11", AviatorEvaluator.execute("date_to_string(date,'yyyy-MM-dd')", env)); assertEquals(date, AviatorEvaluator.execute("string_to_date('2011-09-11','yyyy-MM-dd')")); assertArrayEquals(new String[] { "a", "b", "c" }, (String[]) AviatorEvaluator.execute("string.split('a,b,c',',')")); env.put("tmps", new String[] { "hello", "aviator" }); assertEquals("hello aviator", AviatorEvaluator.execute("string.join(tmps,\" \")", env)); } private Map<String, Object> createEnv() { Map<String, Object> env = new HashMap<String, Object>(); env.put("d", -3.3); env.put("s", "aviator"); env.put("bool", true); env.put("a", 1000); env.put("p1", "[a-z-A-Z]+"); env.put("p2", "\\d+\\.\\d+"); return env; } @Test public void testScientificNotationBiggerSmaller() { assertEquals(4E81 / 3E9, AviatorEvaluator.execute("4E81/3E9")); assertEquals(1E9 / 2E101, AviatorEvaluator.execute("1E9/2E101")); assertEquals(4E81 / 3E9, AviatorEvaluator.exec("a/3E9", 4E81)); assertEquals(1E9 / 2E101, AviatorEvaluator.exec("1E9/b", 2E101)); } @Test(expected = ExpressionSyntaxErrorException.class) public void test4J() { System.out.println(AviatorEvaluator.execute("4(ss*^^%%$$$$")); } }