package org.enumerable.lambda.support.expression; import static org.junit.Assert.*; import japa.parser.ASTHelper; import japa.parser.JavaParser; import japa.parser.ast.CompilationUnit; import japa.parser.ast.PackageDeclaration; import japa.parser.ast.body.ClassOrInterfaceDeclaration; import japa.parser.ast.body.MethodDeclaration; import japa.parser.ast.body.ModifierSet; import japa.parser.ast.body.Parameter; import japa.parser.ast.expr.FieldAccessExpr; import japa.parser.ast.expr.MethodCallExpr; import japa.parser.ast.expr.NameExpr; import japa.parser.ast.expr.StringLiteralExpr; import japa.parser.ast.stmt.BlockStmt; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.enumerable.lambda.weaving.InMemoryCompiler; import org.junit.Test; public class InMemoryCompilerTest { InMemoryCompiler compiler = new InMemoryCompiler(); @Test public void inMemoryCompilationFromJavaParserAST() throws Exception { CompilationUnit cu = createCU(); assertEquals("Hello World from AST", invokeMain(compiler.compile(getFullyQualifiedName(cu), cu.toString())) .trim()); } @Test public void inMemoryCompilationFromPlainString() throws Exception { String className = "HelloWorld"; StringWriter writer = new StringWriter(); PrintWriter out = new PrintWriter(writer); out.println("class " + className + " {"); out.println(" public static void main(String args[]) {"); out.println(" System.out.println(\"Hello World from String\");"); out.println(" }"); out.println("}"); out.close(); assertEquals("Hello World from String", invokeMain(compiler.compile(className, writer.toString())).trim()); } @Test public void inMemoryCompilationFromPlainStringViaJavaParserAST() throws Exception { StringWriter writer = new StringWriter(); PrintWriter out = new PrintWriter(writer); out.println("class HelloWorldAST {"); out.println(" public static void main(String args[]) {"); out.println(" System.out.println(\"Hello World from JavaParser\");"); out.println(" }"); out.println("}"); out.close(); CompilationUnit cu = JavaParser.parse(new ByteArrayInputStream(writer.toString().getBytes())); assertEquals("Hello World from JavaParser", invokeMain( compiler.compile(getFullyQualifiedName(cu), cu.toString())).trim()); } @Test public void inMemoryCompilationSharesClassPath() throws Exception { String className = "HelloWorldSharedClassPath"; StringWriter writer = new StringWriter(); PrintWriter out = new PrintWriter(writer); out.println("import japa.parser.*;"); out.println("class " + className + " {"); out.println(" public static void main(String args[]) {"); out.println(" System.out.println(JavaParser.class.getName());"); out.println(" }"); out.println("}"); out.close(); assertEquals(JavaParser.class.getName(), invokeMain(compiler.compile(className, writer.toString())).trim()); } // This is borrowed from the javaparser examples. CompilationUnit createCU() { CompilationUnit cu = new CompilationUnit(); cu.setPackage(new PackageDeclaration(ASTHelper.createNameExpr("parser.test"))); ClassOrInterfaceDeclaration type = new ClassOrInterfaceDeclaration(0, false, "GeneratedClass"); ASTHelper.addTypeDeclaration(cu, type); MethodDeclaration method = new MethodDeclaration(ModifierSet.PUBLIC, ASTHelper.VOID_TYPE, "main"); method.setModifiers(ModifierSet.addModifier(method.getModifiers(), ModifierSet.STATIC)); ASTHelper.addMember(type, method); Parameter param = ASTHelper.createParameter(ASTHelper.createReferenceType("String", 0), "args"); param.setVarArgs(true); ASTHelper.addParameter(method, param); BlockStmt block = new BlockStmt(); method.setBody(block); NameExpr clazz = new NameExpr("System"); FieldAccessExpr field = new FieldAccessExpr(clazz, "out"); MethodCallExpr call = new MethodCallExpr(field, "println"); ASTHelper.addArgument(call, new StringLiteralExpr("Hello World from AST")); ASTHelper.addStmt(block, call); return cu; } String invokeMain(Class<?> aClass) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException { ByteArrayOutputStream out = new ByteArrayOutputStream(); PrintStream realOut = System.out; try { System.setOut(new PrintStream(out)); Method main = aClass.getDeclaredMethod("main", new Class<?>[] { String[].class }); main.setAccessible(true); main.invoke(null, (Object) new String[0]); return out.toString(); } finally { System.setOut(realOut); } } String getFullyQualifiedName(CompilationUnit cu) { String name = cu.getTypes().get(0).getName(); if (cu.getPackage() != null) return cu.getPackage().getName() + "." + name; return name; } }