package scotch.runner; import static org.apache.commons.io.FileUtils.deleteDirectory; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static scotch.runtime.RuntimeSupport.box; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import org.apache.commons.cli.ParseException; import org.junit.Before; import org.junit.Test; import scotch.runtime.Applicable; import scotch.runtime.Callable; public class CompilerRunnerTest { private static final String OUTPUT_PATH = "build/generated-test-classes/CompilerRunnerTest"; @Before public void setUp() throws IOException { deleteDirectory(new File(OUTPUT_PATH)); } @Test public void shouldCompileFiles() throws Exception { compile(); shouldHaveClasses( "a.b.c.$$Module", "x.y.z.$$Module", "a.b.c.Toast", "a.b.c.Toast$Toast", "a.b.c.Bread", "a.b.c.Bread$Rye", "a.b.c.Bread$Wheat", "a.b.c.Bread$White" ); } @SuppressWarnings("unchecked") @Test public void toastWithBurnLevelOf4ShouldBeBurned() throws Exception { compile(); ClassLoader classLoader = getClassLoader(); Method rye = classLoader.loadClass("a.b.c.$$Module").getMethod("Rye"); Callable toast = getToast(classLoader, rye); Method isBurned = classLoader.loadClass("x.y.z.$$Module").getMethod("isBurned$wat"); assertThat(((Applicable) isBurned.invoke(null)).apply(toast).call(), is(true)); } private void compile() throws ParseException, IOException { CompilerRunner.main(new String[] { "-o", OUTPUT_PATH, "src/test/resources/CompilerRunnerTest/file1.scotch", "src/test/resources/CompilerRunnerTest/file2.scotch", "src/test/resources/CompilerRunnerTest/file3.scotch", }); } private ClassLoader getClassLoader() throws MalformedURLException { return new URLClassLoader(new URL[] { new File(OUTPUT_PATH).toURI().toURL() }, getClass().getClassLoader()); } @SuppressWarnings("unchecked") private Callable getToast(ClassLoader classLoader, Method rye) throws ReflectiveOperationException { Class toastClass = classLoader.loadClass("a.b.c.Toast$Toast"); return (Callable) box(toastClass .getConstructor(Callable.class, Callable.class) .newInstance(rye.invoke(null), box(4))); } private void shouldHaveClasses(String... classNames) throws MalformedURLException, ClassNotFoundException { ClassLoader classLoader = getClassLoader(); for (String className : classNames) { assertThat(classLoader.loadClass(className).getName(), is(className)); } } }