package me.august.lumen; import me.august.lumen.compile.Driver; import me.august.lumen.compile.parser.ast.ProgramNode; import me.august.lumen.compile.scanner.TokenSource; import org.junit.Assert; import org.junit.Test; import java.io.PrintStream; import java.io.StringReader; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; public class RunProgramTest { private static final String SOURCE_PATH = "/program.lm"; private static Class<?> load(final String name, final byte[] bytecode) { return new ClassLoader() { public Class load() { return defineClass(name, bytecode, 0, bytecode.length); } }.load(); } private byte[] compile(String src) { Driver driver = new Driver(src); TokenSource lexer = driver.phase1Scanning(); ProgramNode pgrm = driver.phase2Parsing(lexer); driver.phase3Resolving(pgrm); driver.phase4Analysis(pgrm); return driver.phase5Bytecode(pgrm); } @Test public void testRun() throws Exception { String src = Util.readResource(SOURCE_PATH); Class<?> cls = load("Example", compile(src)); Method method = cls.getMethod("run"); Object instance = cls.newInstance(); PrintStream old = System.out; PrintStreamRecorder recorder = new PrintStreamRecorder(System.out); System.setOut(recorder); method.invoke(instance); System.setOut(old); List<String> expected = new ArrayList<>(); // println expected.add("Hello, world!"); // loop expected.add("0"); expected.add("1"); expected.add("2"); Assert.assertEquals(expected, recorder.lines); } private static final class PrintStreamRecorder extends PrintStream { private List<String> lines = new ArrayList<>(); public PrintStreamRecorder(PrintStream ps) { super(ps); } @Override public void println(String x) { lines.add(x); } @Override public void println(int x) { lines.add(String.valueOf(x)); } } }