package org.mvel2.tests.core;
import org.mvel2.MVEL;
import static org.mvel2.MVEL.executeExpression;
import org.mvel2.ast.Function;
import org.mvel2.compiler.CompiledExpression;
import org.mvel2.compiler.ExpressionCompiler;
import org.mvel2.integration.VariableResolverFactory;
import org.mvel2.integration.impl.MapVariableResolverFactory;
import org.mvel2.optimizers.OptimizerFactory;
import org.mvel2.util.CompilerTools;
import org.mvel2.util.MVELClassLoader;
import static org.mvel2.util.CompilerTools.extractAllDeclaredFunctions;
import java.io.Serializable;
import java.util.*;
/**
* @author Dhanji R. Prasanna (dhanji@gmail com)
*/
public class FunctionsTest extends AbstractTest {
public final void testThatFunctionsCloseOverArguments() {
final Object o = MVEL.eval(
"def fun(x) { ($ in [1, 2, 3] if $ > x) }" +
"" +
"fun(0)",
new HashMap<String, Object>()
);
assertTrue(o instanceof List);
assertEquals(Arrays.asList(1, 2, 3), o);
}
public void testFunctionDefAndCall() {
assertEquals("FoobarFoobar",
test("function heyFoo() { return 'Foobar'; };\n" +
"return heyFoo() + heyFoo();"));
}
public void testFunctionDefAndCall1() {
assertEquals("FoobarFoobar", MVEL.eval("function heyFoo() { return 'Foobar'; };\n"
+ "return heyFoo() + heyFoo();", new HashMap()));
}
public void testFunctionDefAndCall2() {
ExpressionCompiler compiler = new ExpressionCompiler("function heyFoo() { return 'Foobar'; };\n" +
"return heyFoo() + heyFoo();");
Serializable s = compiler.compile();
Map<String, Function> m = extractAllDeclaredFunctions((CompiledExpression) s);
assertTrue(m.containsKey("heyFoo"));
OptimizerFactory.setDefaultOptimizer("reflective");
assertEquals("FoobarFoobar", executeExpression(s, new HashMap()));
assertEquals("FoobarFoobar", executeExpression(s, new HashMap()));
OptimizerFactory.setDefaultOptimizer("dynamic");
}
public void testFunctionDefAndCall3() {
assertEquals("FOOBAR", test("function testFunction() { a = 'foo'; b = 'bar'; a + b; }; testFunction().toUpperCase(); "));
}
public void testFunctionDefAndCall4() {
assertEquals("barfoo", test("function testFunction(input) { return input; }; testFunction('barfoo');"));
}
public void testFunctionDefAndCall5() {
assertEquals(10, test("function testFunction(x, y) { return x + y; }; testFunction(7, 3);"));
}
public void testFunctionDefAndCall6() {
assertEquals("foo", MVEL.eval("def fooFunction(x) x; fooFunction('foo')", new HashMap()));
}
public void testAnonymousFunction() {
assertEquals("foobar", test("a = function { 'foobar' }; a();"));
}
public void testJIRA207() {
String ex = "x = 0; y = 0;" +
"def foo() { x = 1; System.out.println('Word up'); }\n" +
"def bar() { y = 1; System.out.println('Peace out'); }\n" +
"def doMany(fps) {\n" +
"foreach(f : fps) { System.out.println(f); f(); }\n" +
"}\n" +
"doMany([foo,bar]);" +
"x == 1 && y == 1;";
Boolean bool;
OptimizerFactory.setDefaultOptimizer("ASM");
Serializable s = MVEL.compileExpression(ex);
bool = (Boolean) MVEL.executeExpression(s, new HashMap());
assertTrue(bool);
OptimizerFactory.setDefaultOptimizer("dynamic");
}
public void testBranchesWithReturn() {
String ex = "function max($a, $b) {\n" +
" if ($a>$b){\n" +
" System.out.println($a);\n" +
" return $a;\n" +
"} else {\n" +
" System.out.println($b);\n" +
" return $b;\n" +
"};\n" +
"}; val = max(20, 30);";
Serializable s = MVEL.compileExpression(ex);
Map<String, Object> map = new HashMap<String, Object>();
MVEL.executeExpression(s, map);
assertEquals(30, map.get("val"));
}
public static class TestClassAZZ {
public String hey() {
return "Heythere!";
}
}
public void testCallGlobalStaticFunctionFromMVELFunction() {
TestClassAZZ azz = new TestClassAZZ();
String expr = "def foobie12345() { hey(); } foobie12345();";
assertEquals("Heythere!", MVEL.eval(expr, azz, new HashMap<String, Object>()));
}
public void testDeepNestedLoopsInFunction() {
assertEquals(10,
test("def increment(i) { i + 1 }; def ff(i) { x = 0; while (i < 1) { " + "x++; " +
"while (i < 10) { i = increment(i); } }; if (x == 1) return i; else -1; }; i = 0; ff(i);"));
}
public void testFunctions5() {
String exp = "def foo(a,b) { a + b }; foo(1.5,5.25)";
System.out.println(MVEL.eval(exp,
new HashMap()));
}
public void testJIRA174() {
OptimizerFactory.setDefaultOptimizer("ASM");
Serializable s = MVEL.compileExpression("def test(a1) { java.util.Collection a = a1; a.clear(); a.add(1); a.add(2); a.add(3); a.remove((Object) 2); a; }\n" +
"a = test(new java.util.ArrayList());\n" +
"b = test(new java.util.HashSet());");
Map vars = new HashMap();
executeExpression(s, vars);
assertEquals(false, ((Collection) vars.get("a")).contains(2));
assertEquals(2, ((Collection) vars.get("a")).size());
assertEquals(false, ((Collection) vars.get("b")).contains(2));
assertEquals(2, ((Collection) vars.get("b")).size());
}
public void testMVEL225() {
Serializable compileExpression = MVEL.compileExpression(
"def f() { int a=1;a++;return a; }; f();");
MapVariableResolverFactory factory = new MapVariableResolverFactory(new HashMap<String, Object>());
assertEquals(2, MVEL.executeExpression(compileExpression, factory));
}
public void testAnonymousFunctionDecl() {
assertEquals(3,
test("anonFunc = function (a,b) { return a + b; }; anonFunc(1,2)"));
}
public void testFunctionSemantics() {
assertEquals(true,
test("function fooFunction(a) { return a; }; x__0 = ''; 'boob' == fooFunction(x__0 = 'boob') " +
"&& x__0 == 'boob';"));
}
public void testFunctionReuse() {
VariableResolverFactory functionFactory = new MapVariableResolverFactory();
MVEL.eval("def foo() { \"foo\"; }; def bar() { \"bar\" };", functionFactory);
VariableResolverFactory myVarFactory = new MapVariableResolverFactory();
myVarFactory.setNextFactory(functionFactory);
Serializable s = MVEL.compileExpression("foo() + bar();");
assertEquals("foobar", MVEL.executeExpression(s, myVarFactory));
}
}