Add test for luajava, compiler, and compatibility witn luavm 1.0

This commit is contained in:
James Roseborough
2010-04-03 15:14:30 +00:00
parent a548ef27fb
commit 0d18988a96
17 changed files with 237 additions and 479 deletions

View File

@@ -27,6 +27,7 @@ import junit.framework.TestSuite;
import org.luaj.vm2.WeakTableTest.WeakKeyTableTest;
import org.luaj.vm2.WeakTableTest.WeakKeyValueTableTest;
import org.luaj.vm2.lib.jse.LuaJavaCoercionTest;
import org.luaj.vm2.vm1.Luajvm1CompatibilityTest;
public class AllTests {
@@ -58,6 +59,7 @@ public class AllTests {
// compatiblity tests
suite.addTest(CompatibiltyTest.suite());
suite.addTestSuite(Luajvm1CompatibilityTest.class);
// luajc regression tests
TestSuite luajc = new TestSuite("Luajc Tests");

View File

@@ -0,0 +1,98 @@
package org.luaj.vm2.compiler;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import junit.framework.TestCase;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.Print;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.lib.JsePlatform;
abstract public class AbstractUnitTests extends TestCase {
private final String dir;
private final String jar;
private LuaTable _G;
public AbstractUnitTests(String zipfile, String dir) {
URL zip = getClass().getResource(zipfile);
this.jar = "jar:" + zip.toExternalForm()+ "!/";
this.dir = dir;
}
protected void setUp() throws Exception {
super.setUp();
_G = JsePlatform.standardGlobals();
LuaC.install();
}
protected void doTest(String file) {
try {
// load source from jar
String path = jar + dir + "/" + file;
byte[] lua = bytesFromJar(path);
// compile in memory
InputStream is = new ByteArrayInputStream(lua);
Prototype p = LuaC.compile(is, dir + "/" + file);
String actual = protoToString(p);
// load expected value from jar
byte[] luac = bytesFromJar(path + "c");
Prototype e = loadFromBytes(luac, file);
String expected = protoToString(e);
// compare results
assertEquals(expected, actual);
// dump into memory
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DumpState.dump(p, baos, false);
byte[] dumped = baos.toByteArray();
// re-undump
Prototype p2 = loadFromBytes(dumped, file);
String actual2 = protoToString(p2);
// compare again
assertEquals(actual, actual2);
} catch (IOException e) {
fail(e.toString());
}
}
protected byte[] bytesFromJar(String path) throws IOException {
URL url = new URL(path);
InputStream is = url.openStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[2048];
int n;
while ((n = is.read(buffer)) >= 0)
baos.write(buffer, 0, n);
is.close();
return baos.toByteArray();
}
protected Prototype loadFromBytes(byte[] bytes, String script)
throws IOException {
InputStream is = new ByteArrayInputStream(bytes);
return LoadState.compile(is, script);
}
protected String protoToString(Prototype p) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
Print.ps = ps;
new Print().printFunction(p, true);
return baos.toString();
}
}

View File

@@ -0,0 +1,35 @@
package org.luaj.vm2.compiler;
public class CompilerUnitTests extends AbstractUnitTests {
public CompilerUnitTests() {
super("lua5.1-tests.zip", "lua5.1-tests");
}
public void testAll() { doTest("all.lua"); }
public void testApi() { doTest("api.lua"); }
public void testAttrib() { doTest("attrib.lua"); }
public void testBig() { doTest("big.lua"); }
public void testCalls() { doTest("calls.lua"); }
public void testChecktable() { doTest("checktable.lua"); }
public void testClosure() { doTest("closure.lua"); }
public void testCode() { doTest("code.lua"); }
public void testConstruct() { doTest("constructs.lua"); }
public void testDb() { doTest("db.lua"); }
public void testErrors() { doTest("errors.lua"); }
public void testEvents() { doTest("events.lua"); }
public void testFiles() { doTest("files.lua"); }
public void testGc() { doTest("gc.lua"); }
public void testLiterals() { doTest("literals.lua"); }
public void testLocals() { doTest("locals.lua"); }
public void testMain() { doTest("main.lua"); }
public void testMath() { doTest("math.lua"); }
public void testNextvar() { doTest("nextvar.lua"); }
public void testPm() { doTest("pm.lua"); }
public void testSort() { doTest("sort.lua"); }
public void testStrings() { doTest("strings.lua"); }
public void testVararg() { doTest("vararg.lua"); }
public void testVerybig() { doTest("verybig.lua"); }
}

View File

@@ -0,0 +1,136 @@
package org.luaj.vm2.compiler;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import junit.framework.TestCase;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.lib.JsePlatform;
public class DumpLoadEndianIntTest extends TestCase {
private static final String SAVECHUNKS = "SAVECHUNKS";
private static final boolean SHOULDPASS = true;
private static final boolean SHOULDFAIL = false;
private static final String mixedscript = "return tostring(1234)..'-#!-'..tostring(23.75)";
private static final String intscript = "return tostring(1234)..'-#!-'..tostring(23)";
private static final String withdoubles = "1234-#!-23.75";
private static final String withints = "1234-#!-23";
private LuaTable _G;
protected void setUp() throws Exception {
super.setUp();
_G = JsePlatform.standardGlobals();
LuaC.install();
DumpState.ALLOW_INTEGER_CASTING = false;
}
public void testBigDoubleCompile() {
doTest( false, DumpState.NUMBER_FORMAT_FLOATS_OR_DOUBLES, false, mixedscript, withdoubles, withdoubles, SHOULDPASS );
doTest( false, DumpState.NUMBER_FORMAT_FLOATS_OR_DOUBLES, true, mixedscript, withdoubles, withdoubles, SHOULDPASS );
}
public void testLittleDoubleCompile() {
doTest( true, DumpState.NUMBER_FORMAT_FLOATS_OR_DOUBLES, false, mixedscript, withdoubles, withdoubles, SHOULDPASS );
doTest( true, DumpState.NUMBER_FORMAT_FLOATS_OR_DOUBLES, true, mixedscript, withdoubles, withdoubles, SHOULDPASS );
}
public void testBigIntCompile() {
DumpState.ALLOW_INTEGER_CASTING = true;
doTest( false, DumpState.NUMBER_FORMAT_INTS_ONLY, false, mixedscript, withdoubles, withints, SHOULDPASS );
doTest( false, DumpState.NUMBER_FORMAT_INTS_ONLY, true, mixedscript, withdoubles, withints, SHOULDPASS );
DumpState.ALLOW_INTEGER_CASTING = false;
doTest( false, DumpState.NUMBER_FORMAT_INTS_ONLY, false, mixedscript, withdoubles, withints, SHOULDFAIL );
doTest( false, DumpState.NUMBER_FORMAT_INTS_ONLY, true, mixedscript, withdoubles, withints, SHOULDFAIL );
doTest( false, DumpState.NUMBER_FORMAT_INTS_ONLY, false, intscript, withints, withints, SHOULDPASS );
doTest( false, DumpState.NUMBER_FORMAT_INTS_ONLY, true, intscript, withints, withints, SHOULDPASS );
}
public void testLittleIntCompile() {
DumpState.ALLOW_INTEGER_CASTING = true;
doTest( true, DumpState.NUMBER_FORMAT_INTS_ONLY, false, mixedscript, withdoubles, withints, SHOULDPASS );
doTest( true, DumpState.NUMBER_FORMAT_INTS_ONLY, true, mixedscript, withdoubles, withints, SHOULDPASS );
DumpState.ALLOW_INTEGER_CASTING = false;
doTest( true, DumpState.NUMBER_FORMAT_INTS_ONLY, false, mixedscript, withdoubles, withints, SHOULDFAIL );
doTest( true, DumpState.NUMBER_FORMAT_INTS_ONLY, true, mixedscript, withdoubles, withints, SHOULDFAIL );
doTest( true, DumpState.NUMBER_FORMAT_INTS_ONLY, false, intscript, withints, withints, SHOULDPASS );
doTest( true, DumpState.NUMBER_FORMAT_INTS_ONLY, true, intscript, withints, withints, SHOULDPASS );
}
public void testBigNumpatchCompile() {
doTest( false, DumpState.NUMBER_FORMAT_NUM_PATCH_INT32, false, mixedscript, withdoubles, withdoubles, SHOULDPASS );
doTest( false, DumpState.NUMBER_FORMAT_NUM_PATCH_INT32, true, mixedscript, withdoubles, withdoubles, SHOULDPASS );
}
public void testLittleNumpatchCompile() {
doTest( true, DumpState.NUMBER_FORMAT_NUM_PATCH_INT32, false, mixedscript, withdoubles, withdoubles, SHOULDPASS );
doTest( true, DumpState.NUMBER_FORMAT_NUM_PATCH_INT32, true, mixedscript, withdoubles, withdoubles, SHOULDPASS );
}
public void doTest( boolean littleEndian, int numberFormat, boolean stripDebug,
String script, String expectedPriorDump, String expectedPostDump, boolean shouldPass ) {
try {
// compile into prototype
InputStream is = new ByteArrayInputStream(script.getBytes());
Prototype p = LuaC.compile(is, "script");
// double check script result before dumping
LuaClosure f = new LuaClosure(p, _G);
LuaValue r = f.call();
String actual = r.toString();
assertEquals( expectedPriorDump, actual );
// dump into bytes
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
DumpState.dump(p, baos, stripDebug, numberFormat, littleEndian);
if ( ! shouldPass )
fail( "dump should not have succeeded" );
} catch ( Exception e ) {
if ( shouldPass )
fail( "dump threw "+e );
else
return;
}
byte[] dumped = baos.toByteArray();
// load again using compiler
is = new ByteArrayInputStream(dumped);
p = LoadState.compile(is, "dumped");
f = new LuaClosure(p, _G);
r = f.call();
actual = r.toString();
assertEquals( expectedPostDump, actual );
// write test chunk
if ( System.getProperty(SAVECHUNKS) != null && script.equals(mixedscript) ) {
new File("build").mkdirs();
String filename = "build/test-"
+(littleEndian? "little-": "big-")
+(numberFormat==DumpState.NUMBER_FORMAT_FLOATS_OR_DOUBLES? "double-":
numberFormat==DumpState.NUMBER_FORMAT_INTS_ONLY? "int-":
numberFormat==DumpState.NUMBER_FORMAT_NUM_PATCH_INT32? "numpatch4-": "???-")
+(stripDebug? "nodebug-": "debug-")
+"bin.lua";
FileOutputStream fos = new FileOutputStream(filename);
fos.write( dumped );
fos.close();
}
} catch (IOException e) {
fail(e.toString());
}
}
}

