From 241edfbf378b35c3d09d239aa768c62989c1b460 Mon Sep 17 00:00:00 2001 From: Ian Farmer Date: Wed, 4 Jul 2007 04:25:06 +0000 Subject: [PATCH] Added a JUnit test case. Unfortunately, it will almost certainly not work on Windows in its present form, and only one of the test cases passes. In addition two changes to print() were made: output can be redirected to an arbitrary OutputStream and tabs are no longer printed at the end of each line. --- .classpath | 1 + src/main/java/lua/Builtin.java | 26 +++-- src/test/java/lua/LuaJTest.java | 166 ++++++++++++++++++++++++++++++++ src/test/res/test7-expected.out | 6 ++ 4 files changed, 193 insertions(+), 6 deletions(-) create mode 100644 src/test/java/lua/LuaJTest.java create mode 100644 src/test/res/test7-expected.out diff --git a/.classpath b/.classpath index c09db0ba..fc39bf58 100644 --- a/.classpath +++ b/.classpath @@ -5,5 +5,6 @@ + diff --git a/src/main/java/lua/Builtin.java b/src/main/java/lua/Builtin.java index 56c26f4c..07d74dd3 100644 --- a/src/main/java/lua/Builtin.java +++ b/src/main/java/lua/Builtin.java @@ -3,8 +3,10 @@ */ package lua; +import java.io.OutputStream; +import java.io.PrintStream; + import lua.value.LFunction; -import lua.value.LString; import lua.value.LTable; import lua.value.LValue; @@ -22,6 +24,8 @@ final class Builtin extends LFunction { private static final String[] NAMES = { "print", "pairs", "getmetatable", "setmetatable" }; + private static PrintStream stdout = System.out; + private int id; private Builtin( int id ) { this.id = id; @@ -35,11 +39,13 @@ final class Builtin extends LFunction { public void luaStackCall(CallFrame call, int base, int top, int nresults) { switch ( id ) { case PRINT: - for ( int i=base+1; i= 0) call.adjustTop(base + nresults); } + + static void redirectOutput( OutputStream newStdOut ) { + stdout = new PrintStream( newStdOut ); + } + + static void restoreStandardOutput() { + stdout = System.out; + } -} \ No newline at end of file +} diff --git a/src/test/java/lua/LuaJTest.java b/src/test/java/lua/LuaJTest.java new file mode 100644 index 00000000..3d22b0b0 --- /dev/null +++ b/src/test/java/lua/LuaJTest.java @@ -0,0 +1,166 @@ +package lua; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import junit.framework.TestCase; +import lua.StackState; +import lua.addon.luajava.LuaJava; +import lua.io.Closure; +import lua.io.LoadState; +import lua.io.Proto; +import lua.value.LValue; + + +public class LuaJTest extends TestCase { + + public void testTest1() throws IOException, InterruptedException { + runTest( "test1" ); + } + + public void testTest2() throws IOException, InterruptedException { + runTest( "test2" ); + } + + public void testTest3() throws IOException, InterruptedException { + runTest( "test3" ); + } + + public void testTest4() throws IOException, InterruptedException { + runTest( "test4" ); + } + + public void testTest5() throws IOException, InterruptedException { + runTest( "test5" ); + } + + public void testTest6() throws IOException, InterruptedException { + runTest( "test6" ); + } + + public void testTest7() throws IOException, InterruptedException { + runTest( "test7" ); + } + + private void runTest( String testName ) throws IOException, InterruptedException { + // add LuaJava bindings + LuaJava.install(); + + // new lua state + StackState state = new StackState(); + + // load the file + Proto p = loadScriptResource( state, testName, "/" + testName + ".luac" ); + + // Replace System.out with a ByteArrayOutputStream + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + Builtin.redirectOutput( outputStream ); + try { + // create closure and execute + Closure c = new Closure( state, p ); + state.doCall(c, new LValue[0], 0); + + final String actualOutput = new String( outputStream.toByteArray() ); + final String expectedOutput = getExpectedOutput( testName ); + + assertEquals( expectedOutput, actualOutput ); + } finally { + Builtin.restoreStandardOutput(); + outputStream.close(); + } + } + + private Proto loadScriptResource( StackState state, String name, String path ) throws IOException { + InputStream compiledScript = getClass().getResourceAsStream( path ); + try { + return LoadState.undump(state, compiledScript, name); + } finally { + compiledScript.close(); + } + } + + private String getExpectedOutput( final String testName ) throws IOException, InterruptedException { + String expectedOutputName = "/" + testName + "-expected.out"; + InputStream is = getClass().getResourceAsStream( expectedOutputName ); + if ( is != null ) { + try { + return readString( is ); + } finally { + is.close(); + } + } else { + InputStream script = getClass().getResourceAsStream( "/" + testName + ".luac" ); + try { + return collectProcessOutput( new String[] { "lua", "-" }, script ); + } finally { + script.close(); + } + } + } + + private String collectProcessOutput( String[] cmd, final InputStream input ) throws IOException, InterruptedException { + Runtime r = Runtime.getRuntime(); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final Process p = r.exec( cmd ); + try { + // start a thread to write the given input to the subprocess. + Thread inputCopier = (new Thread() { + public void run() { + try { + OutputStream processStdIn = p.getOutputStream(); + try { + copy( input, processStdIn ); + } finally { + processStdIn.close(); + } + } catch ( IOException e ) { + e.printStackTrace(); + } + } + }); + inputCopier.start(); + + // start another thread to read output from the subprocess. + Thread outputCopier = (new Thread() { + public void run() { + try { + InputStream processStdOut = p.getInputStream(); + try { + copy( processStdOut, baos ); + } finally { + processStdOut.close(); + } + } catch ( IOException ioe ) { + ioe.printStackTrace(); + } + } + }); + outputCopier.start(); + + p.waitFor(); + inputCopier.join(); + outputCopier.join(); + + return new String( baos.toByteArray() ); + + } finally { + p.destroy(); + } + } + + private String readString( InputStream is ) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy( is, baos ); + return new String( baos.toByteArray() ); + } + + private void copy( InputStream is, OutputStream os ) throws IOException { + byte[] buf = new byte[ 1024 ]; + int r; + while ( ( r = is.read( buf ) ) >= 0 ) { + os.write( buf, 0, r ); + } + } + +} diff --git a/src/test/res/test7-expected.out b/src/test/res/test7-expected.out new file mode 100644 index 00000000..5d3459be --- /dev/null +++ b/src/test/res/test7-expected.out @@ -0,0 +1,6 @@ +java.lang.Object@b1b4c3 +SampleClass@72ffb +Hello +Hello +World +Square root of 9 is 3.0