package org.mvel2.tests.core;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.mvel2.MVEL;
import org.mvel2.MVELRuntime;
import org.mvel2.Macro;
import org.mvel2.MacroProcessor;
import org.mvel2.ParserContext;
import org.mvel2.ast.ASTNode;
import org.mvel2.ast.WithNode;
import org.mvel2.compiler.CompiledExpression;
import org.mvel2.compiler.ExpressionCompiler;
import org.mvel2.debug.DebugTools;
import org.mvel2.debug.Debugger;
import org.mvel2.debug.Frame;
import org.mvel2.integration.Interceptor;
import org.mvel2.integration.VariableResolverFactory;
import org.mvel2.integration.impl.MapVariableResolverFactory;
import org.mvel2.tests.core.res.Foo;
import java.util.HashMap;
import java.util.Map;
import static org.mvel2.MVEL.executeExpression;
import static org.mvel2.MVEL.parseMacros;
public class MacroProcessorTest extends TestCase {
private MacroProcessor macroProcessor;
protected void setUp() throws Exception {
super.setUp();
Map<String, Macro> macros = new HashMap<String, Macro>();
macros.put("insert",
new Macro() {
public String doMacro() {
return "drools.insert";
}
});
macroProcessor = new MacroProcessor();
macroProcessor.setMacros(macros);
}
public void testParseString() {
String raw = " l.add( \"rule 2 executed \" + str);";
try {
String result = macroProcessor.parse(raw);
assertEquals(raw, result);
}
catch (Exception ex) {
ex.printStackTrace();
fail("there shouldn't be any exception: " + ex.getMessage());
}
}
public void testParseConsequenceWithComments() {
String raw = " // str is null, we are just testing we don't get a null pointer \n " +
" list.add( p );";
try {
String result = macroProcessor.parse(raw);
assertEquals(raw, result);
}
catch (Exception ex) {
ex.printStackTrace();
fail("there shouldn't be any exception: " + ex.getMessage());
}
}
public void testInfiniteLoop() {
String str = "";
str += "int insuranceAmt = caseRate + (charges * pctDiscount / 100);\n";
str += "update (estimate); \n";
Map<String, Macro> macros = new HashMap<String, Macro>();
macros.put("update",
new Macro() {
public String doMacro() {
return "drools.update";
}
});
String result = parseMacros(str, macros);
str = "";
str += "int insuranceAmt = caseRate + (charges * pctDiscount / 100);\n";
str += "drools.update (estimate);";
assertEquals(str, result);
}
public void testMacroSupport() {
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("foo", new Foo());
Map<String, Interceptor> interceptors = new HashMap<String, Interceptor>();
Map<String, Macro> macros = new HashMap<String, Macro>();
interceptors.put("Modify", new Interceptor() {
public int doBefore(ASTNode node, VariableResolverFactory factory) {
((WithNode) node).getNestedStatement().getValue(null,
factory);
factory.createVariable("mod", "FOOBAR!");
return 0;
}
public int doAfter(Object val, ASTNode node, VariableResolverFactory factory) {
return 0;
}
});
macros.put("modify", new Macro() {
public String doMacro() {
return "@Modify with";
}
});
ParserContext ctx = new ParserContext(null, interceptors, null);
ctx.setSourceFile("test.mv");
ctx.setDebugSymbols(true);
ExpressionCompiler compiler = new ExpressionCompiler(parseMacros("modify (foo) { aValue = 'poo = poo', bValue = 'poo, poo' }; mod", macros), ctx);
assertEquals("FOOBAR!", executeExpression(compiler.compile(), null, vars));
}
public void testMacroSupportWithStrings() {
Map<String, Object> vars = new HashMap<String, Object>();
Foo foo = new Foo();
vars.put("foo", foo);
Map<String, Macro> macros = new HashMap<String, Macro>();
macros.put("modify", new Macro() {
public String doMacro() {
return "drools.modify";
}
});
assertEquals("", foo.aValue);
ParserContext ctx = new ParserContext(null, null, null);
ctx.setSourceFile("test.mv");
ctx.setDebugSymbols(true);
ExpressionCompiler compiler = new ExpressionCompiler(parseMacros("\"This is an modify()\"", macros), ctx);
assertEquals("This is an modify()", executeExpression(compiler.compile(), null, vars));
}
public void testMacroSupportWithDebugging() {
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("foo", new Foo());
Map<String, Interceptor> interceptors = new HashMap<String, Interceptor>();
Map<String, Macro> macros = new HashMap<String, Macro>();
interceptors.put("Modify", new Interceptor() {
public int doBefore(ASTNode node, VariableResolverFactory factory) {
((WithNode) node).getNestedStatement().getValue(null,
factory);
factory.createVariable("mod", "FOOBAR!");
return 0;
}
public int doAfter(Object val, ASTNode node, VariableResolverFactory factory) {
return 0;
}
});
macros.put("modify", new Macro() {
public String doMacro() {
return "@Modify with";
}
});
ParserContext ctx = new ParserContext(null, interceptors, null);
ctx.setSourceFile("test.mv");
ctx.setDebugSymbols(true);
ExpressionCompiler compiler = new ExpressionCompiler(
parseMacros(
"System.out.println('hello');\n" +
"System.out.println('bye');\n" +
"modify (foo) { aValue = 'poo', \n" +
" aValue = 'poo' };\n mod", macros)
, ctx);
// compiler.setDebugSymbols(true);
CompiledExpression compiled = compiler.compile();
MVELRuntime.setThreadDebugger(new Debugger() {
public int onBreak(Frame frame) {
System.out.println(frame.getSourceName() + ":" + frame.getLineNumber());
return Debugger.STEP;
}
});
MVELRuntime.registerBreakpoint("test.mv", 3);
System.out.println(DebugTools.decompile(compiled
));
Assert.assertEquals("FOOBAR!", MVEL.executeDebugger(compiled, null, new MapVariableResolverFactory(vars)));
}
public void testParseStringUnmatchedChars() {
String raw = "result.add( \"\\\"\\\' there are } [ unmatched characters in this string (\" );";
try {
String result = macroProcessor.parse(raw);
assertEquals(raw, result);
}
catch (Exception ex) {
ex.printStackTrace();
fail("there shouldn't be any exception: " + ex.getMessage());
}
}
public void testParseConsequenceWithFlowControlBlocks() {
String raw = " // str is null, we are just testing we don't get a null pointer \n " +
" if (l.x < 1) {\n" +
" insert( new RuleLink(\"FIRST.INLET\" , comp, comp) );\n" +
" } else {\n" +
" insert( new RuleLink(\"FIRST.INLET.NOT\" , comp, comp) );\n" +
" }\n" +
" if( 1 < 2 ) { \n" +
" insert( p ); \n" +
" } else { \n" +
" while( true ) {insert(x);}\n" +
" }";
String expected = " // str is null, we are just testing we don't get a null pointer \n " +
" if (l.x < 1) {\n" +
" drools.insert( new RuleLink(\"FIRST.INLET\" , comp, comp) );\n" +
" } else {\n" +
" drools.insert( new RuleLink(\"FIRST.INLET.NOT\" , comp, comp) );\n" +
" }\n" +
" if( 1 < 2 ) { \n" +
" drools.insert( p ); \n" +
" } else { \n" +
" while( true ) {drools.insert(x);}\n" +
" }";
try {
String result = macroProcessor.parse(raw);
assertEquals(expected, result);
}
catch (Exception ex) {
ex.printStackTrace();
fail("there shouldn't be any exception: " + ex.getMessage());
}
}
public void testCommentParsingWithMacro() {
String raw = "/** This is a block comment **/ insert /** This is a second \n\nblock comment insert **/";
String expected = "/** This is a block comment **/ drools.insert /** This is a second \n\nblock comment insert **/";
try {
String result = macroProcessor.parse(raw);
assertEquals(expected, result);
}
catch (Exception ex) {
ex.printStackTrace();
fail("there shouldn't be any exception: " + ex.getMessage());
}
}
}