diff --git a/src/main/java/lua/CallFrame.java b/src/main/java/lua/CallFrame.java index fee223e7..413d0387 100644 --- a/src/main/java/lua/CallFrame.java +++ b/src/main/java/lua/CallFrame.java @@ -24,7 +24,7 @@ public class CallFrame { public final Proto p; private final LValue[] k; private final int nresults; - private int pc = 0; + int pc = 0; boolean done = false; CallFrame(StackState state, Closure c, int base, int nargs, int nresults) { diff --git a/src/test/java/lua/StandardTest.java b/src/test/java/lua/StandardTest.java new file mode 100644 index 00000000..b364186c --- /dev/null +++ b/src/test/java/lua/StandardTest.java @@ -0,0 +1,114 @@ +package lua; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import lua.Builtin; +import lua.StackState; +import lua.io.Closure; +import lua.io.LoadState; +import lua.io.Proto; +import lua.value.LValue; + +public class StandardTest extends TestCase { + + public static Test suite() throws IOException { + ZipEntry file; + + final HashMap tests = new HashMap(); + final HashMap results = new HashMap(); + + InputStream zipStream = StandardTest.class.getResourceAsStream( "/standard-tests.zip" ); + ZipInputStream testSuiteArchive = new ZipInputStream( zipStream ); + try { + while ( ( file = testSuiteArchive.getNextEntry() ) != null ) { + final String entryName = file.getName(); + if ( entryName.endsWith( ".luac" ) ) { + Proto p = LoadState.undump( new StackState(), testSuiteArchive, entryName ); + tests.put( entryName.substring( 0, entryName.length() - 5 ), p ); + } else if ( entryName.endsWith( ".out" ) ) { + results.put( entryName.substring( 0, entryName.length() - 4 ), readString( testSuiteArchive ) ); + } + } + } finally { + testSuiteArchive.close(); + } + + TestSuite suite = new TestSuite(); + + for ( final String test : tests.keySet() ) { + final Proto code = tests.get( test ); + final String expectedResult = results.get( test ); + + if ( code != null && expectedResult != null ) { + suite.addTest( new StandardTest( test, code, expectedResult ) ); + } + } + + return suite; + } + + private final Proto code; + private final String expectedResult; + + public StandardTest( String name, Proto code, String expectedResult ) { + super( name ); + this.code = code; + this.expectedResult = expectedResult; + } + + public void runTest() { + StackState state = new StackState(); + Closure c = new Closure( state, code ); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + Builtin.redirectOutput( output ); + try { + try { + state.doCall( c, new LValue[0], 0 ); + } catch ( RuntimeException exn ) { + StackTraceElement[] stackTrace = new StackTraceElement[state.cc+1]; + for ( int i = 0; i <= state.cc; ++i ) { + CallFrame call = state.calls[i]; + Proto p = call.p; + int line = p.lineinfo[call.pc]; + String func = call.cl.luaAsString(); + stackTrace[state.cc - i] = new StackTraceElement(getName(), func, getName()+".lua", line ); + } + + RuntimeException newExn = new RuntimeException( exn ); + newExn.setStackTrace( stackTrace ); + newExn.printStackTrace(); + throw newExn; + } + + final String actualResult = new String( output.toByteArray() ); + + assertEquals( expectedResult, actualResult ); + } finally { + Builtin.restoreStandardOutput(); + } + } + + private static String readString( InputStream is ) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + copy( is, baos ); + return new String( baos.toByteArray() ); + } + + private static 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/standard-tests.zip b/src/test/res/standard-tests.zip new file mode 100644 index 00000000..457ebd3d Binary files /dev/null and b/src/test/res/standard-tests.zip differ