Add framework to test error messages and argument type checking.
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
<classpathentry kind="src" path="src/j2se"/>
|
||||
<classpathentry kind="src" path="src/script"/>
|
||||
<classpathentry kind="src" path="src/test/java"/>
|
||||
<classpathentry kind="src" path="src/test/res"/>
|
||||
<classpathentry kind="src" path="src/sample"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/3.8.1"/>
|
||||
|
||||
133
src/test/errors/args.lua
Normal file
133
src/test/errors/args.lua
Normal file
@@ -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
|
||||
9
src/test/errors/baselibargs.lua
Normal file
9
src/test/errors/baselibargs.lua
Normal file
@@ -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')
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
178
src/test/java/org/luaj/vm/CompatibiltyTest.java
Normal file
178
src/test/java/org/luaj/vm/CompatibiltyTest.java
Normal file
@@ -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");
|
||||
}
|
||||
}
|
||||
22
src/test/java/org/luaj/vm/ErrorMessageTest.java
Normal file
22
src/test/java/org/luaj/vm/ErrorMessageTest.java
Normal file
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
190
src/test/java/org/luaj/vm/ScriptDrivenTest.java
Normal file
190
src/test/java/org/luaj/vm/ScriptDrivenTest.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
version: 0.40
|
||||
version: 0.41
|
||||
|
||||
Reference in New Issue
Block a user