View File

@@ -0,0 +1,31 @@
package org.luaj.vm2.compiler;
/**
* Framework to add regression tests as problem areas are found.
*
* To add a new regression test:
* 1) run "unpack.sh" in the project root
* 2) add a new "lua" file in the "regressions" subdirectory
* 3) run "repack.sh" in the project root
* 4) add a line to the source file naming the new test
*
* After adding a test, check in the zip file
* rather than the individual regression test files.
*
* @author jrosebor
*/
public class RegressionTests extends AbstractUnitTests {
public RegressionTests() {
super( "regressions.zip",
"regressions" );
}
public void testModulo() { doTest("modulo.lua"); }
public void testConstruct() { doTest("construct.lua"); }
public void testBigAttrs() { doTest("bigattr.lua"); }
public void testControlChars() { doTest("controlchars.lua"); }
public void testComparators() { doTest("comparators.lua"); }
public void testMathRandomseed() { doTest("mathrandomseed.lua"); }
public void testVarargs() { doTest("varargs.lua"); }
}

View File

@@ -0,0 +1,110 @@
package org.luaj.vm2.compiler;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import junit.framework.TestCase;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.LuaDouble;
import org.luaj.vm2.LuaInteger;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Print;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.lib.BaseLib;
import org.luaj.vm2.lib.JsePlatform;
public class SimpleTests extends TestCase {
private LuaTable _G;
protected void setUp() throws Exception {
super.setUp();
_G = JsePlatform.standardGlobals();
LuaC.install();
}
private void doTest( String script ) {
try {
InputStream is = new ByteArrayInputStream( script.getBytes("UTF8") );
Prototype p = LuaC.compile( is, "script" );
assertNotNull( p );
Print.printCode( p );
// try running the code!
LuaClosure c = new LuaClosure( p, _G );
c.call();
} catch ( Exception e ) {
fail("i/o exception: "+e );
}
}
public void testTrivial() {
String s = "print( 2 )\n";
doTest( s );
}
public void testAlmostTrivial() {
String s = "print( 2 )\n" +
"print( 3 )\n";
doTest( s );
}
public void testSimple() {
String s = "print( 'hello, world' )\n"+
"for i = 2,4 do\n" +
" print( 'i', i )\n" +
"end\n";
doTest( s );
}
public void testBreak() {
String s = "a=1\n"+
"while true do\n"+
" if a>10 then\n"+
" break\n"+
" end\n"+
" a=a+1\n"+
" print( a )\n"+
"end\n";
doTest( s );
}
public void testShebang() {
String s = "#!../lua\n"+
"print( 2 )\n";
doTest( s );
}
public void testInlineTable() {
String s = "A = {g=10}\n"+
"print( A )\n";
doTest( s );
}
public void testEqualsAnd() {
String s = "print( 1 == b and b )\n";
doTest( s );
}
private static final int [] samehash = { 0, 1, -1, 2, -2, 4, 8, 16, 32, Integer.MAX_VALUE, Integer.MIN_VALUE };
private static final double [] diffhash = { .5, 1, 1.5, 1, .5, 1.5, 1.25, 2.5 };
public void testDoubleHashCode() {
for ( int i=0; i<samehash.length; i++ ) {
LuaValue j = LuaInteger.valueOf(samehash[i]);
LuaValue d = LuaDouble.valueOf(samehash[i]);
int hj = j.hashCode();
int hd = d.hashCode();
assertEquals(hj, hd);
}
for ( int i=0; i<diffhash.length; i+=2 ) {
LuaValue c = LuaValue.valueOf(diffhash[i+0]);
LuaValue d = LuaValue.valueOf(diffhash[i+1]);
int hc = c.hashCode();
int hd = d.hashCode();
assertTrue("hash codes are same: "+hc,hc!=hd);
}
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,167 @@
/*******************************************************************************
* Copyright (c) 2010 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2.vm1;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import junit.framework.TestCase;
import org.luaj.vm2.LuaValue;
/**
* Test for compatiblity between luaj 1.0 and 2.0 vms
*
*/
public class Luajvm1CompatibilityTest extends TestCase {
private static final String zipfile = "luajvm1-tests.zip";
private static String jarpath;
private void runTest(String test) {
try {
URL zip = getClass().getResource(zipfile);
jarpath = "jar:"+zip.toExternalForm()+"!/";
String luaj10 = luaj10Run(test);
String luaj20 = luaj20Run(test);
assertEquals( luaj10, luaj20 );
} catch ( IOException ioe ) {
fail( ioe.toString() );
}
}
private static InputStream open(String file) {
try {
String path = jarpath+file;
URL url = new URL(path);
return url.openStream();
} catch ( Exception e ) {
return null;
}
}
private String luaj10Run(String test) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
org.luaj.vm.Platform.setInstance(new org.luaj.platform.J2sePlatform() {
public InputStream openFile(String fileName) {
return open( fileName );
}
});
org.luaj.vm.LuaState vm = org.luaj.vm.Platform.newLuaState();
org.luaj.compiler.LuaC.install();
org.luaj.lib.DebugLib.install( vm );
org.luaj.lib.BaseLib.redirectOutput(outputStream);
vm.getglobal("require");
vm.pushstring(test);
vm.call(1,0);
return outputStream.toString();
} finally {
org.luaj.lib.BaseLib.restoreStandardOutput();
outputStream.close();
}
}
private String luaj20Run(String test) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream( outputStream );
try {
org.luaj.vm2.LuaTable _G = org.luaj.vm2.lib.JsePlatform.standardGlobals();
_G.get("package").get("loaders").checktable().insert(1, new org.luaj.vm2.lib.OneArgFunction(_G) {
public LuaValue call(LuaValue arg) {
String name = arg.toString();
String file = name + ".lua";
InputStream is = open( file );
if ( is == null )
return LuaValue.valueOf("not found: "+file);
try {
return org.luaj.vm2.LoadState.load(is, name, env);
} catch (IOException e) {
return LuaValue.valueOf(e.toString());
} finally {
try { is.close(); } catch ( IOException ioe ) {}
}
}
});
org.luaj.vm2.compiler.LuaC.install();
org.luaj.vm2.lib.BaseLib.instance.STDOUT = printStream;
_G.get("require").call(LuaValue.valueOf(test));
printStream.flush();
return outputStream.toString();
} finally {
printStream.close();
// script.close();
}
}
public Luajvm1CompatibilityTest() {
}
public void testTest1() { runTest("test1"); }
public void testTest2() { runTest("test2"); }
public void testTest3() { runTest("test3"); }
public void testTest4() { runTest("test4"); }
public void testTest5() { runTest("test5"); }
public void testTest6() { runTest("test6"); }
public void testTest7() { runTest("test7"); }
public void testTest8() { runTest("test8"); }
public void testTest9() { runTest("test9"); }
public void testAutoload() { runTest("autoload"); }
public void testBaseLib() { runTest("baselib"); }
public void testBoolean() { runTest("boolean"); }
public void testCalls() { runTest("calls"); }
public void testCoercions() { runTest("coercions"); }
public void testCoroutines() { runTest("coroutines"); }
public void testCompare() { runTest("compare"); }
public void testDebugLib() { runTest("debuglib"); }
public void testErrors() { runTest("errors"); }
public void testHugeTable() { runTest("hugetable"); }
public void testIoLib() { runTest("iolib"); }
public void testLoops() { runTest("loops"); }
public void testManyLocals() { runTest("manylocals"); }
public void testMathLib() { runTest("mathlib"); }
public void testMetatables() { runTest("metatables"); }
public void testModule() { runTest("module"); }
public void testNext() { runTest("next"); }
public void testOsLib() { runTest("oslib"); }
public void testPcalls() { runTest("pcalls"); }
public void testPrint() { runTest("print"); }
public void testRequire() { runTest("require"); }
public void testSelect() { runTest("select"); }
public void testSetfenv() { runTest("setfenv"); }
public void testSetlist() { runTest("setlist"); }
public void testSimpleMetatables() { runTest("simplemetatables"); }
public void testStack() { runTest("stack"); }
public void testStrLib() { runTest("strlib"); }
public void testSort() { runTest("sort"); }
public void testTable() { runTest("table"); }
public void testTailcall() { runTest("tailcall"); }
public void testType() { runTest("type"); }
public void testUpvalues() { runTest("upvalues"); }
public void testUpvalues2() { runTest("upvalues2"); }
public void testUpvalues3() { runTest("upvalues3"); }
public void testVarargs() { runTest("varargs"); }
public void testWeakTable() { runTest("weaktable"); }
}

Binary file not shown.