diff --git a/.classpath b/.classpath
index f799784c..f8b7ddb4 100644
--- a/.classpath
+++ b/.classpath
@@ -6,7 +6,6 @@
-
diff --git a/src/test/errors/args.lua b/src/test/errors/args.lua
new file mode 100644
index 00000000..d35942da
--- /dev/null
+++ b/src/test/errors/args.lua
@@ -0,0 +1,133 @@
+-- utilities to check that args of various types pass or fail
+-- argument type checking
+
+anylua = { nil, 'abc', 1.23, true, {aa=11,bb==22}, print }
+
+somestring = { 'abc' }
+somenumber = { 1.23 }
+somestrnum = { 'abc', 1.23 }
+someboolean = { true }
+sometable = { {aa=11,bb=22} }
+somefunction = { print }
+somenil = { nil }
+
+local function contains(set,val)
+ local m = #set
+ for i=1,m do
+ if set[i] == val then
+ return true
+ end
+ end
+ return false
+end
+
+local function except(some)
+ local n = #anylua
+ local z = {}
+ local j = 1
+ for i=1,n do
+ if not contains(some, anylua[i]) then
+ z[j] = anylua[i]
+ j = j + 1
+ end
+ end
+ return z
+end
+
+notastring = except(somestring)
+notanumber = except(somenumber)
+notastrnum = except(somestrnum)
+notaboolean = except(someboolean)
+notatable = except(sometable)
+notafunction = except(somefunction)
+notanil = except(somenil)
+
+local function signature(name,arglist)
+ local t = {}
+ for i=1,#arglist do
+ if type(arglist[i]) == 'table' then
+ t[i] = 'table'
+ elseif type(arglist[i]) == 'function' then
+ t[i] = 'function'
+ else
+ t[i] = tostring(arglist[i])
+ end
+ end
+ return name..'('..table.concat(t,',')..')'
+end
+
+local function expand(argsets, typesets, ...)
+ local n = typesets and #typesets or 0
+ if n <= 0 then
+ table.insert(argsets,{...})
+ return argsets
+ end
+
+ local t = typesets[1]
+ local s = {select(2,unpack(typesets))}
+ local m = #t
+ for i=1,m do
+ expand(argsets, s, t[i], ...)
+ end
+ return argsets
+end
+
+local function arglists(typesets)
+ local argsets = expand({},typesets)
+ return ipairs(argsets)
+end
+
+local function lookup( name )
+ return loadstring('return '..name)()
+end
+
+local function invoke( name, arglist )
+ local s,c = pcall(lookup, name)
+ if not s then return s,c end
+ return pcall(c, unpack(arglist))
+end
+
+-- check that all combinations of arguments pass
+function checkallpass( name, typesets )
+ for i,v in arglists(typesets) do
+ local sig = signature(name,v)
+ local s,e = invoke( name, v )
+ if s then
+ print( 'pass', sig )
+ else
+ print( 'fail', sig, e )
+ end
+ end
+end
+
+-- check that all combinations of arguments fail in some way,
+-- ignore error messages
+function checkallfail( name, typesets )
+ for i,v in arglists(typesets) do
+ local sig = signature(name,v)
+ local s,e,f,g = invoke( name, v )
+ if not s then
+ print( 'ok', sig )
+ else
+ print( 'needcheck', sig, e, f, g )
+ end
+ end
+end
+
+-- check that all combinations of arguments fail in some way,
+-- ignore error messages
+function checkallerrors( name, typesets, template )
+ for i,v in arglists(typesets) do
+ local sig = signature(name,v)
+ local s,e,f,g = invoke( name, v )
+ if not s then
+ if string.match(e, template) then
+ print( 'ok', sig, 'template='..template )
+ else
+ print( 'badmsg', sig, "template='"..template.."' actual='"..e.."'" )
+ end
+ else
+ print( 'needcheck', sig, e, f, g )
+ end
+ end
+end
diff --git a/src/test/errors/baselibargs.lua b/src/test/errors/baselibargs.lua
new file mode 100644
index 00000000..d48ad2ad
--- /dev/null
+++ b/src/test/errors/baselibargs.lua
@@ -0,0 +1,9 @@
+package.path = "?.lua;src/test/errors/?.lua"
+require 'args'
+
+
+-- arg types for basic library functions
+local notastrnumnil={true,{},print}
+checkallpass('dofile', {{nil,'src/test/errors/args.lua','args.lua'}})
+checkallfail('dofile', {notastrnumnil})
+checkallerrors('dofile', {notastrnumnil}, 'bad argument')
\ No newline at end of file
diff --git a/src/test/java/org/luaj/AllTests.java b/src/test/java/org/luaj/AllTests.java
index 4aa7f427..cc79dbc6 100644
--- a/src/test/java/org/luaj/AllTests.java
+++ b/src/test/java/org/luaj/AllTests.java
@@ -10,13 +10,14 @@ public class AllTests {
// debug tests
TestSuite vm = new TestSuite("VM");
+ vm.addTestSuite(org.luaj.vm.CompatibiltyTest.class);
+ vm.addTestSuite(org.luaj.vm.ErrorMessageTest.class);
vm.addTestSuite(org.luaj.vm.LuaStateTest.class);
vm.addTestSuite(org.luaj.vm.LoadStateTest.class);
vm.addTestSuite(org.luaj.vm.LStringTest.class);
vm.addTestSuite(org.luaj.vm.MathLibTest.class);
vm.addTestSuite(org.luaj.vm.LTableTest.class);
vm.addTestSuite(org.luaj.vm.LWeakTableTest.class);
- vm.addTestSuite(org.luaj.vm.LuaJTest.class);
suite.addTest(vm);
// compiler tests
diff --git a/src/test/java/org/luaj/debug/DebugStackStateTest.java b/src/test/java/org/luaj/debug/DebugStackStateTest.java
index 86a204c8..c585e2e6 100644
--- a/src/test/java/org/luaj/debug/DebugStackStateTest.java
+++ b/src/test/java/org/luaj/debug/DebugStackStateTest.java
@@ -21,6 +21,7 @@
******************************************************************************/
package org.luaj.debug;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -33,13 +34,12 @@ import org.luaj.vm.LClosure;
import org.luaj.vm.LPrototype;
import org.luaj.vm.LValue;
import org.luaj.vm.LoadState;
-import org.luaj.vm.LuaState;
import org.luaj.vm.Platform;
public class DebugStackStateTest extends TestCase {
public void testDebugStackState() throws InterruptedException, IOException {
- String script = "/test6.lua";
+ String script = "src/test/res/test6.lua";
// set up the vm
System.setProperty(Platform.PROPERTY_LUAJ_DEBUG, "true");
@@ -51,7 +51,7 @@ public class DebugStackStateTest extends TestCase {
final DebugLuaState state = (DebugLuaState) Platform.newLuaState();
LuaC.install();
- InputStream is = getClass().getResourceAsStream( script );
+ InputStream is = new FileInputStream( script );
LPrototype p = LoadState.undump(state, is, script);
// create closure and execute
diff --git a/src/test/java/org/luaj/jit/LuaJitTest.java b/src/test/java/org/luaj/jit/LuaJitTest.java
index 596cef4d..9fbd1915 100644
--- a/src/test/java/org/luaj/jit/LuaJitTest.java
+++ b/src/test/java/org/luaj/jit/LuaJitTest.java
@@ -4,17 +4,17 @@ import java.io.IOException;
import org.luaj.jit.LuaJit;
import org.luaj.vm.LPrototype;
-import org.luaj.vm.LuaJTest;
+import org.luaj.vm.CompatibiltyTest;
import org.luaj.vm.LuaState;
/**
* Suite of standard tests, but using the LuaJit compiler
* for all loaded prototypes.
*/
-public class LuaJitTest extends LuaJTest {
+public class LuaJitTest extends CompatibiltyTest {
- protected LPrototype loadScriptResource( LuaState state, String name ) throws IOException {
- LPrototype p = super.loadScriptResource(state, name);
+ protected LPrototype loadScript( LuaState state, String name ) throws IOException {
+ LPrototype p = super.loadScript(state, name);
return LuaJit.jitCompile(p);
}
diff --git a/src/test/java/org/luaj/vm/CompatibiltyTest.java b/src/test/java/org/luaj/vm/CompatibiltyTest.java
new file mode 100644
index 00000000..69f633f5
--- /dev/null
+++ b/src/test/java/org/luaj/vm/CompatibiltyTest.java
@@ -0,0 +1,178 @@
+package org.luaj.vm;
+
+import java.io.IOException;
+
+/**
+ * Compatibility tests for the Luaj VM
+ *
+ * Results are compared for exact match with
+ * the installed C-based lua environment.
+ */
+public class CompatibiltyTest extends ScriptDrivenTest {
+
+ private static final String dir = "src/test/res";
+
+ public CompatibiltyTest() {
+ super(dir);
+ }
+
+ 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");
+ }
+
+ public void testTest8() throws IOException, InterruptedException {
+ runTest("test8");
+ }
+
+ public void testArgtypes() throws IOException, InterruptedException {
+ runTest("argtypes");
+ }
+
+ public void testAutoload() throws IOException, InterruptedException {
+ runTest("autoload");
+ }
+
+ public void testBaseLib() throws IOException, InterruptedException {
+ runTest("baselib");
+ }
+
+ public void testBoolean() throws IOException, InterruptedException {
+ runTest("boolean");
+ }
+
+ public void testCalls() throws IOException, InterruptedException {
+ runTest("calls");
+ }
+
+ public void testCoercions() throws IOException, InterruptedException {
+ runTest("coercions");
+ }
+
+ public void testCoroutines() throws IOException, InterruptedException {
+ runTest("coroutines");
+ }
+
+ public void testCompare() throws IOException, InterruptedException {
+ runTest("compare");
+ }
+
+ public void testErrors() throws IOException, InterruptedException {
+ runTest("errors");
+ }
+
+ public void testHugeTable() throws IOException, InterruptedException {
+ runTest("hugetable");
+ }
+
+ public void testLoops() throws IOException, InterruptedException {
+ runTest("loops");
+ }
+
+ public void testManyLocals() throws IOException, InterruptedException {
+ runTest("manylocals");
+ }
+
+ public void testMathLib() throws IOException, InterruptedException {
+ runTest("mathlib");
+ }
+
+ public void testMetatables() throws IOException, InterruptedException {
+ runTest("metatables");
+ }
+
+ public void testModule() throws IOException, InterruptedException {
+ runTest("module");
+ }
+
+ public void testNext() throws IOException, InterruptedException {
+ runTest("next");
+ }
+
+ public void testPcalls() throws IOException, InterruptedException {
+ runTest("pcalls");
+ }
+
+ public void testRequire() throws IOException, InterruptedException {
+ runTest("require");
+ }
+
+ public void testSelect() throws IOException, InterruptedException {
+ runTest("select");
+ }
+
+ public void testSetfenv() throws IOException, InterruptedException {
+ runTest("setfenv");
+ }
+
+ public void testSetlist() throws IOException, InterruptedException {
+ runTest("setlist");
+ }
+
+ public void testSimpleMetatables() throws IOException, InterruptedException {
+ runTest("simplemetatables");
+ }
+
+ public void testStack() throws IOException, InterruptedException {
+ runTest("stack");
+ }
+
+ public void testStrLib() throws IOException, InterruptedException {
+ runTest("strlib");
+ }
+
+ public void testSort() throws IOException, InterruptedException {
+ runTest("sort");
+ }
+
+ public void testTable() throws IOException, InterruptedException {
+ runTest("table");
+ }
+
+ public void testTailcall() throws IOException, InterruptedException {
+ runTest("tailcall");
+ }
+
+ public void testType() throws IOException, InterruptedException {
+ runTest("type");
+ }
+
+ public void testUpvalues() throws IOException, InterruptedException {
+ runTest("upvalues");
+ }
+
+ public void testUpvalues2() throws IOException, InterruptedException {
+ runTest("upvalues2");
+ }
+
+ public void testUpvalues3() throws IOException, InterruptedException {
+ runTest("upvalues3");
+ }
+
+ public void testWeakTable() throws IOException, InterruptedException {
+ runTest("weaktable");
+ }
+}
diff --git a/src/test/java/org/luaj/vm/ErrorMessageTest.java b/src/test/java/org/luaj/vm/ErrorMessageTest.java
new file mode 100644
index 00000000..62a1910a
--- /dev/null
+++ b/src/test/java/org/luaj/vm/ErrorMessageTest.java
@@ -0,0 +1,22 @@
+package org.luaj.vm;
+
+import java.io.IOException;
+
+/**
+ * Test error messages produced by luaj.
+ */
+public class ErrorMessageTest extends ScriptDrivenTest {
+
+ private static final String dir = "src/test/errors";
+
+ public ErrorMessageTest() {
+ super(dir);
+ }
+
+ public void testBaseLibArgs() throws IOException, InterruptedException {
+ runTest("baselibargs");
+ }
+
+
+
+}
diff --git a/src/test/java/org/luaj/vm/LuaJTest.java b/src/test/java/org/luaj/vm/LuaJTest.java
deleted file mode 100644
index c90a1635..00000000
--- a/src/test/java/org/luaj/vm/LuaJTest.java
+++ /dev/null
@@ -1,345 +0,0 @@
-package org.luaj.vm;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import junit.framework.TestCase;
-
-import org.luaj.TestPlatform;
-import org.luaj.compiler.LuaC;
-import org.luaj.lib.BaseLib;
-
-public class LuaJTest extends TestCase {
-
- protected void setUp() throws Exception {
- super.setUp();
- Platform.setInstance(new TestPlatform());
- }
-
- 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");
- }
-
- public void testTest8() throws IOException, InterruptedException {
- runTest("test8");
- }
-
- public void testArgtypes() throws IOException, InterruptedException {
- runTest("argtypes");
- }
-
- public void testAutoload() throws IOException, InterruptedException {
- runTest("autoload");
- }
-
- public void testBaseLib() throws IOException, InterruptedException {
- runTest("baselib");
- }
-
- public void testBoolean() throws IOException, InterruptedException {
- runTest("boolean");
- }
-
- public void testCalls() throws IOException, InterruptedException {
- runTest("calls");
- }
-
- public void testCoercions() throws IOException, InterruptedException {
- runTest("coercions");
- }
-
- public void testCoroutines() throws IOException, InterruptedException {
- runTest("coroutines");
- }
-
- public void testCompare() throws IOException, InterruptedException {
- runTest("compare");
- }
-
- public void testErrors() throws IOException, InterruptedException {
- runTest("errors");
- }
-
- public void testHugeTable() throws IOException, InterruptedException {
- runTest("hugetable");
- }
-
- public void testLoops() throws IOException, InterruptedException {
- runTest("loops");
- }
-
- public void testManyLocals() throws IOException, InterruptedException {
- runTest("manylocals");
- }
-
- public void testMathLib() throws IOException, InterruptedException {
- runTest("mathlib");
- }
-
- public void testMetatables() throws IOException, InterruptedException {
- runTest("metatables");
- }
-
- public void testModule() throws IOException, InterruptedException {
- runTest("module");
- }
-
- public void testNext() throws IOException, InterruptedException {
- runTest("next");
- }
-
- public void testPcalls() throws IOException, InterruptedException {
- runTest("pcalls");
- }
-
- public void testRequire() throws IOException, InterruptedException {
- runTest("require");
- }
-
- public void testSelect() throws IOException, InterruptedException {
- runTest("select");
- }
-
- public void testSetfenv() throws IOException, InterruptedException {
- runTest("setfenv");
- }
-
- public void testSetlist() throws IOException, InterruptedException {
- runTest("setlist");
- }
-
- public void testSimpleMetatables() throws IOException, InterruptedException {
- runTest("simplemetatables");
- }
-
- public void testStack() throws IOException, InterruptedException {
- runTest("stack");
- }
-
- public void testStrLib() throws IOException, InterruptedException {
- runTest("strlib");
- }
-
- public void testSort() throws IOException, InterruptedException {
- runTest("sort");
- }
-
- public void testTable() throws IOException, InterruptedException {
- runTest("table");
- }
-
- public void testTailcall() throws IOException, InterruptedException {
- runTest("tailcall");
- }
-
- public void testType() throws IOException, InterruptedException {
- runTest("type");
- }
-
- public void testUpvalues() throws IOException, InterruptedException {
- runTest("upvalues");
- }
-
- public void testUpvalues2() throws IOException, InterruptedException {
- runTest("upvalues2");
- }
-
- public void testUpvalues3() throws IOException, InterruptedException {
- runTest("upvalues3");
- }
-
- public void testWeakTable() throws IOException, InterruptedException {
- runTest("weaktable");
- }
-
- // */
- private void runTest(String testName) throws IOException,
- InterruptedException {
-
- // new lua state
- LuaState state = Platform.newLuaState();
-
- // install the compiler
- LuaC.install();
-
- // load the file
- LPrototype p = loadScriptResource(state, testName);
- p.source = LString.valueOf("stdin");
-
- // Replace System.out with a ByteArrayOutputStream
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- BaseLib.redirectOutput(outputStream);
- try {
- // create closure and execute
- LClosure c = p.newClosure(state._G);
- state.pushlvalue(c);
- state.call(0, 0);
-
- final String actualOutput = new String(outputStream.toByteArray());
- final String expectedOutput = getExpectedOutput(testName);
-
- assertEquals(expectedOutput, actualOutput);
- } finally {
- BaseLib.restoreStandardOutput();
- outputStream.close();
- }
- }
-
- protected LPrototype loadScriptResource(LuaState state, String name)
- throws IOException {
- InputStream script = getClass().getResourceAsStream(
- "/" + name + ".luac");
- if (script == null) {
- script = getClass().getResourceAsStream("/" + name + ".lua");
- if (script == null) {
- fail("Could not load script for test case: " + name);
- }
- }
-
- try {
- // Use "stdin" instead of resource name so that output matches
- // standard Lua.
- return LoadState.undump(state, script, "stdin");
- } finally {
- script.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;
- // script = getClass().getResourceAsStream( "/" + testName + ".luac"
- // );
- // if ( script == null ) {
- script = getClass().getResourceAsStream("/" + testName + ".lua");
- if (script == null) {
- fail("Could not find script for test case: " + testName);
- }
- // }
- 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();
-
- // start another thread to read output from the subprocess.
- Thread errorCopier = (new Thread() {
- public void run() {
- try {
- InputStream processError = p.getErrorStream();
- try {
- copy(processError, System.err);
- } finally {
- processError.close();
- }
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
- });
- errorCopier.start();
-
- p.waitFor();
- inputCopier.join();
- outputCopier.join();
- errorCopier.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/java/org/luaj/vm/ScriptDrivenTest.java b/src/test/java/org/luaj/vm/ScriptDrivenTest.java
new file mode 100644
index 00000000..66734d93
--- /dev/null
+++ b/src/test/java/org/luaj/vm/ScriptDrivenTest.java
@@ -0,0 +1,190 @@
+package org.luaj.vm;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import junit.framework.TestCase;
+
+import org.luaj.compiler.LuaC;
+import org.luaj.lib.BaseLib;
+import org.luaj.platform.J2sePlatform;
+
+abstract
+public class ScriptDrivenTest extends TestCase {
+
+ private final String basedir;
+
+ protected ScriptDrivenTest( String directory ) {
+ basedir = directory;
+ }
+
+ // */
+ protected void runTest(String testName) throws IOException,
+ InterruptedException {
+
+ // set platform relative to directory
+ Platform.setInstance(new J2sePlatform() {
+ public InputStream openFile(String fileName) {
+ return super.openFile(basedir+"/"+fileName);
+ }
+ });
+
+ // new lua state
+ LuaState state = Platform.newLuaState();
+
+ // install the compiler
+ LuaC.install();
+
+ // load the file
+ LPrototype p = loadScript(state, testName);
+ p.source = LString.valueOf("stdin");
+
+ // Replace System.out with a ByteArrayOutputStream
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ BaseLib.redirectOutput(outputStream);
+ try {
+ // create closure and execute
+ LClosure c = p.newClosure(state._G);
+ state.pushlvalue(c);
+ state.call(0, 0);
+
+ final String actualOutput = new String(outputStream.toByteArray());
+ final String expectedOutput = getExpectedOutput(testName);
+
+ assertEquals(expectedOutput, actualOutput);
+ } finally {
+ BaseLib.restoreStandardOutput();
+ outputStream.close();
+ }
+ }
+
+ protected LPrototype loadScript(LuaState state, String name)
+ throws IOException {
+ File file = new File(basedir+"/"+name+".luac");
+ if ( !file.exists() )
+ file = new File(basedir+"/"+name+".lua");
+ if ( !file.exists() )
+ fail("Could not load script for test case: " + name);
+
+ InputStream script = new FileInputStream(file);
+ try {
+ // Use "stdin" instead of resource name so that output matches
+ // standard Lua.
+ return LoadState.undump(state, script, "stdin");
+ } finally {
+ script.close();
+ }
+ }
+
+ private String getExpectedOutput(final String name) throws IOException,
+ InterruptedException {
+ String expectedOutputName = basedir+"/"+name+"-expected.out";
+ InputStream is = getClass().getResourceAsStream(expectedOutputName);
+ if (is != null) {
+ try {
+ return readString(is);
+ } finally {
+ is.close();
+ }
+ } else {
+ File file = new File(basedir+"/"+name+".lua");
+ if ( !file.exists() )
+ fail("Could not load script for test case: " + name);
+ InputStream script = new FileInputStream(file);
+ // }
+ 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();
+
+ // start another thread to read output from the subprocess.
+ Thread errorCopier = (new Thread() {
+ public void run() {
+ try {
+ InputStream processError = p.getErrorStream();
+ try {
+ copy(processError, System.err);
+ } finally {
+ processError.close();
+ }
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+ });
+ errorCopier.start();
+
+ p.waitFor();
+ inputCopier.join();
+ outputCopier.join();
+ errorCopier.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/version.properties b/version.properties
index 87d19161..2d54a2b4 100644
--- a/version.properties
+++ b/version.properties
@@ -1 +1 @@
-version: 0.40
+version: 0.41