package org.enumerable.lambda.weaving; import org.junit.After; import org.junit.Before; import org.junit.Test; import java.io.*; import java.lang.reflect.Field; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; public class ErrorHandlingTest { InMemoryCompiler compiler = new InMemoryCompiler(); PrintStream realErr; ByteArrayOutputStream err; @Before public void redirectStdErr() { realErr = System.err; err = new ByteArrayOutputStream(); System.setErr(new PrintStream(err)); } @After public void restoreStdErr() { System.setErr(realErr); } @After public void forgetTransformationFailed() throws Exception { Field transformationFailed = LambdaLoader.class.getDeclaredField("transformationFailed"); transformationFailed.setAccessible(true); transformationFailed.set(null, false); } @Test public void givesExceptionForInstanceLambdaParamter() throws Exception { String className = "InstanceLambdaParamter"; StringWriter writer = new StringWriter(); PrintWriter out = new PrintWriter(writer); out.println("import static org.enumerable.lambda.Lambda.*;"); out.println("import org.enumerable.lambda.annotation.LambdaParameter;"); out.println("class " + className + " {"); out.println(" @LambdaParameter"); out.println(" public String instance;"); out.println(" public void method() {"); out.println(" λ(instance, instance);"); out.println(" }"); out.println("}"); out.close(); assertNotNull(compiler.compile(className, writer.toString())); assertErrContains("IllegalStateException: Tried to define non static lambda parameter instance"); } @Test public void givesExceptionForStaticNotAnnotatedAsLambdaParamter() throws IOException { String className = "NotAnnotatedAsLambdaParamter"; StringWriter writer = new StringWriter(); PrintWriter out = new PrintWriter(writer); out.println("import static org.enumerable.lambda.Lambda.*;"); out.println("import org.enumerable.lambda.annotation.LambdaParameter;"); out.println("class " + className + " {"); out.println(" public static String noAnnotation;"); out.println(" public void method() {"); out.println(" λ(noAnnotation, noAnnotation);"); out.println(" }"); out.println("}"); out.close(); assertNotNull(compiler.compile(className, writer.toString())); assertErrContains("IllegalStateException: Got [] as parameters need exactly 1 at "); } @Test public void givesExceptionForMethodCallUsedAsLambdaParamter() throws IOException { String className = "MethodCallUsedAsLambdaParamter"; StringWriter writer = new StringWriter(); PrintWriter out = new PrintWriter(writer); out.println("import static org.enumerable.lambda.Lambda.*;"); out.println("import org.enumerable.lambda.annotation.LambdaParameter;"); out.println("class " + className + " {"); out.println(" public String noAnnotation() { return \"\"; };"); out.println(" public void method() {"); out.println(" λ(noAnnotation(), noAnnotation());"); out.println(" }"); out.println("}"); out.close(); assertNotNull(compiler.compile(className, writer.toString())); assertErrContains("IllegalStateException: Got [] as parameters need exactly 1"); } @Test public void givesExceptionForInstanceNewLambdaMethod() throws Exception { String className = "InstanceNewLambdaMethod"; StringWriter writer = new StringWriter(); PrintWriter out = new PrintWriter(writer); out.println("import org.enumerable.lambda.exception.LambdaWeavingNotEnabledException;"); out.println("import org.enumerable.lambda.annotation.NewLambda;"); out.println("class " + className + " {"); out.println(" @NewLambda"); out.println(" public Runnable instance() {"); out.println(" throw new LambdaWeavingNotEnabledException();"); out.println(" }"); out.println(" public void method() {"); out.println(" Runnable r = instance();"); out.println(" }"); out.println("}"); out.close(); assertNotNull(compiler.compile(className, writer.toString())); assertErrContains("IllegalStateException: Tried to call non static new lambda method instance"); } @Test public void givesExceptionForMissingDebugInfo() throws Exception { String className = "CloseOverParameter"; StringWriter writer = new StringWriter(); PrintWriter out = new PrintWriter(writer); out.println("import static org.enumerable.lambda.Lambda.*;"); out.println("import org.enumerable.lambda.annotation.NewLambda;"); out.println("class " + className + " {"); out.println(" public void method(String param) {"); out.println(" λ(param);"); out.println(" }"); out.println("}"); out.close(); compiler.debugInfo(false); assertNotNull(compiler.compile(className, writer.toString())); assertErrContains("IllegalStateException: Debug information is needed to close over local variables or parameters, please recompile with -g."); } void assertErrContains(String message) throws IOException { err.flush(); if (!err.toString().contains(message)) { restoreStdErr(); System.err.println(err.toString()); fail(err.toString()); } } }