package org.mvel2.tests.core; import junit.framework.TestCase; import org.mvel2.CompileException; import org.mvel2.DataConversion; import org.mvel2.MVEL; import org.mvel2.Macro; import org.mvel2.ParserConfiguration; import org.mvel2.ParserContext; import org.mvel2.PropertyAccessor; import org.mvel2.ast.ASTNode; import org.mvel2.compiler.CompiledExpression; import org.mvel2.compiler.ExecutableStatement; import org.mvel2.compiler.ExpressionCompiler; import org.mvel2.integration.Interceptor; import org.mvel2.integration.PropertyHandlerFactory; import org.mvel2.integration.ResolverTools; import org.mvel2.integration.VariableResolverFactory; import org.mvel2.integration.impl.ClassImportResolverFactory; import org.mvel2.integration.impl.DefaultLocalVariableResolverFactory; import org.mvel2.integration.impl.IndexedVariableResolverFactory; import org.mvel2.integration.impl.MapVariableResolverFactory; import org.mvel2.optimizers.OptimizerFactory; import org.mvel2.tests.core.res.Bar; import org.mvel2.tests.core.res.Base; import org.mvel2.tests.core.res.Cheese; import org.mvel2.tests.core.res.Cheesery; import org.mvel2.tests.core.res.Column; import org.mvel2.tests.core.res.DefaultKnowledgeHelper; import org.mvel2.tests.core.res.Foo; import org.mvel2.tests.core.res.Grid; import org.mvel2.tests.core.res.KnowledgeHelper; import org.mvel2.tests.core.res.KnowledgeHelperFixer; import org.mvel2.tests.core.res.MapObject; import org.mvel2.tests.core.res.MyClass; import org.mvel2.tests.core.res.MyInterface; import org.mvel2.tests.core.res.OverloadedInterface; import org.mvel2.tests.core.res.PojoStatic; import org.mvel2.tests.core.res.RuleBase; import org.mvel2.tests.core.res.RuleBaseImpl; import org.mvel2.tests.core.res.SampleBean; import org.mvel2.tests.core.res.SampleBeanAccessor; import org.mvel2.tests.core.res.Ship; import org.mvel2.tests.core.res.Status; import org.mvel2.tests.core.res.TestClass; import org.mvel2.tests.core.res.User; import org.mvel2.tests.core.res.WorkingMemory; import org.mvel2.tests.core.res.WorkingMemoryImpl; import org.mvel2.tests.core.res.res2.ClassProvider; import org.mvel2.tests.core.res.res2.Outer; import org.mvel2.tests.core.res.res2.OverloadedClass; import org.mvel2.tests.core.res.res2.PublicClass; import org.mvel2.util.ParseTools; import org.mvel2.util.ReflectionUtil; import java.awt.*; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.io.Serializable; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Vector; import static java.util.Collections.unmodifiableCollection; import static org.mvel2.MVEL.*; import static org.mvel2.util.ParseTools.loadFromFile; @SuppressWarnings({"ALL"}) public class CoreConfidenceTests extends AbstractTest { public void testWhileUsingImports() { Map<String, Object> imports = new HashMap<String, Object>(); imports.put("ArrayList", java.util.ArrayList.class); imports.put("List", java.util.List.class); ParserContext context = new ParserContext(imports, null, "testfile"); ExpressionCompiler compiler = new ExpressionCompiler("List list = new ArrayList(); return (list == empty)", context); assertTrue((Boolean) executeExpression(compiler.compile(), new DefaultLocalVariableResolverFactory())); } public void testBooleanModeOnly2() { assertEquals(false, (Object) DataConversion.convert(test("BWAH"), Boolean.class)); } public void testBooleanModeOnly4() { assertEquals(true, test("hour == (hour + 0)")); } // interpreted public void testThisReferenceMapVirtualObjects() { Map<String, String> map = new HashMap<String, String>(); map.put("foo", "bar"); VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap<String, Object>()); factory.createVariable("this", map); assertEquals(true, eval("this.foo == 'bar'", map, factory)); } // compiled - reflective public void testThisReferenceMapVirtualObjects1() { // Create our root Map object Map<String, String> map = new HashMap<String, String>(); map.put("foo", "bar"); VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap<String, Object>()); factory.createVariable("this", map); OptimizerFactory.setDefaultOptimizer("reflective"); // Run test assertEquals(true, executeExpression(compileExpression("this.foo == 'bar'"), map, factory)); } // compiled - asm public void testThisReferenceMapVirtualObjects2() { // Create our root Map object Map<String, String> map = new HashMap<String, String>(); map.put("foo", "bar"); VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap<String, Object>()); factory.createVariable("this", map); // I think we can all figure this one out. if (!Boolean.getBoolean("mvel2.disable.jit")) OptimizerFactory.setDefaultOptimizer("ASM"); // Run test assertEquals(true, executeExpression(compileExpression("this.foo == 'bar'"), map, factory)); } public void testEvalToBoolean() { assertEquals(true, (boolean) evalToBoolean("true ", "true")); assertEquals(true, (boolean) evalToBoolean("true ", "true")); } public void testImport() { assertEquals(HashMap.class, test("import java.util.HashMap; HashMap;")); } public void testImport2() { HashMap[] maps = (HashMap[]) MVEL.eval("import java.util.*; HashMap[] maps = new HashMap[10]; maps", new HashMap()); assertEquals(10, maps.length); } public static class MyPerson { private String name; public MyPerson(String name) { this.name = name; } public String getName() { return name; } } public void testUnusedPackageImport() { String expression = "import java.util.*; " + "name == \"Mario\" "; Serializable compiledExpression = MVEL.compileExpression(expression); boolean result = (Boolean) MVEL.executeExpression(compiledExpression, new MyPerson("Mario")); assertTrue(result); } public void testStaticImport() { assertEquals(2.0, test("import_static java.lang.Math.sqrt; sqrt(4)")); } /** * Start collections framework based compliance tests */ public void testCreationOfSet() { assertEquals("foo bar foo bar", test("set = new java.util.LinkedHashSet(); " + "set.add('foo');" + "set.add('bar');" + "output = '';" + "foreach (item : set) {" + "output = output + item + ' ';" + "} " + "foreach (item : set) {" + "output = output + item + ' ';" + "} " + "output = output.trim();" + "if (set.size() == 2) { return output; }")); } public void testCreationOfList() { assertEquals(5, test("l = new java.util.LinkedList(); l.add('fun'); l.add('happy'); l.add('fun'); l.add('slide');" + "l.add('crap'); poo = new java.util.ArrayList(l); poo.size();")); } public void testMapOperations() { assertEquals("poo5", test("l = new java.util.ArrayList(); l.add('plop'); l.add('poo'); m = new java.util.HashMap();" + "m.put('foo', l); m.put('cah', 'mah'); m.put('bar', 'foo'); m.put('sarah', 'mike');" + "m.put('edgar', 'poe'); if (m.edgar == 'poe') { return m.foo[1] + m.size(); }")); } public void testStackOperations() { assertEquals(10, test("stk = new java.util.Stack();" + "stk.push(5);" + "stk.push(5);" + "stk.pop() + stk.pop();")); } public void testSystemOutPrint() { test("a = 0;\r\nSystem.out.println('This is a test');"); } // public void testClassImportViaFactory() { // MapVariableResolverFactory mvf = new MapVariableResolverFactory(createTestMap()); // ClassImportResolverFactory classes = new ClassImportResolverFactory(); // classes.addClass(HashMap.class); // // ResolverTools.appendFactory(mvf, classes); // // assertTrue(executeExpression(compileExpression("HashMap map = new HashMap()", // classes.getImportedClasses()), // mvf) instanceof HashMap); // } // // public void testSataticClassImportViaFactory() { // MapVariableResolverFactory mvf = new MapVariableResolverFactory(createTestMap()); // ClassImportResolverFactory classes = new ClassImportResolverFactory(); // classes.addClass(Person.class); // // ResolverTools.appendFactory(mvf, // classes); // // assertEquals("tom", // executeExpression(compileExpression("p = new Person('tom'); return p.name;", // classes.getImportedClasses()), // mvf)); // } public void testCheeseConstructor() { MapVariableResolverFactory mvf = new MapVariableResolverFactory(createTestMap()); ClassImportResolverFactory classes = new ClassImportResolverFactory(null, null, false); classes.addClass(Cheese.class); ResolverTools.appendFactory(mvf, classes); assertTrue(executeExpression(compileExpression("cheese = new Cheese(\"cheddar\", 15);", classes.getImportedClasses()), mvf) instanceof Cheese); } public void testInterceptors() { Interceptor testInterceptor = new Interceptor() { public int doBefore(ASTNode node, VariableResolverFactory factory) { System.out.println("BEFORE Node: " + node.getName()); return 0; } public int doAfter(Object val, ASTNode node, VariableResolverFactory factory) { System.out.println("AFTER Node: " + node.getName()); return 0; } }; Map<String, Interceptor> interceptors = new HashMap<String, Interceptor>(); interceptors.put("test", testInterceptor); executeExpression(compileExpression("@test System.out.println('MIDDLE');", null, interceptors)); } public void testSubtractNoSpace1() { assertEquals(59, test("hour-1")); } public void testStrictTypingCompilation() { // OptimizerFactory.setDefaultOptimizer(OptimizerFactory.DYNAMIC); ParserContext ctx = new ParserContext(); ctx.setStrictTypeEnforcement(true); ExpressionCompiler compiler = new ExpressionCompiler("a.foo;\nb.foo;\n x = 5", ctx); try { compiler.compile(); } catch (CompileException e) { e.printStackTrace(); return; } assertTrue(false); // OptimizerFactory.setDefaultOptimizer(OptimizerFactory.DYNAMIC); } public void testEqualityRegression() { ExpressionCompiler compiler = new ExpressionCompiler("price == (new Integer( 5 ) + 5 ) "); compiler.compile(); } public void testEvaluationRegression() { ExpressionCompiler compiler = new ExpressionCompiler("(p.age * 2)"); compiler.compile(); assertTrue(compiler.getParserContextState().getInputs().containsKey("p")); } public void testIncrementAndAssignWithInputs() { ExpressionCompiler compiler = new ExpressionCompiler("total += cheese"); compiler.compile(); assertTrue(compiler.getParserContextState().getInputs().containsKey("total")); assertTrue(compiler.getParserContextState().getInputs().containsKey("cheese")); } public void testAssignmentRegression() { ExpressionCompiler compiler = new ExpressionCompiler("total = total + $cheese.price"); compiler.compile(); } public void testTypeRegression() { ParserContext ctx = new ParserContext(); ctx.setStrictTypeEnforcement(true); ExpressionCompiler compiler = new ExpressionCompiler("total = 0", ctx); compiler.compile(); assertEquals(Integer.class, compiler.getParserContextState().getVarOrInputType("total")); } public void testTestIntToLong() { String s = "1+(long)a"; ParserContext pc = new ParserContext(); pc.addInput("a", Integer.class); ExpressionCompiler compiler = new ExpressionCompiler(s, pc); CompiledExpression expr = compiler.compile(); Map vars = new HashMap(); vars.put("a", 1); Object r = ((ExecutableStatement) expr).getValue(null, new MapVariableResolverFactory(vars)); assertEquals(new Long(2), r); } public void testMapPropertyCreateCondensed() { assertEquals("foo", test("map = new java.util.HashMap(); map['test'] = 'foo'; map['test'];")); } public void testDeepMethod() { assertEquals(false, test("foo.bar.testList.add(new String()); foo.bar.testList == empty")); } public void testListAccessorAssign() { String ex = "a = new java.util.ArrayList(); a.add('foo'); a.add('BAR'); a[1] = 'bar'; a[1]"; OptimizerFactory.setDefaultOptimizer("ASM"); Serializable s = MVEL.compileExpression(ex); assertEquals("bar", MVEL.executeExpression(s, new HashMap())); OptimizerFactory.setDefaultOptimizer(OptimizerFactory.DYNAMIC); assertEquals("bar", test("a = new java.util.ArrayList(); a.add('foo'); a.add('BAR'); a[1] = 'bar'; a[1]")); } public void testBracketInString() { test("System.out.println('1)your guess was:');"); } public void testNesting() { assertEquals("foo", test("new String(new String(new String(\"foo\")));")); } public void testTypeCast() { assertEquals("10", test("(String) 10")); } public void testTypeCast2() { String ex = "map = new java.util.HashMap(); map.put('doggie', new java.util.ArrayList());" + " ((java.util.ArrayList) map['doggie']).size()"; Map map = createTestMap(); assertEquals(0, MVEL.eval(ex, map)); assertEquals(0, test(ex)); } public void testMapAccessSemantics() { Map<String, Object> outermap = new HashMap<String, Object>(); Map<String, Object> innermap = new HashMap<String, Object>(); innermap.put("test", "foo"); outermap.put("innermap", innermap); assertEquals("foo", testCompiledSimple("innermap['test']", outermap, null)); } public void testMapBindingSemantics() { Map<String, Object> outermap = new HashMap<String, Object>(); Map<String, Object> innermap = new HashMap<String, Object>(); innermap.put("test", "foo"); outermap.put("innermap", innermap); setProperty(outermap, "innermap['test']", "bar"); assertEquals("bar", testCompiledSimple("innermap['test']", outermap, null)); } public void testMapNestedInsideList() { ParserContext ctx = new ParserContext(); ctx.addImport("User", User.class); ExpressionCompiler compiler = new ExpressionCompiler("users = [ 'darth' : new User('Darth', 'Vadar')," + "\n'bobba' : new User('Bobba', 'Feta') ]; [ users.get('darth'), users.get('bobba') ]", ctx); // Serializable s = compiler.compileShared(ctx); List list = (List) executeExpression(compiler.compile(), new HashMap()); User user = (User) list.get(0); assertEquals("Darth", user.getFirstName()); user = (User) list.get(1); assertEquals("Bobba", user.getFirstName()); compiler = new ExpressionCompiler("users = [ 'darth' : new User('Darth', 'Vadar')," + "\n'bobba' : new User('Bobba', 'Feta') ]; [ users['darth'], users['bobba'] ]", ctx); list = (List) executeExpression(compiler.compile(), new HashMap()); user = (User) list.get(0); assertEquals("Darth", user.getFirstName()); user = (User) list.get(1); assertEquals("Bobba", user.getFirstName()); } public void testListNestedInsideList() { ParserContext ctx = new ParserContext(); ctx.addImport("User", User.class); ExpressionCompiler compiler = new ExpressionCompiler("users = [ new User('Darth', 'Vadar'), " + "new User('Bobba', 'Feta') ]; [ users.get( 0 ), users.get( 1 ) ]", ctx); List list = (List) executeExpression(compiler.compile(), new HashMap()); User user = (User) list.get(0); assertEquals("Darth", user.getFirstName()); user = (User) list.get(1); assertEquals("Bobba", user.getFirstName()); compiler = new ExpressionCompiler("users = [ new User('Darth', 'Vadar'), " + "new User('Bobba', 'Feta') ]; [ users[0], users[1] ]", ctx); list = (List) executeExpression(compiler.compile(), new HashMap()); user = (User) list.get(0); assertEquals("Darth", user.getFirstName()); user = (User) list.get(1); assertEquals("Bobba", user.getFirstName()); } public void testSetSemantics() { Bar bar = new Bar(); Foo foo = new Foo(); assertEquals("dog", MVEL.getProperty("name", bar)); assertEquals("dog", MVEL.getProperty("name", foo)); } public void testMapBindingSemantics2() { OptimizerFactory.setDefaultOptimizer("ASM"); Map<String, Object> outermap = new HashMap<String, Object>(); Map<String, Object> innermap = new HashMap<String, Object>(); innermap.put("test", "foo"); outermap.put("innermap", innermap); executeSetExpression(compileSetExpression("innermap['test']"), outermap, "bar"); assertEquals("bar", testCompiledSimple("innermap['test']", outermap, null)); } public void testDynamicImports() { ParserContext ctx = new ParserContext(); ctx.addPackageImport("java.util"); ExpressionCompiler compiler = new ExpressionCompiler("HashMap", ctx); Serializable s = compiler.compile(); assertEquals(HashMap.class, executeExpression(s)); compiler = new ExpressionCompiler("map = new HashMap(); map.size()", ctx); s = compiler.compile(); assertEquals(0, executeExpression(s, new DefaultLocalVariableResolverFactory())); } public void testDynamicImports3() { String expression = "import java.util.*; HashMap map = new HashMap(); map.size()"; ExpressionCompiler compiler = new ExpressionCompiler(expression); Serializable s = compiler.compile(); assertEquals(0, executeExpression(s, new DefaultLocalVariableResolverFactory())); assertEquals(0, MVEL.eval(expression, new HashMap())); } public void testDynamicImportsInList() { ParserContext ctx = new ParserContext(); ctx.addPackageImport("org.mvel2.tests.core.res"); ExpressionCompiler compiler = new ExpressionCompiler("[ new User('Bobba', 'Feta') ]", ctx); List list = (List) executeExpression(compiler.compile()); User user = (User) list.get(0); assertEquals("Bobba", user.getFirstName()); } public void testDynamicImportsInMap() { ParserContext ctx = new ParserContext(); ctx.addPackageImport("org.mvel2.tests.core.res"); ExpressionCompiler compiler = new ExpressionCompiler("[ 'bobba' : new User('Bobba', 'Feta') ]", ctx); Map map = (Map) executeExpression(compiler.compile()); User user = (User) map.get("bobba"); assertEquals("Bobba", user.getFirstName()); } public void testDynamicImportsOnNestedExpressions() { ParserContext ctx = new ParserContext(); ctx.addPackageImport("org.mvel2.tests.core.res"); ExpressionCompiler compiler = new ExpressionCompiler("new Cheesery(\"bobbo\", new Cheese(\"cheddar\", 15))", ctx); Cheesery p1 = new Cheesery("bobbo", new Cheese("cheddar", 15)); Cheesery p2 = (Cheesery) executeExpression(compiler.compile(), new DefaultLocalVariableResolverFactory()); assertEquals(p1, p2); } public void testDynamicImportsWithNullConstructorParam() { ParserContext ctx = new ParserContext(); ctx.addPackageImport("org.mvel2.tests.core.res"); ExpressionCompiler compiler = new ExpressionCompiler("new Cheesery(\"bobbo\", null)", ctx); Cheesery p1 = new Cheesery("bobbo", null); Cheesery p2 = (Cheesery) executeExpression(compiler.compile(), new DefaultLocalVariableResolverFactory()); assertEquals(p1, p2); } public void testDynamicImportsWithNullConstructorParamWithStrongType() { ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addPackageImport("org.mvel2.tests.core.res"); ExpressionCompiler compiler = new ExpressionCompiler("new Cheesery(\"bobbo\", null)", ctx); Cheesery p1 = new Cheesery("bobbo", null); Cheesery p2 = (Cheesery) executeExpression(compiler.compile(), new DefaultLocalVariableResolverFactory()); assertEquals(p1, p2); } public void testDynamicImportsWithIdentifierSameAsClassWithDiffCase() { ParserContext ctx = new ParserContext(); ctx.addPackageImport("org.mvel2.tests.core.res"); ctx.setStrictTypeEnforcement(false); ExpressionCompiler compiler = new ExpressionCompiler("bar.add(\"hello\")", ctx); compiler.compile(); } public void testTypedAssignment() { assertEquals("foobar", test("java.util.Map map = new java.util.HashMap(); map.put('conan', 'foobar'); map['conan'];")); } public void testFQCNwithStaticInList() { assertEquals(Integer.MIN_VALUE, test("list = [java.lang.Integer.MIN_VALUE]; list[0]")); } public void testPrecedenceOrder() { assertTrue((Boolean) test("5 > 6 && 2 < 1 || 10 > 9")); } @SuppressWarnings({"unchecked"}) public void testDifferentImplSameCompile() { Serializable compiled = compileExpression("a.funMap.hello"); Map testMap = new HashMap(); for (int i = 0; i < 100; i++) { Base b = new Base(); b.funMap.put("hello", "dog"); testMap.put("a", b); assertEquals("dog", executeExpression(compiled, testMap)); b = new Base(); b.funMap.put("hello", "cat"); testMap.put("a", b); assertEquals("cat", executeExpression(compiled, testMap)); } } @SuppressWarnings({"unchecked"}) public void testInterfaceMethodCallWithSpace() { Map map = new HashMap(); DefaultKnowledgeHelper helper = new DefaultKnowledgeHelper(); map.put("drools", helper); Cheese cheese = new Cheese("stilton", 15); map.put("cheese", cheese); executeExpression(compileExpression("drools.retract (cheese)"), map); assertSame(cheese, helper.retracted.get(0)); } @SuppressWarnings({"unchecked"}) public void testInterfaceMethodCallWithMacro() { Map macros = new HashMap(1); macros.put("retract", new Macro() { public String doMacro() { return "drools.retract"; } }); Map map = new HashMap(); DefaultKnowledgeHelper helper = new DefaultKnowledgeHelper(); map.put("drools", helper); Cheese cheese = new Cheese("stilton", 15); map.put("cheese", cheese); executeExpression(compileExpression(parseMacros("retract(cheese)", macros)), map); assertSame(cheese, helper.retracted.get(0)); } public void testParsingStability1() { assertEquals(true, test("( order.number == 1 || order.number == ( 1+1) || order.number == $id )")); } public void testParsingStability2() { Map<String, Object> imports = new HashMap<String, Object>(); imports.put("java.awt.Dimension", Dimension.class); final ParserContext parserContext = new ParserContext(imports, null, "sourceFile"); parserContext.setStrictTypeEnforcement(false); ExpressionCompiler compiler = new ExpressionCompiler("( dim.height == 1 || dim.height == ( 1+1) || dim.height == x )", parserContext); compiler.compile(); } public void testConcatWithLineBreaks() { ParserContext ctx = new ParserContext(); ctx.setDebugSymbols(true); ctx.setSourceFile("source.mv"); ExpressionCompiler parser = new ExpressionCompiler("\"foo\"+\n\"bar\"", ctx); assertEquals("foobar", executeExpression(parser.compile())); } /** * Provided by: Alex Roytman */ public void testMethodResolutionWithNullParameter() { Context ctx = new Context(); ctx.setBean(new Bean()); Map<String, Object> vars = new HashMap<String, Object>(); System.out.println("bean.today: " + eval("bean.today", ctx, vars)); System.out.println("formatDate(bean.today): " + eval("formatDate(bean.today)", ctx, vars)); //calling method with string param with null parameter works System.out.println("formatString(bean.nullString): " + eval("formatString(bean.nullString)", ctx, vars)); System.out.println("bean.myDate = bean.nullDate: " + eval("bean.myDate = bean.nullDate; return bean.nullDate;", ctx, vars)); //calling method with Date param with null parameter fails System.out.println("formatDate(bean.myDate): " + eval("formatDate(bean.myDate)", ctx, vars)); //same here System.out.println(eval("formatDate(bean.nullDate)", ctx, vars)); } /** * Provided by: Phillipe Ombredanne */ public void testCompileParserContextShouldNotLoopIndefinitelyOnValidJavaExpression() { String expr = " System.out.println( message );\n" + // "m.setMessage( \"Goodbye cruel world\" );\n" + // "System.out.println(m.getStatus());\n" + // "m.setStatus( Message.GOODBYE );\n"; ParserContext context = new ParserContext(); context.setStrictTypeEnforcement(false); context.addImport("Message", Message.class); context.addInput("System", void.class); context.addInput("message", Object.class); context.addInput("m", Object.class); ExpressionCompiler compiler = new ExpressionCompiler(expr, context); compiler.compile(); } public void testStaticNested() { assertEquals(1, eval("org.mvel2.tests.core.AbstractTest$Message.GOODBYE", new HashMap())); } public void testStaticNestedWithImport() { String expr = "Message.GOODBYE;\n"; ParserContext context = new ParserContext(); context.setStrictTypeEnforcement(false); context.addImport("Message", Message.class); ExpressionCompiler compiler = new ExpressionCompiler(expr, context); assertEquals(1, executeExpression(compiler.compile())); } public void testStaticNestedWithMethodCall() { String expr = "item = new Item( \"Some Item\"); $msg.addItem( item ); return $msg"; ParserContext context = new ParserContext(); context.setStrictTypeEnforcement(false); context.addImport("Message", Message.class); context.addImport("Item", Item.class); // Serializable compiledExpression = compiler.compileShared(context); Map vars = new HashMap(); vars.put("$msg", new Message()); ExpressionCompiler compiler = new ExpressionCompiler(expr, context); Message msg = (Message) executeExpression(compiler.compile(), vars); Item item = (Item) msg.getItems().get(0); assertEquals("Some Item", item.getName()); } public void testsequentialAccessorsThenMethodCall() { String expr = "System.out.println(drools.workingMemory); " + "drools.workingMemory.ruleBase.removeRule(\"org.drools.examples\", \"some rule\"); "; ParserContext context = new ParserContext(); context.setStrictTypeEnforcement(true); context.addInput("drools", KnowledgeHelper.class); RuleBase ruleBase = new RuleBaseImpl(); WorkingMemory wm = new WorkingMemoryImpl(ruleBase); KnowledgeHelper drools = new DefaultKnowledgeHelper(wm); Map vars = new HashMap(); vars.put("drools", drools); ExpressionCompiler compiler = new ExpressionCompiler(expr, context); executeExpression(compiler.compile(), vars); } /** * Provided by: Aadi Deshpande */ public void testPropertyVerfierShoudldNotLoopIndefinately() { String expr = "\t\tmodel.latestHeadlines = $list;\n" + "model.latestHeadlines.add( 0, (model.latestHeadlines[2]) );"; ParserContext pCtx = new ParserContext(); pCtx.addInput("$list", List.class); pCtx.addInput("model", Model.class); ExpressionCompiler compiler = new ExpressionCompiler(expr, pCtx); compiler.setVerifying(true); compiler.compile(); } public void testCompileWithNewInsideMethodCall() { String expr = " p.name = \"goober\";\n" + " System.out.println(p.name);\n" + " drools.insert(new Address(\"Latona\"));\n"; ParserContext context = new ParserContext(); context.setStrictTypeEnforcement(false); context.addImport("Person", Person.class); context.addImport("Address", Address.class); context.addInput("p", Person.class); context.addInput("drools", Drools.class); ExpressionCompiler compiler = new ExpressionCompiler(expr, context); compiler.compile(); } /** * Submitted by: cleverpig */ public void testBug4() { ClassA A = new ClassA(); ClassB B = new ClassB(); System.out.println(MVEL.getProperty("date", A)); System.out.println(MVEL.getProperty("date", B)); } public void testIndexer() { assertEquals("foobar", testCompiledSimple("import java.util.LinkedHashMap; LinkedHashMap map = new LinkedHashMap();" + " map.put('a', 'foo'); map.put('b', 'bar'); s = ''; " + "foreach (key : map.keySet()) { System.out.println(map[key]); s += map[key]; }; return s;", createTestMap())); } public void testLateResolveOfClass() { ParserContext ctx = new ParserContext(); ctx.addImport(Foo.class); ExpressionCompiler compiler = new ExpressionCompiler("System.out.println(new Foo());", ctx); System.out.println(executeExpression(compiler.compile())); } public void testClassAliasing() { assertEquals("foobar", test("Foo244 = String; new Foo244('foobar')")); } public void testRandomExpression1() { assertEquals("HelloWorld", test("if ((x15 = foo.bar) == foo.bar && x15 == foo.bar) { return 'HelloWorld'; } " + "else { return 'GoodbyeWorld' } ")); } public void testRandomExpression4() { assertEquals(true, test("result = org.mvel2.MVEL.eval('10 * 3'); result == (10 * 3);")); } public void testRandomExpression5() { assertEquals(true, test("FooClassRef = foo.getClass(); fooInst = new FooClassRef();" + " name = org.mvel2.MVEL.eval('name', fooInst); return name == 'dog'")); } public void testRandomExpression6() { assertEquals(500, test("exprString = '250' + ' ' + '*' + ' ' + '2'; " + "compiledExpr = org.mvel2.MVEL.compileExpression(exprString);" + " return org.mvel2.MVEL.executeExpression(compiledExpr);")); } public void testRandomExpression7() { assertEquals("FOOBAR", test("'foobar'.toUpperCase();")); } public void testRandomExpression8() { assertEquals(true, test("'someString'.intern(); 'someString'.hashCode() == 'someString'.hashCode();")); } public void testRandomExpression9() { assertEquals(false, test("_abc = 'someString'.hashCode(); _xyz = _abc + 1; _abc == _xyz")); } public void testRandomExpression10() { assertEquals(false, test("(_abc = (_xyz = 'someString'.hashCode()) + 1); _abc == _xyz")); } /** * Submitted by: Guerry Semones */ private Map<Object, Object> outerMap; private Map<Object, Object> innerMap; public void testAddIntToMapWithMapSyntax() throws Throwable { outerMap = new HashMap<Object, Object>(); innerMap = new HashMap<Object, Object>(); outerMap.put("innerMap", innerMap); // fails because mvel2 checks for 'tak' in the outerMap, // rather than inside innerMap in outerMap PropertyAccessor.set(outerMap, "innerMap['foo']", 42); // instead of here assertEquals(42, innerMap.get("foo")); } public void testUpdateIntInMapWithMapSyntax() throws Throwable { outerMap = new HashMap<Object, Object>(); innerMap = new HashMap<Object, Object>(); outerMap.put("innerMap", innerMap); // fails because mvel2 checks for 'tak' in the outerMap, // rather than inside innerMap in outerMap innerMap.put("foo", 21); PropertyAccessor.set(outerMap, "innerMap['foo']", 42); // instead of updating it here assertEquals(42, innerMap.get("foo")); } private HashMap<String, Object> context = new HashMap<String, Object>(); public void before() { HashMap<String, Object> map = new HashMap<String, Object>(); MyBean bean = new MyBean(); bean.setVar(4); map.put("bean", bean); context.put("map", map); } public void testDeepProperty() { before(); Object obj = executeExpression(compileExpression("map.bean.var"), context); assertEquals(4, obj); } public void testDeepProperty2() { before(); Object obj = executeExpression(compileExpression("map.bean.getVar()"), context); assertEquals(4, obj); } public class MyBean { int var; public int getVar() { return var; } public void setVar(int var) { this.var = var; } } public void testBooleanEvaluation() { assertEquals(true, test("true||false||false")); } public void testBooleanEvaluation2() { assertEquals(true, test("equalityCheck(1,1)||fun||ackbar")); } public void testStaticWithExplicitParam() { PojoStatic pojo = new PojoStatic("10"); eval("org.mvel2.tests.core.res.AStatic.Process('10')", pojo, new HashMap()); } public void testSimpleExpression() { PojoStatic pojo = new PojoStatic("10"); eval("value!= null", pojo, new HashMap()); } public void testStaticWithExpressionParam() { PojoStatic pojo = new PojoStatic("10"); assertEquals("java.lang.String", eval("org.mvel2.tests.core.res.AStatic.Process(value.getClass().getName().toString())", pojo)); } public void testStringIndex() { assertEquals(true, test("a = 'foobar'; a[4] == 'a'")); } public void testAssertKeyword() { ExpressionCompiler compiler = new ExpressionCompiler("assert 1 == 2;"); Serializable s = compiler.compile(); try { executeExpression(s); } catch (AssertionError e) { return; } assertTrue(false); } public void testNullSafe() { Foo foo = new Foo(); Map map = new HashMap(); map.put("foo", foo); String expression = "foo.?bar.name == null"; Serializable compiled = compileExpression(expression); OptimizerFactory.setDefaultOptimizer("reflective"); assertEquals(false, executeExpression(compiled, map)); foo.setBar(null); assertEquals(true, executeExpression(compiled, map)); // execute a second time (to search for optimizer problems) OptimizerFactory.setDefaultOptimizer("ASM"); compiled = compileExpression(expression); foo.setBar(new Bar()); assertEquals(false, executeExpression(compiled, map)); foo.setBar(null); assertEquals(true, executeExpression(compiled, map)); // execute a second time (to search for optimizer problems) assertEquals(true, eval(expression, map)); } /** * MVEL-57 (Submitted by: Rognvald Eaversen) -- Slightly modified by cbrock to include a positive testcase. */ public void testMethodInvocationWithCollectionElement() { context = new HashMap(); context.put("pojo", new POJO()); context.put("number", "1192800637980"); Object result = MVEL.eval("pojo.function(pojo.dates[0].time)", context); assertEquals(String.valueOf(((POJO) context.get("pojo")).getDates().iterator().next().getTime()), result); } public class POJO { private Set<Date> dates = new HashSet<Date>(); private Map<String, Object> map = new HashMap<String, Object>(); public POJO() { dates.add(new Date()); } public Set<Date> getDates() { return dates; } public void setDates(Set<Date> dates) { this.dates = dates; } public String function(long num) { return String.valueOf(num); } public String aMethod(long num) { return String.valueOf(num); } public Map<String, Object> getMap() { return map; } public void setMap(Map<String, Object> map) { this.map = map; } public String getKey() { return "1"; } } public void testNestedMethod1() { Vector vectorA = new Vector(); Vector vectorB = new Vector(); vectorA.add("Foo244"); Map map = new HashMap(); map.put("vecA", vectorA); map.put("vecB", vectorB); testCompiledSimple("vecB.add(vecA.remove(0)); vecA.add('Foo244');", null, map); assertEquals("Foo244", vectorB.get(0)); } public void testDynamicImports2() { assertEquals(BufferedReader.class, test("import java.io.*; BufferedReader")); } public void testUseOfVarKeyword() { assertEquals("FOO_BAR", test("var barfoo = 'FOO_BAR'; return barfoo;")); } public void testAssignment5() { assertEquals(15, test("x = (10) + (5); x")); } public void testSetExpressions1() { Map<String, Object> myMap = new HashMap<String, Object>(); final Serializable fooExpr = compileSetExpression("foo"); executeSetExpression(fooExpr, myMap, "blah"); assertEquals("blah", myMap.get("foo")); executeSetExpression(fooExpr, myMap, "baz"); assertEquals("baz", myMap.get("foo")); } public void testDuplicateVariableDeclaration() { ParserContext context = new ParserContext(); ExpressionCompiler compiler = new ExpressionCompiler("String x = \"abc\"; Integer x = new Integer( 10 );", context); try { compiler.compile(); fail("Compilation must fail with duplicate variable declaration exception."); } catch (RuntimeException ce) { // success } } public void testFullyQualifiedTypeAndCast() { assertEquals(1, test("java.lang.Integer number = (java.lang.Integer) '1';")); } public void testThreadSafetyInterpreter1() { //First evaluation System.out.println("First evaluation: " + MVEL.eval("true")); new Thread(new Runnable() { public void run() { // Second evaluation - this succeeds only if the first evaluation is not commented out System.out.println("Second evaluation: " + MVEL.eval("true")); } }).start(); } public void testArrayList() throws SecurityException, NoSuchMethodException { Collection<String> collection = new ArrayList<String>(); collection.add("I CAN HAS CHEEZBURGER"); assertEquals(collection.size(), MVEL.eval("size()", collection)); } public void testUnmodifiableCollection() throws SecurityException, NoSuchMethodException { Collection<String> collection = new ArrayList<String>(); collection.add("I CAN HAS CHEEZBURGER"); collection = unmodifiableCollection(collection); assertEquals(collection.size(), MVEL.eval("size()", collection)); } public void testSingleton() throws SecurityException, NoSuchMethodException { Collection<String> collection = Collections.singleton("I CAN HAS CHEEZBURGER"); assertEquals(collection.size(), MVEL.eval("size()", collection)); } public static class TestClass2 { public void addEqualAuthorizationConstraint(Foo leg, Bar ctrlClass, Integer authorization) { } } public void testJIRA93() { Map testMap = createTestMap(); testMap.put("testClass2", new TestClass2()); Serializable s = compileExpression("testClass2.addEqualAuthorizationConstraint(foo, foo.bar, 5)"); for (int i = 0; i < 5; i++) { executeExpression(s, testMap); } } public void testJIRA96() { ParserContext ctx = new ParserContext(); ctx.setStrictTypeEnforcement(true); ctx.addInput("fooString", String[].class); ExpressionCompiler compiler = new ExpressionCompiler("fooString[0].toUpperCase()", ctx); compiler.compile(); } public void testStringToArrayCast() { Object o = test("(char[]) 'abcd'"); assertTrue(o instanceof char[]); } public void testStringToArrayCast2() { assertTrue((Boolean) test("_xyxy = (char[]) 'abcd'; _xyxy[0] == 'a'")); } public void testStaticallyTypedArrayVar() { String ex = "char[] _c___ = new char[10]; _c___ instanceof char[]"; assertTrue((Boolean) test(ex)); } public void testParserErrorHandling() { final ParserContext ctx = new ParserContext(); ExpressionCompiler compiler = new ExpressionCompiler("a[", ctx); try { compiler.compile(); } catch (Exception e) { return; } assertTrue(false); } public void testJIRA100() { assertEquals(new BigDecimal(20), test("java.math.BigDecimal axx = new java.math.BigDecimal( 10.0 ); java.math.BigDecimal bxx = " + "new java.math.BigDecimal( 10.0 ); java.math.BigDecimal cxx = axx + bxx; return cxx; ")); } public void testJIRA100b() { Serializable s = MVEL.compileExpression("java.math.BigDecimal axx = new java.math.BigDecimal( 10.0 ); java.math.BigDecimal bxx = " + "new java.math.BigDecimal( 10.0 ); java.math.BigDecimal cxx = axx + bxx; return cxx; "); assertEquals(new BigDecimal(20), executeExpression(s, new HashMap())); } public void testAssignToBean() { Person person = new Person(); MVEL.eval("this.name = 'foo'", person); assertEquals("foo", person.getName()); executeExpression(compileExpression("this.name = 'bar'"), person); assertEquals("bar", person.getName()); } public void testMapAssignmentNestedExpression() { Map map = new HashMap(); map.put("map", new HashMap()); String ex = "map[java.lang.Integer.MAX_VALUE] = 'bar'; map[java.lang.Integer.MAX_VALUE];"; assertEquals("bar", executeExpression(compileExpression(ex), map)); assertEquals("bar", MVEL.eval(ex, map)); } public void testMapAssignmentNestedExpression2() { Map map = new HashMap(); map.put("x", "bar"); map.put("map", new HashMap()); String ex = "map[x] = 'foo'; map['bar'];"; assertEquals("foo", executeExpression(compileExpression(ex), map)); assertEquals("foo", MVEL.eval(ex, map)); } /** * MVEL-103 */ public static class MvelContext { public boolean singleCalled; public boolean arrayCalled; public String[] regkeys; public void methodForTest(String string) { System.out.println("sigle param method called!"); singleCalled = true; } public void methodForTest(String[] strings) { System.out.println("array param method called!"); arrayCalled = true; } public void setRegkeys(String[] regkeys) { this.regkeys = regkeys; } public void setRegkeys(String regkey) { this.regkeys = regkey.split(","); } } public void testMethodResolutionOrder() { MvelContext mvelContext = new MvelContext(); MVEL.eval("methodForTest({'1','2'})", mvelContext); MVEL.eval("methodForTest('1')", mvelContext); assertTrue(mvelContext.arrayCalled && mvelContext.singleCalled); } public void testCustomPropertyHandler() { MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true; PropertyHandlerFactory.registerPropertyHandler(SampleBean.class, new SampleBeanAccessor()); assertEquals("dog", test("foo.sampleBean.bar.name")); PropertyHandlerFactory.unregisterPropertyHandler(SampleBean.class); MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = false; } public void testSetAccessorOverloadedEqualsStrictMode() { ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addInput("foo", Foo.class); try { CompiledExpression expr = new ExpressionCompiler("foo.bar = 0", ctx).compile(); } catch (CompileException e) { // should fail. e.printStackTrace(); return; } assertTrue(false); } private static final KnowledgeHelperFixer fixer = new KnowledgeHelperFixer(); public void testAdd__Handle__Simple() { String result = fixer.fix("update(myObject );"); assertEqualsIgnoreWhitespace("drools.update(myObject );", result); result = fixer.fix("update ( myObject );"); assertEqualsIgnoreWhitespace("drools.update( myObject );", result); } public void testAdd__Handle__withNewLines() { final String result = fixer.fix("\n\t\n\tupdate( myObject );"); assertEqualsIgnoreWhitespace("\n\t\n\tdrools.update( myObject );", result); } public void testAdd__Handle__rComplex() { String result = fixer.fix("something update( myObject); other"); assertEqualsIgnoreWhitespace("something drools.update( myObject); other", result); result = fixer.fix("something update ( myObject );"); assertEqualsIgnoreWhitespace("something drools.update( myObject );", result); result = fixer.fix(" update( myObject ); x"); assertEqualsIgnoreWhitespace(" drools.update( myObject ); x", result); //should not touch, as it is not a stand alone word result = fixer.fix("xxupdate(myObject ) x"); assertEqualsIgnoreWhitespace("xxupdate(myObject ) x", result); } public void testMultipleMatches() { String result = fixer.fix("update(myObject); update(myObject );"); assertEqualsIgnoreWhitespace("drools.update(myObject); drools.update(myObject );", result); result = fixer.fix("xxx update(myObject ); update( myObject ); update( yourObject ); yyy"); assertEqualsIgnoreWhitespace("xxx drools.update(myObject ); " + "drools.update( myObject ); drools.update( yourObject ); yyy", result); } public void testAssert1() { final String raw = "insert( foo );"; final String result = "drools.insert( foo );"; assertEqualsIgnoreWhitespace(result, fixer.fix(raw)); } public void testAssert2() { final String raw = "some code; insert( new String(\"foo\") );\n More();"; final String result = "some code; drools.insert( new String(\"foo\") );\n More();"; assertEqualsIgnoreWhitespace(result, fixer.fix(raw)); } public void testAssertLogical() { final String raw = "some code; insertLogical(new String(\"foo\"));\n More();"; final String result = "some code; drools.insertLogical(new String(\"foo\"));\n More();"; assertEqualsIgnoreWhitespace(result, fixer.fix(raw)); } public void testModifyRetractModifyInsert() { final String raw = "some code; insert( bar ); modifyRetract( foo );\n More();" + " retract( bar ); modifyInsert( foo );"; final String result = "some code; drools.insert( bar ); drools.modifyRetract( foo );\n More();" + " drools.retract( bar ); drools.modifyInsert( foo );"; assertEqualsIgnoreWhitespace(result, fixer.fix(raw)); } public void testAllActionsMushedTogether() { String result = fixer.fix("insert(myObject ); update(ourObject);\t retract(herObject);"); assertEqualsIgnoreWhitespace("drools.insert(myObject ); drools.update(ourObject);\t drools.retract(herObject);", result); result = fixer.fix("insert( myObject ); update(ourObject);\t retract(herObject );\n" + "insert( myObject ); update(ourObject);\t retract( herObject );"); assertEqualsIgnoreWhitespace("drools.insert( myObject ); drools.update(ourObject);\t " + "drools.retract(herObject );\ndrools.insert( myObject ); drools.update(ourObject);\t" + " drools.retract( herObject );", result); } public void testLeaveLargeAlone() { final String original = "yeah yeah yeah minsert( xxx ) this is a long() thing Person" + " (name=='drools') modify a thing"; final String result = fixer.fix(original); assertEqualsIgnoreWhitespace(original, result); } public void testWithNull() { final String original = null; final String result = fixer.fix(original); assertEqualsIgnoreWhitespace(original, result); } public void testLeaveAssertAlone() { final String original = "drools.insert(foo)"; assertEqualsIgnoreWhitespace(original, fixer.fix(original)); } public void testLeaveAssertLogicalAlone() { final String original = "drools.insertLogical(foo)"; assertEqualsIgnoreWhitespace(original, fixer.fix(original)); } public void testWackyAssert() { final String raw = "System.out.println($person1.getName() + \" and \" + $person2.getName() " + "+\" are sisters\");\n" + "insert($person1.getName(\"foo\") + \" and \" + $person2.getName() " + "+\" are sisters\"); yeah();"; final String expected = "System.out.println($person1.getName() + \" and \" + $person2.getName()" + " +\" are sisters\");\n" + "drools.insert($person1.getName(\"foo\") + \" and \" + $person2.getName() " + "+\" are sisters\"); yeah();"; assertEqualsIgnoreWhitespace(expected, fixer.fix(raw)); } public void testMoreAssertCraziness() { final String raw = "foobar(); (insert(new String(\"blah\").get()); bangBangYudoHono();)"; assertEqualsIgnoreWhitespace("foobar(); (drools.insert(new String(\"blah\").get()); bangBangYudoHono();)", fixer.fix(raw)); } public void testRetract() { final String raw = "System.out.println(\"some text\");retract(object);"; assertEqualsIgnoreWhitespace("System.out.println(\"some text\");drools.retract(object);", fixer.fix(raw)); } private void assertEqualsIgnoreWhitespace(final String expected, final String actual) { if (expected == null || actual == null) { assertEquals(expected, actual); return; } final String cleanExpected = expected.replaceAll("\\s+", ""); final String cleanActual = actual.replaceAll("\\s+", ""); assertEquals(cleanExpected, cleanActual); } public void testIncrementInBooleanStatement() { assertEquals(true, test("hour++ < 61 && hour == 61")); } public void testIncrementInBooleanStatement2() { assertEquals(true, test("++hour == 61")); } public void testStaticallyTypedLong() { assertEquals(10l, test("10l")); } public void testNakedMethodCall() { MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true; OptimizerFactory.setDefaultOptimizer("ASM"); Serializable c = compileExpression("tm = System.currentTimeMillis"); assertTrue(((Long) executeExpression(c, new HashMap())) > 0); OptimizerFactory.setDefaultOptimizer("reflective"); assertTrue(((Long) executeExpression(c, new HashMap())) > 0); Map map = new HashMap(); map.put("foo", new Foo()); c = compileExpression("foo.happy"); assertEquals("happyBar", executeExpression(c, map)); OptimizerFactory.setDefaultOptimizer("ASM"); c = compileExpression("foo.happy"); assertEquals("happyBar", executeExpression(c, map)); MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = false; } public void testDecl() { assertEquals((char) 100, test("char chr; chr = 100; chr")); } public void testInlineUnion() { assertEquals("test", test("{'foo', 'test'}[1]")); } public static double minim(double[] tab) { double min = Float.MAX_VALUE; for (int i = 0; i < tab.length; i++) { if (min > tab[i]) { min = tab[i]; } } return min; } public void testJIRA113() { assertEquals(true, test("org.mvel2.tests.core.CoreConfidenceTests.minim( new double[] {456.2, 2.3} ) == 2.3")); } public void testChainedMethodCallsWithParams() { assertEquals(true, test("foo.toUC(\"abcd\").equals(\"ABCD\")")); } public void testIsUsedInIf() { assertEquals(true, test("c = 'str'; if (c is String) { true; } else { false; } ")); } public void testJIRA122() { Serializable s = compileExpression("System.out.println('>'+java.lang.Character.toLowerCase(name.charAt(0))); java.lang.Character.toLowerCase(name.charAt(0)) == 'a'"); OptimizerFactory.setDefaultOptimizer("ASM"); Map map = new HashMap(); map.put("name", "Adam"); assertEquals(true, executeExpression(s, map)); assertEquals(true, executeExpression(s, map)); } public void testJIRA122b() { Serializable s = compileExpression("System.out.println('>'+java.lang.Character.toLowerCase(name.charAt(0))); java.lang.Character.toLowerCase(name.charAt(0)) == 'a'"); OptimizerFactory.setDefaultOptimizer("reflective"); Map map = new HashMap(); map.put("name", "Adam"); assertEquals(true, executeExpression(s, map)); assertEquals(true, executeExpression(s, map)); } public void testJIRA103() { MvelContext mvelContext = new MvelContext(); MVEL.setProperty(mvelContext, "regkeys", "s"); } public void testJIRA103b() { MvelContext mvelContext = new MvelContext(); Map map = new HashMap(); map.put("ctx", mvelContext); Serializable c = compileExpression("ctx.regkeys = 'foo'"); executeExpression(c, map); executeExpression(c, map); } public void testMethodCaching() { MVEL.eval("for (pet: getPets()) pet.run();", new PetStore()); } public static class PetStore { public List getPets() { List pets = new ArrayList(); pets.add(new Dog()); pets.add(new Cat()); return pets; } } public static class Pet { public void run() { } } public static class Dog extends Pet { @Override public void run() { System.out.println("dog is running"); } } public static class Cat extends Pet { @Override public void run() { System.out.println("cat is running"); } } public void testSetExpressions2() { Foo foo = new Foo(); Collection col = new ArrayList(); final Serializable fooExpr = compileSetExpression("collectionTest"); executeSetExpression(fooExpr, foo, col); assertEquals(col, foo.getCollectionTest()); } public class Fruit { public class Apple { } } public void testInnerClassReference() { assertEquals(Fruit.Apple.class, test("import " + CoreConfidenceTests.class.getName() + "; CoreConfidenceTests.Fruit.Apple")); } public void testEdson() { assertEquals("foo", test("list = new java.util.ArrayList(); list.add(new String('foo')); list[0]")); } public void testEnumSupport() { MyInterface myInterface = new MyClass(); myInterface.setType(MyInterface.MY_ENUM.TWO, true); boolean isType = MVEL.eval("isType(org.mvel2.tests.core.res.MyInterface$MY_ENUM.ONE)", myInterface, Boolean.class); System.out.println(isType); } public void testOperatorPrecedenceOrder() { Serializable compiled = compileExpression("bean1.successful && bean2.failed || bean1.failed && bean2.successful"); Map context = new HashMap(); BeanB bean1 = new BeanB(true); BeanB bean2 = new BeanB(false); context.put("bean1", bean1); context.put("bean2", bean2); System.out.println("interpreted: " + MVEL.eval("bean1.successful && bean2.failed || bean1.failed && bean2.successful", context)); assertEquals(bean1.isSuccessful() && bean2.isFailed() || bean1.isFailed() && bean2.isSuccessful(), (boolean) executeExpression(compiled, context, Boolean.class)); } public static class BeanB { private boolean successful; public BeanB(boolean successful) { this.successful = successful; } public boolean isSuccessful() { return successful; } public boolean isFailed() { return !successful; } } public void testJIRA139() { ParserContext ctx = new ParserContext(); ctx.addImport("ReflectionUtil", ReflectionUtil.class); Serializable s = compileExpression("ReflectionUtil.getGetter('foo')", ctx); assertEquals(ReflectionUtil.getGetter("foo"), executeExpression(s)); } public void testJIRA140() { ParserContext ctx = new ParserContext(); Serializable s = compileExpression("import org.mvel2.tests.core.res.*;" + "cols = new Column[] { new Column('name', 20), new Column('age', 2) };" + "grid = new Grid(new Model(cols));", ctx); Grid g = (Grid) executeExpression(s, new HashMap()); assertEquals(g.getModel().getColumns()[0].getName(), "name"); assertEquals(g.getModel().getColumns()[0].getLength(), 20); assertEquals(g.getModel().getColumns()[1].getName(), "age"); assertEquals(g.getModel().getColumns()[1].getLength(), 2); } public void testVerifierWithIndexedProperties() { ParserContext ctx = new ParserContext(); ctx.setStrictTypeEnforcement(true); ctx.addInput("base", Base.class); Serializable s = compileExpression("base.fooMap['foo'].setName('coffee')", ctx); Map vars = new HashMap(); vars.put("base", new Base()); executeExpression(s, vars); assertEquals("coffee", ((Base) vars.get("base")).fooMap.get("foo").getName()); } public void testEmpty() { ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); Serializable s = compileExpression("list = new java.util.ArrayList(); list == empty", ctx); Map vars = new HashMap(); Boolean x = (Boolean) executeExpression(s, vars); assertNotNull(x); assertTrue(x.booleanValue()); } public void testMapsAndLists() { OptimizerFactory.setDefaultOptimizer("ASM"); ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addImport(HashMap.class); ctx.addImport(ArrayList.class); ctx.addInput("list", List.class); String expression = "m = new HashMap();\n" + "l = new ArrayList();\n" + "l.add(\"first\");\n" + "m.put(\"content\", l);\n" + "list.add(((ArrayList)m[\"content\"])[0]);"; Serializable s = compileExpression(expression, ctx); Map vars = new HashMap(); List list = new ArrayList(); vars.put("list", list); Boolean result = (Boolean) executeExpression(s, vars); assertNotNull(result); assertTrue(result); assertEquals(1, list.size()); assertEquals("first", list.get(0)); } public void testMapsAndLists2() { OptimizerFactory.setDefaultOptimizer("reflective"); ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addImport(HashMap.class); ctx.addImport(ArrayList.class); ctx.addInput("list", List.class); String expression = "m = new HashMap();\n" + "l = new ArrayList();\n" + "l.add(\"first\");\n" + "m.put(\"content\", l);\n" + "list.add(((ArrayList)m[\"content\"])[0]);"; Serializable s = compileExpression(expression, ctx); Map vars = new HashMap(); List list = new ArrayList(); vars.put("list", list); Boolean result = (Boolean) executeExpression(s, vars); assertNotNull(result); assertTrue(result); assertEquals(1, list.size()); assertEquals("first", list.get(0)); } public void testReturnBoolean() { String ex = "list = new java.util.ArrayList(); return list != null"; ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); Serializable s = compileExpression(ex, ctx); assertEquals(true, executeExpression(s, new HashMap())); } public void testComaProblemStrikesBack() { String ex = "a.explanation = \"There is a coma, in here\""; ParserContext ctx = new ParserContext(); ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx); Serializable s = compiler.compile(); Base a = new Base(); Map<String, Object> variables = new HashMap<String, Object>(); variables.put("a", a); executeExpression(s, variables); assertEquals("There is a coma, in here", a.data); } public static interface Services { public final static String A_CONST = "Hello World"; public void log(String text); } public void testStringConcatenation() { // debugging MVEL code, it seems that MVEL 'thinks' that the result of the expression: // "Drop +5%: "+$sb+" avg: $"+$av+" price: $"+$pr // is a double, and as so, he looks for a method: // Services.log( double ); // but finds only: // Services.log( String ); // raising the error. String ex = "services.log((String) \"Drop +5%: \"+$sb+\" avg: $\"+$av+\" price: $\"+$pr );"; ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addInput("$sb", String.class); ctx.addInput("$av", double.class); ctx.addInput("$pr", double.class); ctx.addInput("services", Services.class); try { ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx); compiler.compile(); } catch (Throwable e) { e.printStackTrace(); fail("Should not raise exception: " + e.getMessage()); } } public void testStringConcatenation2() { String ex = "services.log( $cheese + \" some string \" );"; ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addInput("$cheese", Cheese.class); ctx.addInput("services", Services.class); try { ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx); compiler.compile(); } catch (Throwable e) { e.printStackTrace(); fail("Should not raise exception: " + e.getMessage()); } } public void testStringConcatenation3() { // BUG: return type of the string concatenation is inferred as double instead of String String ex = "services.log($av + \"Drop +5%: \"+$sb+\" avg: $\"+percent($av)+\" price: $\"+$pr );"; ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.setStrictTypeEnforcement(true); ctx.addInput("$sb", String.class); ctx.addInput("$av", double.class); ctx.addInput("$pr", double.class); ctx.addInput("services", Services.class); ctx.addImport("percent", MVEL.getStaticMethod(String.class, "valueOf", new Class[]{double.class})); try { Serializable compiledExpression = MVEL.compileExpression(ex, ctx); Services services = new Services() { public void log(String text) { } }; Map<String, Object> vars = new HashMap<String, Object>(); vars.put("services", services); vars.put("$sb", "RHT"); vars.put("$av", 15.0); vars.put("$pr", 10.0); MVEL.executeExpression(compiledExpression, vars); } catch (Throwable e) { e.printStackTrace(); fail("Should not raise exception: " + e.getMessage()); } } public void testMapsWithVariableAsKey() { String ex = "aMap[aKey] == 'aValue'"; ParserContext ctx = new ParserContext(); ctx.setStrongTyping(false); ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx); compiler.setVerifyOnly(true); compiler.compile(); Set<String> requiredInputs = compiler.getParserContextState().getInputs().keySet(); assertTrue(requiredInputs.contains("aMap")); assertTrue(requiredInputs.contains("aKey")); } public void testMapsWithVariableAsKey2() { String ex = "objectKeyMaptributes[$aPerson] == foo"; Foo foo = new Foo(); Person person = new Person(); person.setObjectKeyMaptributes(new HashMap<Object, Foo>()); person.getObjectKeyMaptributes().put(person, foo); Map<String, Class> inputs = new HashMap<String, Class>(); inputs.put("this", Person.class); inputs.put("foo", Foo.class); inputs.put("$aPerson", Person.class); ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.setInputs(inputs); Serializable expression = MVEL.compileExpression(ex, ctx); Map<String, Object> variables = new HashMap<String, Object>(); variables.put("foo", foo); variables.put("$aPerson", person); Boolean result = (Boolean) MVEL.executeExpression(expression, person, variables); assertTrue(result); } public static void testProjectionUsingThis() { Set records = new HashSet(); for (int i = 0; i < 53; i++) { Bean2 record = new Bean2(i); records.add(record); } Object result = MVEL.eval("(_prop in this)", records); System.out.println("result: " + result); } public static final class Bean2 { public final int _prop; public Bean2(int prop_) { _prop = prop_; } public int getProp() { return _prop; } public String toString() { return Integer.toString(_prop); } } public void testUnaryOpNegation1() { assertEquals(false, test("!new Boolean(true)")); } public void testUnaryOpNegation2() { assertEquals(true, test("!isdef _foozy_")); } public class Az { public void foo(String s) { } } public class Bz extends Az { } public void testJIRA151() { OptimizerFactory.setDefaultOptimizer(OptimizerFactory.SAFE_REFLECTIVE); Bz b = new Bz(); ParserContext context = new ParserContext(); Object expression = MVEL.compileExpression("a.foo(value)", context); Map<String, Object> variables = new HashMap<String, Object>(); variables.put("a", b); variables.put("value", 123); for (int i = 0; i < 100; i++) { System.out.println("i: " + i); System.out.flush(); executeExpression(expression, variables); } } public void testJIRA151b() { OptimizerFactory.setDefaultOptimizer("ASM"); Bz b = new Bz(); ParserContext context = new ParserContext(); Object expression = MVEL.compileExpression("a.foo(value)", context); Map<String, Object> variables = new HashMap<String, Object>(); variables.put("a", b); variables.put("value", 123); for (int i = 0; i < 100; i++) { System.out.println("i: " + i); System.out.flush(); executeExpression(expression, variables); } } public void testJIRA153() { assertEquals(false, MVEL.eval("!(true)")); assertEquals(false, executeExpression(MVEL.compileExpression("!(true)"))); } public void testMultipleNegations() { assertEquals(true, executeExpression(MVEL.compileExpression("!false"))); assertEquals(false, executeExpression(MVEL.compileExpression("!!false"))); assertEquals(true, executeExpression(MVEL.compileExpression("!!!false"))); assertEquals(false, executeExpression(MVEL.compileExpression("!!!!false"))); } public void testJIRA154() { Map m = createTestMap(); m.put("returnTrue", MVEL.getStaticMethod(CoreConfidenceTests.class, "returnTrue", new Class[0])); assertEquals(false, MVEL.eval("!returnTrue()", m)); } public void testJIRA154b() { ParserContext pctx = new ParserContext(); pctx.addImport("returnTrue", MVEL.getStaticMethod(CoreConfidenceTests.class, "returnTrue", new Class[0])); assertEquals(false, executeExpression(MVEL.compileExpression("!(returnTrue())", pctx))); } public void testJIRA155() { ParserContext pctx = new ParserContext(); pctx.addImport("returnTrue", MVEL.getStaticMethod(CoreConfidenceTests.class, "returnTrue", new Class[0])); assertEquals(true, executeExpression(MVEL.compileExpression("!true || returnTrue()", pctx))); } public void testJIRA155b() { ParserContext pctx = new ParserContext(); pctx.addImport("returnTrue", MVEL.getStaticMethod(CoreConfidenceTests.class, "returnTrue", new Class[0])); assertEquals(true, executeExpression(MVEL.compileExpression("!(!true || !returnTrue())", pctx))); } public void testJIRA156() throws Throwable { ClassProvider provider = new ClassProvider(); provider.getPrivate().foo(); PublicClass.class.getMethod("foo").invoke(provider.getPrivate()); String script = "provider.getPrivate().foo()"; HashMap<String, Object> vars = new HashMap<String, Object>(); vars.put("provider", provider); MVEL.eval(script, vars); } public void testJIRA156b() throws Throwable { ClassProvider provider = new ClassProvider(); provider.getPrivate().foo(); PublicClass.class.getMethod("foo").invoke(provider.getPrivate()); String script = "provider.getPrivate().foo()"; Serializable s = MVEL.compileExpression(script); HashMap<String, Object> vars = new HashMap<String, Object>(); vars.put("provider", provider); OptimizerFactory.setDefaultOptimizer("reflective"); executeExpression(s, vars); OptimizerFactory.setDefaultOptimizer("ASM"); executeExpression(s, vars); } public void testJIRA156c() throws Throwable { ClassProvider provider = new ClassProvider(); provider.getPublic().foo(); PublicClass.class.getMethod("foo").invoke(provider.getPublic()); String script = "provider.getPublic().foo()"; Serializable s = MVEL.compileExpression(script); HashMap<String, Object> vars = new HashMap<String, Object>(); vars.put("provider", provider); MVEL.eval(script, vars); OptimizerFactory.setDefaultOptimizer("reflective"); executeExpression(s, vars); OptimizerFactory.setDefaultOptimizer("ASM"); executeExpression(s, vars); } public static boolean returnTrue() { return true; } public static class TestHelper { public static void method(int id, Object[] arr) { System.out.println(id + " -> " + arr.length); } public static void method(Object obj1, Object obj2) { System.out.println(obj1 + "-> " + obj2); } public static Calendar minDate() { return Calendar.getInstance(); } public static Calendar maxDate() { return Calendar.getInstance(); } } public static class Fooz { public Fooz(String id) { } } public void testArray() { String ex = " TestHelper.method(1, new String[]{\"a\", \"b\"});\n" + " TestHelper.method(2, new String[]{new String(\"a\"), new String(\"b\")});\n" + " TestHelper.method(3, new Fooz[]{new Fooz(\"a\"), new Fooz(\"b\")});"; ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addImport(TestHelper.class); ctx.addImport(Fooz.class); ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx); OptimizerFactory.setDefaultOptimizer("ASM"); CompiledExpression expr = compiler.compile(); executeExpression(expr); OptimizerFactory.setDefaultOptimizer("reflective"); expr = compiler.compile(); executeExpression(expr); } public void testArray2() { String ex = " TestHelper.method(1, {\"a\", \"b\"});\n" + " TestHelper.method(2, {new String(\"a\"), new String(\"b\")});\n" + " TestHelper.method(3, {new Fooz(\"a\"), new Fooz(\"b\")});"; ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addImport(TestHelper.class); ctx.addImport(Fooz.class); ExpressionCompiler compiler = new ExpressionCompiler(ex, ctx); OptimizerFactory.setDefaultOptimizer("ASM"); CompiledExpression expr = compiler.compile(); executeExpression(expr); OptimizerFactory.setDefaultOptimizer("reflective"); expr = compiler.compile(); executeExpression(expr); } public void testJIRA166() { Object v = MVEL.eval("import java.util.regex.Matcher; import java.util.regex.Pattern;" + " if (Pattern.compile(\"hoge\").matcher(\"hogehogehoge\").find()) { 'foo' } else { 'bar' }", new HashMap()); assertEquals("foo", v); } public static class Beano { public String getProperty1() { return null; } public boolean isProperty2() { return true; } public boolean isProperty3() { return false; } } public void testJIRA167() { Map context = new HashMap(); context.put("bean", new Beano()); MVEL.eval("bean.property1==null?bean.isProperty2():bean.isProperty3()", context); } public void testJIRA168() { boolean before = MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL; try { Map<String, Object> st = new HashMap<String, Object>(); st.put("__fact__", new ArrayList()); st.put("__expected__", 0); String expressionNaked = "__fact__.size == __expected__"; String expressionNonNaked = "__fact__.size() == __expected__"; MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true; // the following works fine ParserContext ctx = new ParserContext(); for (Map.Entry<String, Object> entry : st.entrySet()) { ctx.addInput(entry.getKey(), entry.getValue().getClass()); } CompiledExpression expr = new ExpressionCompiler(expressionNaked, ctx).compile(); Boolean result = (Boolean) executeExpression(expr, st); assertTrue(result); // the following works fine result = (Boolean) MVEL.eval(expressionNonNaked, st); assertTrue(result); // the following fails result = (Boolean) MVEL.eval(expressionNaked, st); assertTrue(result); } finally { MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = before; } } public void testJIRA170() { OptimizerFactory.setDefaultOptimizer("reflective"); List<Integer> staticDispatch = Arrays.asList(2, 1, 0); List<Integer> multimethodDispatch = Arrays.asList(3, 2, 1); // invokeJIRA170("Dynamic", ctxJIRA170(false, false), varsJIRA170(), multimethodDispatch); // invokeJIRA170("Strict", ctxJIRA170(true, false), varsJIRA170(), multimethodDispatch); invokeJIRA170("Strong", ctxJIRA170(false, true), varsJIRA170(), staticDispatch); } public void testJIRA170b() { OptimizerFactory.setDefaultOptimizer("ASM"); List<Integer> staticDispatch = Arrays.asList(2, 1, 0); List<Integer> multimethodDispatch = Arrays.asList(3, 2, 1); // invokeJIRA170("Dynamic", ctxJIRA170(false, false), varsJIRA170(), multimethodDispatch); // invokeJIRA170("Strict", ctxJIRA170(true, false), varsJIRA170(), multimethodDispatch); invokeJIRA170("Strong", ctxJIRA170(false, true), varsJIRA170(), staticDispatch); } public void invokeJIRA170(String name, ParserContext pctx, Map<String, ?> vars, Collection<Integer> expected) { Serializable expression = MVEL.compileExpression("x.remove((Object) y); x ", pctx); Object result = executeExpression(expression, vars); assertTrue(String.format("%s Expected %s, Got %s", name, expected, result), expected.equals(result)); result = executeExpression(expression, vars); assertTrue(String.format("%s Expected %s, Got %s", name, expected, result), expected.equals(result)); } private Map<String, ?> varsJIRA170() { Map<String, Object> vars = new HashMap<String, Object>(); vars.put("x", new ArrayList<Integer>(Arrays.asList(3, 2, 1, 0))); vars.put("y", 3); return vars; } private ParserContext ctxJIRA170(boolean strictTypeEnforcement, boolean strongTyping) { ParserContext ctx = new ParserContext(); // ctx.setStrictTypeEnforcement(strictTypeEnforcement); ctx.setStrongTyping(strongTyping); ctx.addInput("x", Collection.class, new Class[]{Integer.class}); ctx.addInput("y", Integer.class); return ctx; } public static class JIRA167Step { public String getParent() { return null; } } public static class JIRA167Node { public boolean isServer() { return true; } } public void testJIRA167b() { Map context = new HashMap(); context.put("current", new JIRA167Step()); context.put("node", new JIRA167Node()); MVEL.eval("current.parent==null?node.isServer():(node==current.parent.node)", context); } public void testJIRA167c() { MVEL.eval("true?true:(false)"); } public void testJIRA176() { Map innerMap = new HashMap(); innerMap.put("testKey[MyValue=newValue]", "test"); Map vars = new HashMap(); vars.put("mappo", innerMap); assertEquals("test", MVEL.eval("mappo['testKey[MyValue=newValue]']", vars)); } public void testJIRA176b() { Map innerMap = new HashMap(); innerMap.put("testKey[MyValue=newValue]", "test"); Map vars = new HashMap(); vars.put("mappo", innerMap); Serializable s = MVEL.compileExpression("mappo['testKey[MyValue=newValue]']"); OptimizerFactory.setDefaultOptimizer("reflective"); assertEquals("test", executeExpression(s, vars)); s = MVEL.compileExpression("mappo['testKey[MyValue=newValue]']"); OptimizerFactory.setDefaultOptimizer("ASM"); assertEquals("test", executeExpression(s, vars)); } public void testRandomSomething() { Foo foo = new Foo(); foo.setName("foo1"); Foo foo2 = new Foo(); foo2.setName("foo2"); MVEL.setProperty(foo, "name", 5); Serializable s = MVEL.compileExpression("name.toUpperCase()", ParserContext.create().stronglyTyped().withInput("name", String.class)); Object _return = executeExpression(s, foo); System.out.println("returned value: " + String.valueOf(_return)); _return = executeExpression(s, foo2); System.out.println("returned value: " + String.valueOf(_return)); } public static class ProcessManager { public void startProcess(String name, Map<String, Object> variables) { System.out.println("Process started"); } } public static class KnowledgeRuntimeHelper { public ProcessManager getProcessManager() { return new ProcessManager(); } } public void testDeepMethodNameResolution() { String expression = "variables = [ \"symbol\" : \"RHT\" ]; \n" + "drools.getProcessManager().startProcess(\"id\", variables );"; // third pass ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addInput("drools", KnowledgeRuntimeHelper.class); Map vars = new HashMap(); vars.put("drools", new KnowledgeRuntimeHelper()); Serializable expr = MVEL.compileExpression(expression, ctx); executeExpression(expr, vars); } public void testJIRA183() { String exp1 = "int end = 'attribute'.indexOf('@'); if(end == -1)" + " { end = 'attribute'.length()} 'attribute'.substring(0, end);"; Object val1 = MVEL.eval(exp1, new HashMap<String, Object>()); String exp2 = "int end = 'attribute'.indexOf('@'); if(end == -1)" + " { end = 'attribute'.length() } 'attribute'.substring(0, end);"; Object val2 = MVEL.eval(exp2, new HashMap<String, Object>()); } public void testContextAssignments() { Foo foo = new Foo(); MVEL.eval("this.name = 'bar'", foo); assertEquals("bar", foo.getName()); } public void testMVEL187() { ParserContext context = new ParserContext(); context.addPackageImport("test"); context.addInput("outer", Outer.class); Object compiled = MVEL.compileExpression( "outer.getInner().getValue()", context); Map<String, Object> vars = new HashMap<String, Object>(); vars.put("outer", new Outer()); VariableResolverFactory varsResolver = new MapVariableResolverFactory(vars); assertEquals(2, executeExpression(compiled, varsResolver)); } public void testMVEL190() { ParserContext context = new ParserContext(); context.addImport(Ship.class); context.addImport(MapObject.class); context.addInput("obj", MapObject.class); Object compiled = MVEL.compileExpression( "((Ship) obj).getName()", context); Map<String, Object> vars = new HashMap<String, Object>(); vars.put("obj", new Ship()); VariableResolverFactory varsResolver = new MapVariableResolverFactory(vars); System.out.println( executeExpression(compiled, varsResolver)); } public void testMethodScoring() { OptimizerFactory.setDefaultOptimizer("ASM"); ParserConfiguration pconf = new ParserConfiguration(); for (Method m : StaticMethods.class.getMethods()) { if (Modifier.isStatic(m.getModifiers())) { pconf.addImport(m.getName(), m); } } pconf.addImport("TestCase", TestCase.class); ParserContext pctx = new ParserContext(pconf); Map<String, Object> vars = new HashMap<String, Object>(); // this is successful TestCase.assertTrue(StaticMethods.is(StaticMethods.getList(java.util.Formatter.class))); // this also should be fine Serializable expr = MVEL.compileExpression("TestCase.assertTrue( is( getList( java.util.Formatter ) ) )", pctx); executeExpression(expr, vars); } public void testMethodWithNegativeIntParamMVEL313() { assertTrue((Boolean) runSingleTest("ord(true,-1)")); } public static class StaticMethods { public static <T> boolean is(List<T> arg) { return true; } public static boolean is(Collection arg) { throw new RuntimeException("Wrong method called"); } public static List<Object> getList(Class<?> arg) { ArrayList<Object> result = new ArrayList<Object>(); result.add(arg); return result; } public static String throwException() { throw new RuntimeException("this should throw an exception"); } } public void testSetterViaDotNotation() { TestClass tc = new TestClass(); tc.getExtra().put("test", "value"); ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); String expression = "extra.test"; Serializable compiled = MVEL.compileSetExpression(expression, ctx); MVEL.executeSetExpression(compiled, tc, "value2"); assertEquals("value2", tc.getExtra().get("test")); } public void testSetterViaMapNotation() { TestClass tc = new TestClass(); tc.getExtra().put("test", "value"); ParserContext ctx = new ParserContext(); ctx.withInput("this", TestClass.class); ctx.setStrongTyping(true); String expression = "extra[\"test\"]"; Serializable compiled = MVEL.compileSetExpression(expression, tc.getClass(), ctx); MVEL.executeSetExpression(compiled, tc, "value3"); assertEquals("value3", tc.getExtra().get("test")); } public void testGetterViaDotNotation() { TestClass tc = new TestClass(); tc.getExtra().put("test", "value"); Map vars = new HashMap(); vars.put("tc", tc); ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addInput("tc", tc.getClass()); String expression = "tc.extra.test"; Serializable compiled = MVEL.compileExpression(expression, ctx); String val = (String) executeExpression(compiled, vars); assertEquals("value", val); } public void testGetterViaMapNotation() { TestClass tc = new TestClass(); tc.getExtra().put("test", "value"); Map vars = new HashMap(); vars.put("tc", tc); ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addInput("tc", tc.getClass()); String expression = "tc.extra[\"test\"]"; Serializable compiled = MVEL.compileExpression(expression, ctx); String val = (String) executeExpression(compiled, vars); assertEquals("value", val); } public void testGetterViaMapGetter() { TestClass tc = new TestClass(); tc.getExtra().put("test", "value"); Map vars = new HashMap(); vars.put("tc", tc); ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addInput("tc", tc.getClass()); String expression = "tc.extra.get(\"test\")"; Serializable compiled = MVEL.compileExpression(expression, ctx); String val = (String) executeExpression(compiled, vars); assertEquals("value", val); } public void testJIRA209() { Map vars = new LinkedHashMap(); vars.put("bal", new BigDecimal("999.99")); String[] testCases = { // "bal < 100 or bal > 200", // "bal < 100 || bal > 200", "bal > 200 or bal < 100", "bal > 200 || bal < 100", "bal < 100 and bal > 200", "bal < 100 && bal > 200", "bal > 200 and bal < 100", "bal > 200 && bal < 100" }; Object val1, val2; for (String expr : testCases) { System.out.println("Evaluating '" + expr + "': ......"); val1 = MVEL.eval(expr, vars); assertNotNull(val1); Serializable compiled = MVEL.compileExpression(expr); val2 = executeExpression(compiled, vars); assertNotNull(val2); assertEquals("expression did not evaluate correctly: " + expr, val1, val2); } } public void testBigDecimalOutput() { String str = "import java.math.BigDecimal; BigDecimal test = new BigDecimal(\"50000\"); System.out.println(test / new BigDecimal(\"1.13\"));"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.setStrictTypeEnforcement(true); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); MVEL.executeExpression(stmt, new HashMap()); } public void testConstructor() { String ex = " TestHelper.method(new Person('bob', 30), new Person('mark', 40, 999, 55, 10));\n"; ParserContext ctx = new ParserContext(); ctx.setStrongTyping(true); ctx.addImport(TestHelper.class); ctx.addImport(Person.class); // un-comment the following line to see how MVEL is converting the int argument 40 into a // string and then executing the wrong constructor on the Person class try { MVEL.compileExpression(ex, ctx); fail("Constructor should not have been found."); } catch (CompileException e) { // yay. } // fail( "The Person constructor used in the expression does not exist, so an error should have been raised during compilation." ); } public void testAmbiguousGetName() { Map<String, Object> vars = createTestMap(); vars.put("Foo244", Foo.class); OptimizerFactory.setDefaultOptimizer("ASM"); Serializable s = MVEL.compileExpression("foo.getClass().getName()"); System.out.println(MVEL.executeExpression(s, vars)); s = MVEL.compileExpression("Foo244.getName()"); System.out.println(MVEL.executeExpression(s, vars)); } public void testBindingNullToPrimitiveTypes() { Map<String, Object> vars = createTestMap(); ((Foo) vars.get("foo")).setCountTest(10); OptimizerFactory.setDefaultOptimizer("reflective"); Serializable s = MVEL.compileSetExpression("foo.countTest"); MVEL.executeSetExpression(s, vars, null); assertEquals(((Foo) vars.get("foo")).getCountTest(), 0); OptimizerFactory.setDefaultOptimizer("ASM"); s = MVEL.compileSetExpression("foo.countTest"); MVEL.executeSetExpression(s, vars, null); assertEquals(((Foo) vars.get("foo")).getCountTest(), 0); MVEL.executeSetExpression(s, vars, null); assertEquals(((Foo) vars.get("foo")).getCountTest(), 0); } public void testBindingNullToPrimitiveTypes2() { Map<String, Object> vars = createTestMap(); ((Foo) vars.get("foo")).setCountTest(10); OptimizerFactory.setDefaultOptimizer("reflective"); Serializable s = MVEL.compileSetExpression("foo.boolTest"); MVEL.executeSetExpression(s, vars, null); assertFalse(((Foo) vars.get("foo")).isBoolTest()); OptimizerFactory.setDefaultOptimizer("ASM"); s = MVEL.compileSetExpression("foo.boolTest"); MVEL.executeSetExpression(s, vars, null); assertFalse(((Foo) vars.get("foo")).isBoolTest()); MVEL.executeSetExpression(s, vars, null); assertFalse(((Foo) vars.get("foo")).isBoolTest()); } public void testBindingNullToPrimitiveTypes3() { Map<String, Object> vars = createTestMap(); ((Foo) vars.get("foo")).setCharTest('a'); OptimizerFactory.setDefaultOptimizer("reflective"); Serializable s = MVEL.compileSetExpression("foo.charTest"); MVEL.executeSetExpression(s, vars, null); assertEquals(((Foo) vars.get("foo")).getCharTest(), 0); OptimizerFactory.setDefaultOptimizer("ASM"); s = MVEL.compileSetExpression("foo.charTest"); MVEL.executeSetExpression(s, vars, null); assertEquals(((Foo) vars.get("foo")).getCharTest(), 0); MVEL.executeSetExpression(s, vars, null); assertEquals(((Foo) vars.get("foo")).getCharTest(), 0); } public void testBindingNullToPrimitiveTypes4() { Map<String, Object> vars = createTestMap(); ((Foo) vars.get("foo")).charTestFld = 'a'; OptimizerFactory.setDefaultOptimizer("reflective"); Serializable s = MVEL.compileSetExpression("foo.charTestFld"); MVEL.executeSetExpression(s, vars, null); assertEquals(((Foo) vars.get("foo")).charTestFld, 0); OptimizerFactory.setDefaultOptimizer("ASM"); s = MVEL.compileSetExpression("foo.charTestFld"); MVEL.executeSetExpression(s, vars, null); assertEquals(((Foo) vars.get("foo")).charTestFld, 0); MVEL.executeSetExpression(s, vars, null); assertEquals(((Foo) vars.get("foo")).charTestFld, 0); } public void testBindListToArray() { Map<String, Object> vars = createTestMap(); ArrayList<String> list = new ArrayList<String>(); list.add("a"); list.add("b"); list.add("c"); OptimizerFactory.setDefaultOptimizer("reflective"); Serializable s = MVEL.compileSetExpression("foo.charArray"); MVEL.executeSetExpression(s, vars, list); assertEquals(((Foo) vars.get("foo")).getCharArray().length, 3); } public void testBindListToMultiArray() { Map<String, Object> vars = createTestMap(); ArrayList<List<String>> list = new ArrayList<List<String>>(); List<String> l1 = new ArrayList<String>(); l1.add("a"); l1.add("b"); l1.add("c"); List<String> l2 = new ArrayList<String>(); l2.add("d"); l2.add("e"); l2.add("f"); List<String> l3 = new ArrayList<String>(); l3.add("g"); l3.add("h"); l3.add("i"); list.add(l1); list.add(l2); list.add(l3); OptimizerFactory.setDefaultOptimizer("reflective"); Serializable s = MVEL.compileSetExpression("foo.charArrayMulti"); MVEL.executeSetExpression(s, vars, list); Foo foo = (Foo) vars.get("foo"); assertEquals(foo.getCharArrayMulti().length, 3); assertEquals(foo.getCharArrayMulti()[2][2], 'i'); } public void testMVEL224() { ParserContext ctx = new ParserContext(); MVEL.compileExpression("(pin == 1)", ctx); } public static class A221 { public B221 b; } public static class B221 { public String c = "something"; } public void testMVEL221() { A221 a1 = new A221(); a1.b = new B221(); A221 a2 = new A221(); OptimizerFactory.setDefaultOptimizer("ASM"); String expression = "this.?b.c"; Serializable compiledExpression = MVEL.compileExpression(expression); assertEquals(null, MVEL.executeExpression(compiledExpression, a2, String.class)); assertEquals("something", MVEL.executeExpression(compiledExpression, a1, String.class)); OptimizerFactory.setDefaultOptimizer("reflective"); compiledExpression = MVEL.compileExpression(expression); assertEquals(null, MVEL.executeExpression(compiledExpression, a2, String.class)); assertEquals("something", MVEL.executeExpression(compiledExpression, a1, String.class)); } public void testMVEL222() throws IOException { String script = "for (int i= 0; i < 10; i++ ){ values[i] = 1.0; }"; Map<String, Object> scriptVars = new HashMap<String, Object>(); double[] values = new double[10]; scriptVars.put("values", values); Serializable expression = MVEL.compileExpression(script); for (int i = 0; i < 6; i++) { scriptVars.put("values", values); MVEL.executeExpression(expression, scriptVars); } } public void testMVEL238() throws IOException { String expr = new String(loadFromFile(new File("src/test/java/org/mvel2/tests/MVEL238.mvel"))); Serializable s = MVEL.compileExpression(expr); System.out.println(MVEL.executeExpression(s, new HashMap())); System.out.println(MVEL.executeExpression(s, new HashMap())); } public void testParsingRegression() { String expr = "if (false) {System.out.println(\" foo\")} else {System.out.println(\" bar\")}"; MVEL.eval(expr); } public static class StaticClassWithStaticMethod { public static String getString() { return "hello"; } } // public void testStaticImportWithWildcard() { // // this isn't supported yet // assertEquals("hello", // test("import_static " + getClass().getName() + ".StaticClassWithStaticMethod.*; getString()")); // } public void testArrayLength() { ParserContext context = new ParserContext(); context.setStrongTyping(true); context.addInput("x", String[].class); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression("x.length", context); } public void testEmptyConstructorWithSpace() throws Exception { ParserConfiguration pconf = new ParserConfiguration(); pconf.addImport("getString", StaticClassWithStaticMethod.class.getMethod("getString", null)); String text = "getString( )"; ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.setStrictTypeEnforcement(true); MVEL.compileExpression(text, pctx); } public void testJavaLangImport() throws Exception { String s = "Exception e = null;"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); MVEL.compileExpression(s, pctx); } public void testContextFieldNotFound() { String str = "'stilton'.equals( type );"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.addInput("this", Cheese.class); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); MVEL.executeExpression(stmt, new Cheese(), new HashMap()); } public void testVarArgs() throws Exception { ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); MVEL.analyze("String.format(\"\");", parserContext); } public void testOperatorPrecedence() throws IOException { String script = "list = [1, 2, 3]; x = 10; list contains x || x == 20"; Serializable expression = MVEL.compileExpression(script); Object result = MVEL.executeExpression(expression, new HashMap()); assertEquals(Boolean.FALSE, result); } public void testNestedEnum() throws Exception { // assertEquals(Triangle.Foo.class, MVEL.analyze("import " + Triangle.class.getCanonicalName() +"; Triangle.Foo.OBTUSE" , ParserContext.create())); // Serializable o = MVEL.compileExpression( "import " + Triangle.class.getCanonicalName() +"; Triangle.Foo.OBTUSE" ); // assertEquals( Triangle.Foo.OBTUSE, MVEL.executeExpression(o, new HashMap()) ); MVEL.eval("import " + Triangle.class.getCanonicalName() + "; Triangle.Foo.OBTUSE", new HashMap()); } public void testNestedNumInMapKey() { String str = "objectKeyMaptributes[Triangle.Foo.OBTUSE]"; ParserConfiguration pconf = new ParserConfiguration(); pconf.addImport("Triangle", Triangle.class); ParserContext pctx = new ParserContext(pconf); pctx.addInput("this", Person.class); pctx.setStrongTyping(true); Foo foo = new Foo(); Person p = new Person(); Map<Object, Foo> map = new HashMap<Object, Foo>(); map.put(Triangle.Foo.OBTUSE, foo); p.setObjectKeyMaptributes(map); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); Object o = MVEL.executeExpression(stmt, p, new HashMap()); } public void testNestedClassWithNestedGenericsOnNakedMethod() { String str = "deliveries.size"; MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.addInput("this", Triangle.class); pctx.setStrongTyping(true); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); assertEquals(Integer.valueOf(0), (Integer) MVEL.executeExpression(stmt, new Triangle(), new HashMap())); str = "deliveries.size == 0"; stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); assertTrue((Boolean) MVEL.executeExpression(stmt, new Triangle(), new HashMap())); MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = false; } public static class Triangle { public static enum Foo { INCOMPLETE, UNCLASSIFIED, EQUILATERAL, ISOSCELES, RECTANGLED, ISOSCELES_RECTANGLED, ACUTE, OBTUSE; } private List<Map<String, Object>> deliveries = new ArrayList<Map<String, Object>>(); public List<Map<String, Object>> getDeliveries() { return deliveries; } private Object objLabel = "Triangle"; private String strLabel = "Triangle"; private Double doubleVal = 29.0; public Object getObjLabel() { return objLabel; } public void setObjLabel(Object objLabel) { this.objLabel = objLabel; } public String getStrLabel() { return strLabel; } public void setStrLabel(String strLabel) { this.strLabel = strLabel; } public Double getDoubleVal() { return doubleVal; } public void setDoubleVal(Double doubleVal) { this.doubleVal = doubleVal; } } public void testStrictModeAddAll() { String str = "list.addAll( o );"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.addInput("o", Object.class); pctx.addInput("list", ArrayList.class); try { ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); fail("This should not compileShared, as o is not of a type Collection"); } catch (Exception e) { } } public void testNestedEnumFromJar() throws ClassNotFoundException, SecurityException, NoSuchFieldException { String expr = "EventRequest.Status.ACTIVE"; // creating a classloader for the jar URL resource = getClass().getResource("/eventing-example.jar"); assertNotNull(resource); URLClassLoader loader = new URLClassLoader(new URL[]{resource}, getClass().getClassLoader()); // loading the class to prove it works Class<?> er = loader.loadClass("org.drools.examples.eventing.EventRequest"); assertNotNull(er); assertEquals("org.drools.examples.eventing.EventRequest", er.getCanonicalName()); // getting the value of the enum to prove it works: Class<?> st = er.getDeclaredClasses()[0]; assertNotNull(st); Field active = st.getField("ACTIVE"); assertNotNull(active); // now, trying with MVEL ParserConfiguration pconf = new ParserConfiguration(); pconf.setClassLoader(loader); pconf.addImport(er); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); Serializable compiled = MVEL.compileExpression(expr, pctx); Object result = MVEL.executeExpression(compiled); assertNotNull(result); } public void testContextObjMethodCall() { String str = "getName() == \"bob\""; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.addInput("this", Bar.class); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); Bar ctx = new Bar(); ctx.setName("bob"); Boolean result = (Boolean) MVEL.executeExpression(stmt, ctx); assertTrue(result); } public void testMapAccessWithNestedMethodCall() { String str = "map[aMethod(1)] == \"one\""; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.addInput("this", POJO.class); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); POJO ctx = new POJO(); ctx.getMap().put("1", "one"); Boolean result = (Boolean) MVEL.executeExpression(stmt, ctx); assertTrue(result); } public void testMapAccessWithNestedProperty() { String str = "map[key] == \"one\""; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.addInput("this", POJO.class); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); POJO ctx = new POJO(); ctx.getMap().put("1", "one"); Boolean result = (Boolean) MVEL.executeExpression(stmt, ctx); assertTrue(result); } public void testArrays() { String str = "Object[] a = new Object[3]; a[0] = \"a\"; a[1] = \"b\"; a[2] = \"c\"; System.out.println(java.util.Arrays.toString(a));"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); MVEL.executeExpression(stmt, new HashMap()); } public void testFullyQualifiedEnums() { String str = "System.out.println( STATIC_ENUM.FOO ); \n" + "System.out.println( org.mvel2.tests.core.res.MyInterface$STATIC_ENUM.BAR );\n" + "System.out.println( org.mvel2.tests.core.res.MyInterface.MyInnerInterface.INNER_STATIC_ENUM.BAR );\n" + "System.out.println( RoundingMode.UP );\n" + "System.out.println( java.math.RoundingMode.DOWN );"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.addInput("this", MyInterface.class); pctx.addImport(MyInterface.STATIC_ENUM.class); pctx.addImport(java.math.RoundingMode.class); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); } public void testGenericsMap() throws Exception { try { String str = "triangle.deliveries[0].containsKey( \"x\" )"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.addInput("triangle", Triangle.class); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); } catch (Exception e) { // it should not raise CCE e.printStackTrace(); throw e; } } public void testWithInsideBlock() { String str = "Foo f = new Foo(); with(f) { setBoolTest( true ) }; f.isBoolTest()"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.addInput("this", Bar.class); pctx.addImport(Foo.class); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); Bar ctx = new Bar(); Boolean result = (Boolean) MVEL.executeExpression(stmt, ctx, new HashMap()); assertTrue(result); } public void testMethodCallWithSpaces() { String[] str = new String[]{ "Foo f = new Foo(); f.setBoolTest( true ) ; f.isBoolTest()", "Foo f = new Foo(); f . setBoolTest( true ) ; f.isBoolTest()", "Foo f = new Foo(); f. setBoolTest( true ) ; f.isBoolTest()", "Foo f = new Foo(); f .setBoolTest( true ) ; f.isBoolTest()", "Foo f = new Foo(); f.boolTest = true ; f.isBoolTest()", "Foo f = new Foo(); f . boolTest = true ; f.isBoolTest()", "Foo f = new Foo(); f. boolTest = true ; f.isBoolTest()", "Foo f = new Foo(); f .boolTest = true ; f.isBoolTest()" }; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.addInput("this", Bar.class); pctx.addImport(Foo.class); List<String> errors = new ArrayList<String>(); for (String s : str) { try { ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(s, pctx); Bar ctx = new Bar(); Boolean result = (Boolean) MVEL.executeExpression(stmt, ctx, new HashMap()); assertTrue(result); } catch (Exception e) { e.printStackTrace(); errors.add("**** Error on expression: " + s + "\n" + e.getMessage()); } } assertTrue(errors.toString(), errors.isEmpty()); } public void testInlineConstructor() { String str = "cheese = new Cheese().{ type = $c.type };"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); pctx.addInput("$c", Cheese.class); pctx.addImport(Cheese.class); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); Cheese $c = new Cheese(); $c.setType("stilton"); Map<String, Object> vars = new HashMap<String, Object>(); vars.put("$c", $c); Cheese cheese = (Cheese) MVEL.executeExpression(stmt, vars); assertEquals("stilton", cheese.getType()); } public void testStrTriangleEqualsEquals() { MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true; try { ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.addInput("this", Triangle.class); pctx.setStrongTyping(true); String str = "this.strLabel == this"; try { ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); fail("should have failed"); } catch (CompileException e) { System.out.println(); return; } } finally { MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = false; } } //public void testSysoutNullVariable() { // // Create our root Map object // Map<String, String> map = new HashMap<String, String>(); // map.put("foo", null); // // VariableResolverFactory factory = new MapVariableResolverFactory(new HashMap<String, Object>()); // factory.createVariable("this", map); // // org.mvel2.MVEL.executeExpression(org.mvel2.MVEL.compileExpression("System.out.println(foo);"), map, factory); //} public void testPackageImportEnum() { String str = "new Status( START )"; ParserConfiguration pconf = new ParserConfiguration(); pconf.addPackageImport("org.mvel2.tests.core.res"); pconf.addPackageImport("org.mvel2.tests.core.res.Status"); ParserContext context = new ParserContext(pconf); context.setStrongTyping(true); Serializable s = MVEL.compileExpression(str.trim(), context); assertEquals(new Status(Status.START), MVEL.executeExpression(s)); assertFalse(new Status(Status.STOP).equals(MVEL.executeExpression(s))); } // public void testStrDoubleEqualsEquals() { // // MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = true; // try { // ParserConfiguration pconf = new ParserConfiguration(); // ParserContext pctx = new ParserContext(pconf); // pctx.addInput("this", Triangle.class); // pctx.setStrongTyping(true); // // String str = "strLabel == doubleVal"; // // try { // ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); // } // catch (CompileException e) { // fail("should have failed"); // // } // } // finally { // MVEL.COMPILER_OPT_ALLOW_NAKED_METH_CALL = false; // } // } public void testNarrowToWideCompare() { Serializable s = MVEL.compileExpression("new String('foo') == new Object()", ParserContext.create().stronglyTyped()); assertFalse((Boolean) MVEL.executeExpression(s)); } public void testPrimitiveArray() { Map vars = new HashMap(); vars.put("array", new boolean[]{true, false}); String expression = "a = true; array contains a"; Serializable compiled = MVEL.compileExpression(expression); boolean result = (Boolean) MVEL.executeExpression(compiled, vars); assertEquals(true, result); vars = new HashMap(); vars.put("array", new int[]{1, 3, 4}); expression = "a = 2; array contains a"; compiled = MVEL.compileExpression(expression); result = (Boolean) MVEL.executeExpression(compiled, vars); assertEquals(false, result); expression = "a = 3; array contains a"; compiled = MVEL.compileExpression(expression); result = (Boolean) MVEL.executeExpression(compiled, vars); assertEquals(true, result); expression = "a = false; array contains a"; compiled = MVEL.compileExpression(expression); result = (Boolean) MVEL.executeExpression(compiled, vars); assertEquals(false, result); } public void testPrimitiveArrayWithStrongTyping() { String expression = "a = true; new boolean[] { true, false } contains a"; boolean result = (Boolean) compileAndExecuteWithStrongTyping(expression); assertEquals(true, result); expression = "a = 2; new int[] { 1, 3 } contains a"; result = (Boolean) compileAndExecuteWithStrongTyping(expression); assertEquals(false, result); expression = "a = true; array = new boolean[] { true, false }; array contains a"; result = (Boolean) compileAndExecuteWithStrongTyping(expression); assertEquals(true, result); } public void testVarArgsParams() { assertEquals(String.format("null"), runSingleTest("import org.mvel2.tests.core.res.AStatic; a = null; AStatic.process(a)")); assertEquals(String.format("hello,world,"), runSingleTest("import org.mvel2.tests.core.res.AStatic; AStatic.process(\"hello\",\"world\")")); assertEquals(String.format(""), runSingleTest("import org.mvel2.tests.core.res.AStatic; AStatic.process()")); assertEquals(String.format("null"), runSingleTest("import org.mvel2.tests.core.res.AStatic; AStatic.process(null)")); assertEquals(String.format("xxx"), runSingleTest("String.format(\"xxx\")")); assertEquals(String.format("%010d", 123), runSingleTest("String.format(\"%010d\", 123)")); assertEquals(String.format("%010d", 123), runSingleTest("a = new Object[1]; a[0] = 123; String.format(\"%010d\", a)")); assertEquals(String.format("%010d", 123), runSingleTest("a = 123; String.format(\"%010d\", a)")); assertEquals(String.format("%010d -- %010d", 123, 456), runSingleTest("a = 123; b = 456; String.format(\"%010d -- %010d\", {a, b})")); assertEquals(String.format("%010d -- %010d", 123, 456), runSingleTest("a = new Object[2]; a[0] = 123; a[1] = 456; String.format(\"%010d -- %010d\", a)")); assertEquals(String.format("%010d -- %010d", 123, 456), runSingleTest("String.format(\"%010d -- %010d\", 123, 456)")); assertEquals(String.format("%010d -- %010d", 123, 456), runSingleTest("a = 123; b = 456; String.format(\"%010d -- %010d\", a, b)")); } public static class A { public int invoke(String s1, String s2, B... bs) { return bs.length; } public static int invokeSum(int start, B... bs) { for (B b : bs) start += b.getValue(); return start; } } public static class B { private int value; public B() { } public B(int value) { this.value = value; } public int getValue() { return value; } public boolean equals(Object other) { return other != null && other instanceof B && value == ((B) other).value; } } public static class MySet { private Set<String> set = new HashSet<String>(); public MySet(String... strings) { add(strings); } public void add(String... strings) { for (String s : strings) { set.add(s); } } public boolean contains(String s) { return set.contains(s); } public String toString() { return set.toString(); } } public void testTypedVarArgsParams() { String imports = "import org.mvel2.tests.core.CoreConfidenceTests.A;\nimport org.mvel2.tests.core.CoreConfidenceTests.B;\n"; String invoke0 = imports + "new A().invoke(\"s1\", \"s2\")"; int result = (Integer) compileAndExecuteWithStrongTyping(invoke0); assertEquals(0, result); assertEquals(0, runSingleTest(invoke0)); String invokeSum0 = imports + "A.invokeSum(3)"; result = (Integer) compileAndExecuteWithStrongTyping(invokeSum0); assertEquals(3, result); assertEquals(3, runSingleTest(invokeSum0)); String invoke3 = imports + "new A().invoke(\"s1\", \"s2\", new B(), new B(), new B())"; result = (Integer) compileAndExecuteWithStrongTyping(invoke3); assertEquals(3, result); assertEquals(3, runSingleTest(invoke3)); String invokeSum2 = imports + "A.invokeSum(3, new B(4), new B(5))"; result = (Integer) compileAndExecuteWithStrongTyping(invokeSum2); assertEquals(12, result); assertEquals(12, runSingleTest(invokeSum2)); } public void testTypedVarArgsConstructor() { String imports = "import org.mvel2.tests.core.CoreConfidenceTests.MySet;\n"; String constructor = imports + "new MySet(\"s1\", \"s2\")"; MySet result = (MySet) compileAndExecuteWithStrongTyping(constructor); assertTrue(result.contains("s1")); assertTrue(result.contains("s2")); } private <T> T compileAndExecuteWithStrongTyping(String expression) { return (T) compileAndExecuteWithStrongTyping(expression, new HashMap()); } private <T> T compileAndExecuteWithStrongTyping(String expression, Map vars) { ParserContext context = new ParserContext(); context.setStrongTyping(true); context.setStrictTypeEnforcement(true); Serializable compiled = MVEL.compileExpression(expression, context); return (T) MVEL.executeExpression(compiled, vars); } public void testArrayCreation() { assertTrue(Arrays.deepEquals(new Object[0], (Object[]) compileAndExecuteWithStrongTyping("{}"))); assertTrue(Arrays.deepEquals(new String[0], (String[]) compileAndExecuteWithStrongTyping("new String[] {}"))); assertTrue(Arrays.deepEquals(new String[]{"xyz"}, (String[]) compileAndExecuteWithStrongTyping("new String[] { \"xyz\" }"))); assertTrue(Arrays.deepEquals(new String[]{"xyz"}, (String[]) compileAndExecuteWithStrongTyping("new String[] { new String(\"xyz\") }"))); assertTrue(Arrays.deepEquals(new String[]{"xyz", "abc"}, (String[]) compileAndExecuteWithStrongTyping("new String[] { new String(\"xyz\"), new String(\"abc\") }"))); assertTrue(Arrays.deepEquals(new B[0], (B[]) compileAndExecuteWithStrongTyping("import org.mvel2.tests.core.CoreConfidenceTests.B;\nnew B[] { }"))); assertTrue(Arrays.deepEquals(new B[]{new B(5)}, (B[]) compileAndExecuteWithStrongTyping("import org.mvel2.tests.core.CoreConfidenceTests.B;\nnew B[] { new B(5) }"))); assertTrue(Arrays.deepEquals(new B[]{new B(), new B(), new B()}, (B[]) compileAndExecuteWithStrongTyping("import org.mvel2.tests.core.CoreConfidenceTests.B;\nnew B[] {new B(),new B(),new B()}"))); } public static class Bean1 { private String Field1; private String FIELD2; private int intField; public String getField1() { return Field1; } public void setField1(String Field1) { this.Field1 = Field1; } public String getFIELD2() { return FIELD2; } public void setFIELD2(String FIELD2) { this.FIELD2 = FIELD2; } public int getIntField() { return intField; } public void setIntField(int intField) { this.intField = intField; } public Option<String> getField1Option() { return new Option(Field1); } } public static class Option<T> { public final T t; public Option(T t) { this.t = t; } public boolean isDefined() { return t != null; } public T get() { return t; } } public void testUppercaseField() { String ex = "Field1 == \"foo\" || FIELD2 == \"bar\""; final ParserContext parserContext2 = new ParserContext(); parserContext2.setStrictTypeEnforcement(true); parserContext2.setStrongTyping(true); parserContext2.addInput("this", Bean1.class); MVEL.analyze(ex, parserContext2); } public void testExpressionReturnType() { assertEquals(String.class, expressionReturnType("Field1")); assertEquals(String.class, expressionReturnType("Field1 + FIELD2")); assertEquals(String.class, expressionReturnType("Field1 + 3")); assertEquals(String.class, expressionReturnType("Field1 + 3 + FIELD2")); assertEquals(int.class, expressionReturnType("intField")); assertEquals(Integer.class, expressionReturnType("intField = 3")); assertEquals(Boolean.class, expressionReturnType("intField == 3")); assertEquals(Boolean.class, expressionReturnType("intField == \"3\"")); assertEquals(Boolean.class, expressionReturnType("intField == 1 || Field1 == \"xxx\"")); assertEquals(Boolean.class, expressionReturnType("FIELD2 == \"yyy\" && intField == 1 + 2 || Field1 == \"xxx\"")); } public void testConstantOnLeftExpression() { assertEquals(Boolean.class, expressionReturnType("3 == intField")); assertEquals(Boolean.class, expressionReturnType("\"xxx\" == Field1")); assertEquals(Boolean.class, expressionReturnType("null == Field1")); } public void testExpressionReturnTypeWithGenerics() { assertEquals(String.class, expressionReturnType("Field1Option.get")); assertEquals(String.class, expressionReturnType("Field1Option.t")); } public void testWrongExpressions() { wrongExpressionMustFail("Field1 == 3"); wrongExpressionMustFail("Field1 - 3"); wrongExpressionMustFail("intField == 3 || Field1"); } private void wrongExpressionMustFail(String expr) { try { expressionReturnType(expr); fail("wrong expression '" + expr + "' must fail"); } catch (Exception e) { } } private Class<?> expressionReturnType(String expr) { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("this", Bean1.class); MVEL.compileExpression(expr, parserContext); return MVEL.analyze(expr, parserContext); } public void testExponentialNotation() { assertEquals(110.0, runSingleTest("10 + 1.0E+2")); assertEquals(90.0, runSingleTest("1.0E+2 - 10")); assertEquals(10.01, runSingleTest("10 + 1.0E-2")); } public void testShiftOperator() { String expression = "1 << 65536L"; Serializable compiled = MVEL.compileExpression(expression, context); Object result = MVEL.executeExpression(compiled, new HashMap()); assertEquals(1 << 65536L, result); expression = "one << shift"; Map map = new HashMap() {{ put("one", 1); put("shift", 65536L); }}; compiled = MVEL.compileExpression(expression, context); result = MVEL.executeExpression(compiled, map); assertEquals(1 << 65536L, result); System.out.println(result); } public void testSystemOutOnPrivateClass() { PrintStream originalSystemOut = System.out; System.setOut(new MyPrivatePrintStream(System.out)); String expression = "System.out.println(\"Hello World\");"; runSingleTest(expression); System.setOut(originalSystemOut); } private static class MyPrivatePrintStream extends PrintStream { public MyPrivatePrintStream(OutputStream os) { super(os); } public void println(String s) { super.println(s); } } public void testSystemOutWithActualInstanceMethod() { PrintStream originalSystemOut = System.out; System.setOut(new MyPublicPrintStream(System.out)); String expression = "System.out.myPrintln(\"Hello World\");"; runSingleTest(expression); System.setOut(originalSystemOut); } public static class MyPublicPrintStream extends PrintStream { public MyPublicPrintStream(OutputStream os) { super(os); } public void println(String s) { super.println(s); } public void myPrintln(String s) { super.println(s); } } public void testMinusOperatorWithoutSpace() { String str = "length == $c.length -1"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); ExecutableStatement stmt = (ExecutableStatement) MVEL.compileExpression(str, pctx); Column col1 = new Column("x", 0); Column col2 = new Column("x", 0); Map<String, Object> vars = new HashMap<String, Object>(); vars.put("$c", col2); Boolean result = (Boolean) MVEL.executeExpression(stmt, col1, vars); assertFalse(result); } public void testDhanji2() { String ex = "name = null;\n" + "$_1 = ?name.?toLowerCase();\n"; Serializable s = MVEL.compileExpression(ex); MVEL.executeExpression(s, new HashMap()); } public void testPrimitiveNumberCoercion() { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("a", int.class); parserContext.addInput("b", double.class); Class<?> clazz = MVEL.analyze("a > b", parserContext); assertEquals(Boolean.class, clazz); } public void testClassLiteral() { try { MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS = true; final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("a", Class.class); MVEL.compileExpression("a == String", parserContext); } finally { MVEL.COMPILER_OPT_SUPPORT_JAVA_STYLE_CLASS_LITERALS = false; } } public void testBigIntegerWithZeroValue() { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("a", BigInteger.class); Serializable expression = MVEL.compileExpression("a == 0I", parserContext); boolean result = (Boolean) MVEL.executeExpression(expression, new HashMap() {{ put("a", new BigInteger("0")); }}); assertTrue(result); } public void testBigDecimalWithZeroValue() { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("a", BigDecimal.class); Serializable expression = MVEL.compileExpression("a == 0B", parserContext); boolean result = (Boolean) MVEL.executeExpression(expression, new HashMap() {{ put("a", new BigDecimal("0.0")); }}); assertTrue(result); } public void testMethodReturningPrimitiveTypeAnalysis() { String str = "value"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.addInput("this", MyObj.class); pctx.setStrongTyping(true); Class<?> returnType = MVEL.analyze(str, pctx); assertEquals(long.class, returnType); } public static class MyObj { public long valueField; public MyObj(long value) { this.valueField = value; } public long getValue() { return valueField; } public static String doSomething(MyObj s1, String s2) { return s1 + s2; } } public void testStaticMethodsInvocationWithNullArg() { String str = "org.mvel2.tests.core.CoreConfidenceTests$MyObj.doSomething(null, \"abc\")"; ParserConfiguration pconf = new ParserConfiguration(); ParserContext pctx = new ParserContext(pconf); pctx.setStrongTyping(true); assertEquals(null + "abc", MVEL.executeExpression(MVEL.compileExpression(str, pctx))); } public interface InterfaceA { InterfaceB getB(); } public interface InterfaceB { } public static class ImplementationA implements InterfaceA { public ImplementationB getB() { return new ImplementationB(); } public void setB(InterfaceB b) { } } public static class ImplementationB implements InterfaceB { public int getValue() { return 42; } } public void testCovariance() { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("this", ImplementationA.class); assertEquals(int.class, MVEL.analyze("b.value", parserContext)); assertEquals(42, MVEL.executeExpression(MVEL.compileExpression("b.value", parserContext), new ImplementationA())); } public void testDivisionType() { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("a", BigDecimal.class); Serializable expression = MVEL.compileExpression("(a / 3).setScale(2, java.math.BigDecimal.ROUND_HALF_UP)", parserContext); Object result = MVEL.executeExpression(expression, new HashMap() {{ put("a", new BigDecimal("3.0")); }}); System.out.println(result); } public void testUntypedClone() { String expression = "obj.clone();"; ParserContext context = new ParserContext(); context.setStrongTyping(false); context.setStrictTypeEnforcement(false); MVEL.analyze(expression, context); try { context.addInput("obj", Object.class); context.setStrongTyping(true); context.setStrictTypeEnforcement(true); MVEL.analyze(expression, context); fail("Must fail with strong typing"); } catch (CompileException e) { } } public void testOverloading() { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("this", Overloaded.class); Overloaded overloaded = new Overloaded(); assertEquals(15, MVEL.executeExpression(MVEL.compileExpression("method(5, 9, \"x\")", parserContext), overloaded)); assertEquals(-3, MVEL.executeExpression(MVEL.compileExpression("method(5, \"x\", 9)", parserContext), overloaded)); assertEquals(-13, MVEL.executeExpression(MVEL.compileExpression("method(\"x\", 5, 9)", parserContext), overloaded)); } public static class Overloaded { public int method(int i, int j, String s) { return i + j + s.length(); } public int method(int i, String s, int j) { return i + s.length() - j; } public int method(String s, int i, int j) { return s.length() - i - j; } } public void testPippo() { final ParserContext parserContext = new ParserContext(); parserContext.setStrongTyping(true); assertEquals(String.class, MVEL.analyze("new String(\"b)ar\")", parserContext)); } public void testReturnTypeExtendingGeneric() { final ParserContext parserContext = new ParserContext(); parserContext.setStrongTyping(true); parserContext.addInput("this", StringConcrete.class); assertEquals(String.class, MVEL.analyze("foo.concat(\"bar\")", parserContext)); assertEquals(String.class, MVEL.analyze("getFoo().concat(\"bar\")", parserContext)); } public static abstract class AbstractBase<T> { protected T foo; public T getFoo() { return foo; } } public static class StringConcrete extends AbstractBase<String> { public StringConcrete() { this.foo = new String(); } } public void testNullCollection() throws CompileException { boolean allowCompilerOverride = MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING; MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = true; String[] names = { "missing" }; String[] values = { null }; try { MVEL.executeExpression( (CompiledExpression) MVEL.compileExpression("1; missing[3]"), new IndexedVariableResolverFactory(names, values) ); fail("Should throw a NullPointerExcption"); } catch (Exception e) { } finally { MVEL.COMPILER_OPT_ALLOW_OVERRIDE_ALL_PROPHANDLING = allowCompilerOverride; } } public void testRegExWithCast() { final ParserContext parserContext = new ParserContext(); parserContext.setStrongTyping(true); parserContext.addInput("this", Foo.class); assertEquals(Boolean.class, MVEL.analyze("(String)bar.name ~= '[a-z].+'", parserContext)); } public void testUnwantedImport() { ParserConfiguration conf = new ParserConfiguration(); conf.addPackageImport("java.util"); conf.addPackageImport("org.mvel2.tests.core.res"); ParserContext pctx = new ParserContext( conf ); MVEL.analysisCompile( "ScenarioType.Set.ADD", pctx ); assertNull(conf.getImports().get("Set")); } public void testUnaryNegative() { ParserConfiguration conf = new ParserConfiguration(); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("value", int.class); Map vars = new HashMap() {{ put("value", 42); }}; assertEquals(-42, MVEL.executeExpression(MVEL.compileExpression("-value", pctx), vars)); } public void testUnaryNegativeWithSpace() { ParserConfiguration conf = new ParserConfiguration(); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("value", int.class); Map vars = new HashMap() {{ put("value", 42); }}; assertEquals(-42, MVEL.executeExpression(MVEL.compileExpression("- value", pctx), vars)); } public static class ARef { public static int getSize(String s) { return 0; } } public static class BRef extends ARef { public static int getSize(String s) { return s.length(); } } public void testStaticMethodInvocation() { ParserConfiguration conf = new ParserConfiguration(); conf.addImport(ARef.class); conf.addImport(BRef.class); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("value", String.class); Map vars = new HashMap() {{ put("value", "1234"); }}; assertEquals(0, MVEL.executeExpression(MVEL.compileExpression("ARef.getSize(value)", pctx), vars)); assertEquals(4, MVEL.executeExpression(MVEL.compileExpression("BRef.getSize(value)", pctx), vars)); } public void testMultiplyIntByDouble() { ParserConfiguration conf = new ParserConfiguration(); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("i", Integer.class); pctx.addInput("d", Double.class); Map vars = new HashMap() {{ put("i", 10); put("d", 0.3); }}; assertEquals(3.0, MVEL.executeExpression(MVEL.compileExpression("i*d", pctx), vars)); assertEquals(3.0, MVEL.executeExpression(MVEL.compileExpression("i*0.3", pctx), vars)); } public void testCharToStringCoercionForComparison() { ParserConfiguration conf = new ParserConfiguration(); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("ch", Character.class); Map vars = new HashMap() {{ put("ch", 'a'); }}; assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("ch == \"a\"", pctx), vars)); assertEquals(false, MVEL.executeExpression(MVEL.compileExpression("ch == \"b\"", pctx), vars)); } public void testFieldNameWithUnderscore() { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("this", Underscore.class); Underscore underscore = new Underscore(); assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("_id == \"test\"", parserContext), underscore)); } public static class Underscore { public String get_id() { return "test"; } } public void testEmptyOperatorOnStrings() { ParserConfiguration conf = new ParserConfiguration(); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("nullString", String.class); pctx.addInput("emptyString", String.class); pctx.addInput("blankString", String.class); pctx.addInput("nonEmptyString", String.class); Map vars = new HashMap() {{ put("nullString", null); put("emptyString", ""); put("blankString", " "); put("nonEmptyString", "abc"); }}; assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("nullString == empty", pctx), vars)); assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("emptyString == empty", pctx), vars)); assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("blankString == empty", pctx), vars)); assertEquals(false, MVEL.executeExpression(MVEL.compileExpression("nonEmptyString == empty", pctx), vars)); } public void testEmptyOperatorOnBoolean() { ParserConfiguration conf = new ParserConfiguration(); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("bNull", Boolean.class); pctx.addInput("bTrue", Boolean.class); pctx.addInput("bFalse", Boolean.class); Map vars = new HashMap() {{ put("bNull", null); put("bTrue", true); put("bFalse", false); }}; assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("bNull == empty", pctx), vars)); assertEquals(false, MVEL.executeExpression(MVEL.compileExpression("bTrue == empty", pctx), vars)); assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("bFalse == empty", pctx), vars)); } public void testEmptyOperatorOnInteger() { ParserConfiguration conf = new ParserConfiguration(); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("nullInt", Integer.class); pctx.addInput("zero", Integer.class); pctx.addInput("nonZero", Integer.class); Map vars = new HashMap() {{ put("nullInt", null); put("zero", 0); put("nonZero", 42); }}; assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("nullInt == empty", pctx), vars)); assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("zero == empty", pctx), vars)); assertEquals(false, MVEL.executeExpression(MVEL.compileExpression("nonZero == empty", pctx), vars)); } public void testInstanceofOnInnerClass() { ParserConfiguration conf = new ParserConfiguration(); conf.addImport(ARef.class); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("value", Object.class); Map vars = new HashMap() {{ put("value", new ARef()); }}; assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("value instanceof ARef", pctx), vars)); assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("value instanceof " + ARef.class.getCanonicalName(), pctx), vars)); } public void testInstanceofWithPackageImport() { ParserConfiguration conf = new ParserConfiguration(); conf.addPackageImport( "org.mvel2.tests.core" ); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("value", Object.class); Map vars = new HashMap() {{ put("value", new CoreConfidenceTests()); }}; assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("value instanceof CoreConfidenceTests", pctx), vars)); assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("value instanceof " + CoreConfidenceTests.class.getCanonicalName(), pctx), vars)); } public void testInstanceofWithPackageImportAndInnerClass() { ParserConfiguration conf = new ParserConfiguration(); conf.addPackageImport( "org.mvel2.tests.core.CoreConfidenceTests" ); ParserContext pctx = new ParserContext( conf ); pctx.setStrictTypeEnforcement(true); pctx.setStrongTyping(true); pctx.addInput("value", Object.class); Map vars = new HashMap() {{ put("value", new ARef()); }}; assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("value instanceof ARef", pctx), vars)); assertEquals(true, MVEL.executeExpression(MVEL.compileExpression("value instanceof " + ARef.class.getCanonicalName(), pctx), vars)); } public void testCompilerExceptionFormatting() throws Exception { try { Object value = test("\n2x * 3\n"); fail("Invalid expression should fail"); } catch (Exception e) { // Invalid expression should fail to compile } } public void testHandleNumericConversionBug() { String[] testLiterals = {"0x20","020",}; String baseExpression = "int foo = "; for( String literal : testLiterals ) { char[] decExpr = ( baseExpression + literal ).toCharArray(); assertEquals( Integer.decode( literal ), ParseTools.handleNumericConversion( decExpr, baseExpression.length(), literal.length() ) ); } } public static class Parent { public Object getSomething() { return null; } } public static class Child extends Parent { @Override public String getSomething() { return null; } } public void testNoArgMethodInheritance() { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("a", Parent.class); parserContext.addInput("b", Child.class); assertEquals(Object.class, MVEL.analyze("a.getSomething()", parserContext)); assertEquals(String.class, MVEL.analyze("b.getSomething()", parserContext)); } public void testMethodOverloadMatch() throws Exception { OverloadedClass c = new OverloadedClass(); Method found = ParseTools.getExactMatch("putXX", new Class[]{int.class, String.class}, void.class, OverloadedInterface.class); Method correct = OverloadedInterface.class.getMethod("putXX", new Class[]{int.class, String.class}); assertEquals(correct, found); } public static class O1 { public O2 getObj() { return new O2(); } } public static class O2 extends O3 { } public abstract static class O3 { public String getValue() { return "value"; } } public void testInvokeMethodInAbstractClass() { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("a", O1.class); assertEquals(String.class, MVEL.analyze("a.getObj().getValue()", parserContext)); Map vars = new HashMap() {{ put("a", new O1()); }}; assertEquals("value", MVEL.executeExpression(MVEL.compileExpression("a.getObj().getValue()", parserContext), vars)); } public class Convention { private final Map<String, List<String>> comms; public Convention( Map<String, List<String>> comms ) { this.comms = comms; } public Map<String, List<String>> getComms(){ return comms; } } public void testParseGenericMap() { final ParserContext parserContext = new ParserContext(); parserContext.setStrictTypeEnforcement(true); parserContext.setStrongTyping(true); parserContext.addInput("conv", Convention.class); assertEquals(List.class, MVEL.analyze("conv.getComms().get(\"test\")", parserContext)); } }