Move sources into maven modules
This commit is contained in:
0
luaj-test/src/main/java/.keep
Normal file
0
luaj-test/src/main/java/.keep
Normal file
0
luaj-test/src/main/resources/.keep
Normal file
0
luaj-test/src/main/resources/.keep
Normal file
61
luaj-test/src/test/java/org/luaj/luajc/SampleMainChunk.java
Normal file
61
luaj-test/src/test/java/org/luaj/luajc/SampleMainChunk.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package org.luaj.luajc;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Varargs;
|
||||
import org.luaj.vm2.lib.TwoArgFunction;
|
||||
import org.luaj.vm2.lib.VarArgFunction;
|
||||
|
||||
public class SampleMainChunk extends VarArgFunction {
|
||||
|
||||
static final LuaValue $print = valueOf("print");
|
||||
static final LuaValue $foo = valueOf("foo");
|
||||
|
||||
LuaValue[] rw_ENV; // The environment when it is read-write
|
||||
// LuaValue ro_ENV; // The environment when it is read-only in all sub-functions
|
||||
|
||||
LuaValue[] rw_openup1; // upvalue that we create and modify in "slot" 1, passed to sub-function in initer.
|
||||
LuaValue[] rw_openup2; // array is instantiated on first set or before supply to closure, after that value is get, set.
|
||||
LuaValue[] rw_openup3; // closing these nulls them out, sub-functions still retain references to array & can use
|
||||
LuaValue ro_openup4; // open upvalue that is read-only once it is supplied to an inner function.
|
||||
LuaValue ro_openup5; // closing this also nulls it out.
|
||||
|
||||
// Must have this in the main chunk so it can be loaded and instantiated on all platforms.
|
||||
public SampleMainChunk() {
|
||||
}
|
||||
|
||||
public void initupvalue1(LuaValue[] v) {
|
||||
this.rw_ENV = v;
|
||||
}
|
||||
|
||||
public Varargs invoke(Varargs args) {
|
||||
rw_ENV[0].get($print).call($foo);
|
||||
|
||||
rw_ENV[0].set($print, new InnerFunction(rw_openup3, rw_openup1, ro_openup5));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static class InnerFunction extends TwoArgFunction {
|
||||
static final LuaValue $print = valueOf("print"); // A constant, named for what it is.
|
||||
static final LuaValue $foo = valueOf("foo");
|
||||
|
||||
final LuaValue[] rw_upvalue1; // from enclosing function, corresponds to upvaldesc not instack.
|
||||
final LuaValue[] rw_upvalue2; // from enclosing function, corresponds to upvaldesc not instack.
|
||||
final LuaValue ro_upvalue3; // from enclosing function, but read-only everywhere.
|
||||
|
||||
LuaValue[] rw_openup1; // closing these nulls them out, sub-functions still retain references to array & can use
|
||||
LuaValue ro_openup2; // open upvalue that is read-only once it is supplied to an inner function.
|
||||
|
||||
InnerFunction(LuaValue[] rw_upvalue1, LuaValue[] rw_upvalue2, LuaValue ro_upvalue3) {
|
||||
this.rw_upvalue1 = rw_upvalue1;
|
||||
this.rw_upvalue2 = rw_upvalue2;
|
||||
this.ro_upvalue3 = ro_upvalue3;
|
||||
}
|
||||
|
||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||
return NIL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
70
luaj-test/src/test/java/org/luaj/luajc/TestLuaJ.java
Normal file
70
luaj-test/src/test/java/org/luaj/luajc/TestLuaJ.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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.luajc;
|
||||
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Print;
|
||||
import org.luaj.vm2.Prototype;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
|
||||
/** Test the plain old bytecode interpreter */
|
||||
public class TestLuaJ {
|
||||
// create the script
|
||||
public static String name = "script";
|
||||
public static String script =
|
||||
"function r(q,...)\n"+
|
||||
" local a=arg\n"+
|
||||
" return a and a[2]\n"+
|
||||
"end\n" +
|
||||
"function s(q,...)\n"+
|
||||
" local a=arg\n"+
|
||||
" local b=...\n"+
|
||||
" return a and a[2],b\n"+
|
||||
"end\n" +
|
||||
"print( r(111,222,333),s(111,222,333) )";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println(script);
|
||||
|
||||
// create an environment to run in
|
||||
Globals globals = JsePlatform.standardGlobals();
|
||||
|
||||
// compile into a chunk, or load as a class
|
||||
LuaValue chunk = globals.load(script, "script");
|
||||
|
||||
// The loaded chunk should be a closure, which contains the prototype.
|
||||
print( chunk.checkclosure().p );
|
||||
|
||||
// The chunk can be called with arguments as desired.
|
||||
chunk.call(LuaValue.ZERO, LuaValue.ONE);
|
||||
}
|
||||
|
||||
private static void print(Prototype p) {
|
||||
System.out.println("--- "+p);
|
||||
Print.printCode(p);
|
||||
if (p.p!=null)
|
||||
for ( int i=0,n=p.p.length; i<n; i++ )
|
||||
print( p.p[i] );
|
||||
}
|
||||
|
||||
}
|
||||
102
luaj-test/src/test/java/org/luaj/luajc/TestLuaJC.java
Normal file
102
luaj-test/src/test/java/org/luaj/luajc/TestLuaJC.java
Normal file
@@ -0,0 +1,102 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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.luajc;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Print;
|
||||
import org.luaj.vm2.Prototype;
|
||||
import org.luaj.vm2.Varargs;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
import org.luaj.vm2.luajc.LuaJC;
|
||||
|
||||
public class TestLuaJC {
|
||||
// This file will be loaded using the finder as a resource, provided it is in the
|
||||
// build path. This allows the debugger to find the file when stepping into the function.
|
||||
public static String filename = "perf/nsieve.lua";
|
||||
|
||||
static Globals globals;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length > 0)
|
||||
filename = args[0];
|
||||
System.out.println("filename: "+filename);
|
||||
try {
|
||||
|
||||
// create an environment to run in
|
||||
globals = JsePlatform.standardGlobals();
|
||||
|
||||
// print the chunk as a closure, and pretty-print the closure.
|
||||
LuaValue f = globals.loadfile(filename).arg1();
|
||||
Prototype p = f.checkclosure().p;
|
||||
Print.print(p);
|
||||
|
||||
// load into a luajc java-bytecode based chunk by installing the LuaJC compiler first
|
||||
if ( ! (args.length>0 && args[0].equals("nocompile")) ) {
|
||||
LuaJC.install(globals);
|
||||
f = globals.loadfile(filename).arg1();
|
||||
}
|
||||
|
||||
// call with arguments
|
||||
Varargs v = f.invoke(LuaValue.NONE);
|
||||
|
||||
// print the result
|
||||
System.out.println("result: "+v);
|
||||
|
||||
// Write out the files.
|
||||
// saveClasses();
|
||||
|
||||
} catch ( Throwable e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void saveClasses() throws Exception {
|
||||
// create the chunk
|
||||
String destdir = ".";
|
||||
|
||||
InputStream is = globals.finder.findResource(filename);
|
||||
Hashtable t = LuaJC.instance.compileAll(is, filename, filename, globals, true);
|
||||
|
||||
// write out the chunk
|
||||
for ( Enumeration e = t.keys(); e.hasMoreElements(); ) {
|
||||
String key = (String) e.nextElement();
|
||||
byte[] bytes = (byte[]) t.get(key);
|
||||
String destpath = (destdir!=null? destdir+"/": "") + key + ".class";
|
||||
System.out.println(
|
||||
"chunk "+filename+
|
||||
" from "+filename+
|
||||
" written to "+destpath
|
||||
+" length="+bytes.length+" bytes");
|
||||
FileOutputStream fos = new FileOutputStream( destpath );
|
||||
fos.write( bytes );
|
||||
fos.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
109
luaj-test/src/test/java/org/luaj/vm2/AllTests.java
Normal file
109
luaj-test/src/test/java/org/luaj/vm2/AllTests.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.luaj.vm2.WeakTableTest.WeakKeyTableTest;
|
||||
import org.luaj.vm2.WeakTableTest.WeakKeyValueTableTest;
|
||||
import org.luaj.vm2.WeakTableTest.WeakValueTableTest;
|
||||
import org.luaj.vm2.compiler.CompilerUnitTests;
|
||||
import org.luaj.vm2.compiler.DumpLoadEndianIntTest;
|
||||
import org.luaj.vm2.compiler.LuaParserTests;
|
||||
import org.luaj.vm2.compiler.RegressionTests;
|
||||
import org.luaj.vm2.compiler.SimpleTests;
|
||||
import org.luaj.vm2.lib.jse.JsePlatformTest;
|
||||
import org.luaj.vm2.lib.jse.LuaJavaCoercionTest;
|
||||
import org.luaj.vm2.lib.jse.LuajavaAccessibleMembersTest;
|
||||
import org.luaj.vm2.lib.jse.LuajavaClassMembersTest;
|
||||
import org.luaj.vm2.lib.jse.OsLibTest;
|
||||
import org.luaj.vm2.script.ScriptEngineTests;
|
||||
|
||||
public class AllTests {
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite("All Tests for Luaj-vm2");
|
||||
|
||||
// vm tests
|
||||
TestSuite vm = new TestSuite("VM Tests");
|
||||
vm.addTestSuite(TypeTest.class);
|
||||
vm.addTestSuite(UnaryBinaryOperatorsTest.class);
|
||||
vm.addTestSuite(MetatableTest.class);
|
||||
vm.addTestSuite(LuaOperationsTest.class);
|
||||
vm.addTestSuite(StringTest.class);
|
||||
vm.addTestSuite(OrphanedThreadTest.class);
|
||||
vm.addTestSuite(VarargsTest.class);
|
||||
vm.addTestSuite(LoadOrderTest.class);
|
||||
suite.addTest(vm);
|
||||
|
||||
// table tests
|
||||
TestSuite table = new TestSuite("Table Tests");
|
||||
table.addTestSuite(TableTest.class);
|
||||
table.addTestSuite(TableHashTest.class);
|
||||
table.addTestSuite(WeakValueTableTest.class);
|
||||
table.addTestSuite(WeakKeyTableTest.class);
|
||||
table.addTestSuite(WeakKeyValueTableTest.class);
|
||||
suite.addTest(table);
|
||||
|
||||
// bytecode compilers regression tests
|
||||
TestSuite bytecodetests = FragmentsTest.suite();
|
||||
suite.addTest(bytecodetests);
|
||||
|
||||
// I/O tests
|
||||
TestSuite io = new TestSuite("I/O Tests");
|
||||
io.addTestSuite(BufferedStreamTest.class);
|
||||
io.addTestSuite(UTF8StreamTest.class);
|
||||
suite.addTest(io);
|
||||
|
||||
// prototype compiler
|
||||
TestSuite compiler = new TestSuite("Lua Compiler Tests");
|
||||
compiler.addTestSuite(CompilerUnitTests.class);
|
||||
compiler.addTestSuite(DumpLoadEndianIntTest.class);
|
||||
compiler.addTestSuite(LuaParserTests.class);
|
||||
compiler.addTestSuite(RegressionTests.class);
|
||||
compiler.addTestSuite(SimpleTests.class);
|
||||
suite.addTest(compiler);
|
||||
|
||||
// library tests
|
||||
TestSuite lib = new TestSuite("Library Tests");
|
||||
lib.addTestSuite(JsePlatformTest.class);
|
||||
lib.addTestSuite(LuajavaAccessibleMembersTest.class);
|
||||
lib.addTestSuite(LuajavaClassMembersTest.class);
|
||||
lib.addTestSuite(LuaJavaCoercionTest.class);
|
||||
lib.addTestSuite(RequireClassTest.class);
|
||||
lib.addTestSuite(OsLibTest.class);
|
||||
suite.addTest(lib);
|
||||
|
||||
// Script engine tests.
|
||||
TestSuite script = ScriptEngineTests.suite();
|
||||
suite.addTest(script);
|
||||
|
||||
// compatiblity tests
|
||||
TestSuite compat = CompatibiltyTest.suite();
|
||||
suite.addTest(compat);
|
||||
compat.addTestSuite(ErrorsTest.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
}
|
||||
115
luaj-test/src/test/java/org/luaj/vm2/BufferedStreamTest.java
Normal file
115
luaj-test/src/test/java/org/luaj/vm2/BufferedStreamTest.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014 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;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.Globals.BufferedStream;
|
||||
|
||||
|
||||
public class BufferedStreamTest extends TestCase {
|
||||
|
||||
public BufferedStreamTest() {}
|
||||
|
||||
private BufferedStream NewBufferedStream(int buflen, String contents) {
|
||||
return new BufferedStream(buflen, new ByteArrayInputStream(contents.getBytes()));
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testReadEmptyStream() throws java.io.IOException {
|
||||
BufferedStream bs = NewBufferedStream(4, "");
|
||||
assertEquals(-1, bs.read());
|
||||
assertEquals(-1, bs.read(new byte[10]));
|
||||
assertEquals(-1, bs.read(new byte[10], 0, 10));
|
||||
}
|
||||
|
||||
public void testReadByte() throws java.io.IOException {
|
||||
BufferedStream bs = NewBufferedStream(2, "abc");
|
||||
assertEquals('a', bs.read());
|
||||
assertEquals('b', bs.read());
|
||||
assertEquals('c', bs.read());
|
||||
assertEquals(-1, bs.read());
|
||||
}
|
||||
|
||||
public void testReadByteArray() throws java.io.IOException {
|
||||
byte[] array = new byte[3];
|
||||
BufferedStream bs = NewBufferedStream(4, "abcdef");
|
||||
assertEquals(3, bs.read(array));
|
||||
assertEquals("abc", new String(array));
|
||||
assertEquals(1, bs.read(array));
|
||||
assertEquals("d", new String(array, 0, 1));
|
||||
assertEquals(2, bs.read(array));
|
||||
assertEquals("ef", new String(array, 0, 2));
|
||||
assertEquals(-1, bs.read());
|
||||
}
|
||||
|
||||
public void testReadByteArrayOffsetLength() throws java.io.IOException {
|
||||
byte[] array = new byte[10];
|
||||
BufferedStream bs = NewBufferedStream(8, "abcdefghijklmn");
|
||||
assertEquals(4, bs.read(array, 0, 4));
|
||||
assertEquals("abcd", new String(array, 0, 4));
|
||||
assertEquals(4, bs.read(array, 2, 8));
|
||||
assertEquals("efgh", new String(array, 2, 4));
|
||||
assertEquals(6, bs.read(array, 0, 10));
|
||||
assertEquals("ijklmn", new String(array, 0, 6));
|
||||
assertEquals(-1, bs.read());
|
||||
}
|
||||
|
||||
public void testMarkOffsetBeginningOfStream() throws java.io.IOException {
|
||||
byte[] array = new byte[4];
|
||||
BufferedStream bs = NewBufferedStream(8, "abcdefghijkl");
|
||||
assertEquals(true, bs.markSupported());
|
||||
bs.mark(4);
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("abcd", new String(array));
|
||||
bs.reset();
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("abcd", new String(array));
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("efgh", new String(array));
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("ijkl", new String(array));
|
||||
assertEquals(-1, bs.read());
|
||||
}
|
||||
|
||||
public void testMarkOffsetMiddleOfStream() throws java.io.IOException {
|
||||
byte[] array = new byte[4];
|
||||
BufferedStream bs = NewBufferedStream(8, "abcdefghijkl");
|
||||
assertEquals(true, bs.markSupported());
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("abcd", new String(array));
|
||||
bs.mark(4);
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("efgh", new String(array));
|
||||
bs.reset();
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("efgh", new String(array));
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("ijkl", new String(array));
|
||||
assertEquals(-1, bs.read());
|
||||
}
|
||||
}
|
||||
115
luaj-test/src/test/java/org/luaj/vm2/CompatibiltyTest.java
Normal file
115
luaj-test/src/test/java/org/luaj/vm2/CompatibiltyTest.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.luaj.vm2.luajc.LuaJC;
|
||||
|
||||
/**
|
||||
* Compatibility tests for the Luaj VM
|
||||
*
|
||||
* Results are compared for exact match with
|
||||
* the installed C-based lua environment.
|
||||
*/
|
||||
public class CompatibiltyTest extends TestSuite {
|
||||
|
||||
private static final String dir = "";
|
||||
|
||||
abstract protected static class CompatibiltyTestSuite extends ScriptDrivenTest {
|
||||
LuaValue savedStringMetatable;
|
||||
protected CompatibiltyTestSuite(PlatformType platform) {
|
||||
super(platform,dir);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
savedStringMetatable = LuaString.s_metatable;
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
LuaNil.s_metatable = null;
|
||||
LuaBoolean.s_metatable = null;
|
||||
LuaNumber.s_metatable = null;
|
||||
LuaFunction.s_metatable = null;
|
||||
LuaThread.s_metatable = null;
|
||||
LuaString.s_metatable = savedStringMetatable;
|
||||
}
|
||||
|
||||
public void testBaseLib() { runTest("baselib"); }
|
||||
public void testCoroutineLib() { runTest("coroutinelib"); }
|
||||
public void testDebugLib() { runTest("debuglib"); }
|
||||
public void testErrors() { runTest("errors"); }
|
||||
public void testFunctions() { runTest("functions"); }
|
||||
public void testIoLib() { runTest("iolib"); }
|
||||
public void testManyUpvals() { runTest("manyupvals"); }
|
||||
public void testMathLib() { runTest("mathlib"); }
|
||||
public void testMetatags() { runTest("metatags"); }
|
||||
public void testOsLib() { runTest("oslib"); }
|
||||
public void testStringLib() { runTest("stringlib"); }
|
||||
public void testTableLib() { runTest("tablelib"); }
|
||||
public void testTailcalls() { runTest("tailcalls"); }
|
||||
public void testUpvalues() { runTest("upvalues"); }
|
||||
public void testVm() { runTest("vm"); }
|
||||
}
|
||||
|
||||
|
||||
public static TestSuite suite() {
|
||||
TestSuite suite = new TestSuite("Compatibility Tests");
|
||||
suite.addTest( new TestSuite( JseCompatibilityTest.class, "JSE Compatibility Tests" ) );
|
||||
suite.addTest( new TestSuite( JmeCompatibilityTest.class, "JME Compatibility Tests" ) );
|
||||
suite.addTest( new TestSuite( LuaJCCompatibilityTest.class, "LuaJC Compatibility Tests" ) );
|
||||
return suite;
|
||||
}
|
||||
|
||||
public static class JmeCompatibilityTest extends CompatibiltyTestSuite {
|
||||
public JmeCompatibilityTest() {
|
||||
super(ScriptDrivenTest.PlatformType.JME);
|
||||
}
|
||||
protected void setUp() throws Exception {
|
||||
System.setProperty("JME", "true");
|
||||
super.setUp();
|
||||
}
|
||||
}
|
||||
public static class JseCompatibilityTest extends CompatibiltyTestSuite {
|
||||
public JseCompatibilityTest() {
|
||||
super(ScriptDrivenTest.PlatformType.JSE);
|
||||
}
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
System.setProperty("JME", "false");
|
||||
}
|
||||
}
|
||||
public static class LuaJCCompatibilityTest extends CompatibiltyTestSuite {
|
||||
public LuaJCCompatibilityTest() {
|
||||
super(ScriptDrivenTest.PlatformType.LUAJIT);
|
||||
}
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
System.setProperty("JME", "false");
|
||||
LuaJC.install(globals);
|
||||
}
|
||||
// not supported on this platform - don't test
|
||||
public void testDebugLib() {}
|
||||
}
|
||||
}
|
||||
63
luaj-test/src/test/java/org/luaj/vm2/ErrorsTest.java
Normal file
63
luaj-test/src/test/java/org/luaj/vm2/ErrorsTest.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
/**
|
||||
* Test argument type check errors
|
||||
*
|
||||
* Results are compared for exact match with
|
||||
* the installed C-based lua environment.
|
||||
*/
|
||||
public class ErrorsTest extends ScriptDrivenTest {
|
||||
|
||||
private static final String dir = "errors/";
|
||||
|
||||
public ErrorsTest() {
|
||||
super(ScriptDrivenTest.PlatformType.JSE, dir);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
public void testBaseLibArgs() {
|
||||
globals.STDIN = new InputStream() {
|
||||
public int read() throws IOException {
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
runTest("baselibargs");
|
||||
}
|
||||
public void testCoroutineLibArgs() { runTest("coroutinelibargs"); }
|
||||
public void testDebugLibArgs() { runTest("debuglibargs"); }
|
||||
public void testIoLibArgs() { runTest("iolibargs"); }
|
||||
public void testMathLibArgs() { runTest("mathlibargs"); }
|
||||
public void testModuleLibArgs() { runTest("modulelibargs"); }
|
||||
public void testOperators() { runTest("operators"); }
|
||||
public void testStringLibArgs() { runTest("stringlibargs"); }
|
||||
public void testTableLibArgs() { runTest("tablelibargs"); }
|
||||
|
||||
}
|
||||
612
luaj-test/src/test/java/org/luaj/vm2/FragmentsTest.java
Normal file
612
luaj-test/src/test/java/org/luaj/vm2/FragmentsTest.java
Normal file
@@ -0,0 +1,612 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
import org.luaj.vm2.luajc.LuaJC;
|
||||
|
||||
/**
|
||||
* Test compilation of various fragments that have
|
||||
* caused problems for jit compiling during development.
|
||||
*
|
||||
*/
|
||||
public class FragmentsTest extends TestSuite {
|
||||
|
||||
static final int TEST_TYPE_LUAC = 0;
|
||||
static final int TEST_TYPE_LUAJC = 1;
|
||||
|
||||
public static class JseFragmentsTest extends FragmentsTestCase {
|
||||
public JseFragmentsTest() { super( TEST_TYPE_LUAC ); }
|
||||
}
|
||||
public static class LuaJCFragmentsTest extends FragmentsTestCase {
|
||||
public LuaJCFragmentsTest() { super( TEST_TYPE_LUAJC ); }
|
||||
}
|
||||
public static TestSuite suite() {
|
||||
TestSuite suite = new TestSuite("Compiler Fragments Tests");
|
||||
suite.addTest( new TestSuite( JseFragmentsTest.class, "JSE Fragments Tests" ) );
|
||||
suite.addTest( new TestSuite( LuaJCFragmentsTest.class, "LuaJC Fragments Tests" ) );
|
||||
return suite;
|
||||
}
|
||||
|
||||
abstract protected static class FragmentsTestCase extends TestCase {
|
||||
|
||||
final int TEST_TYPE;
|
||||
|
||||
protected FragmentsTestCase(int testType) {
|
||||
this.TEST_TYPE = testType;
|
||||
}
|
||||
|
||||
public void runFragment( Varargs expected, String script ) {
|
||||
try {
|
||||
String name = getName();
|
||||
Globals globals = JsePlatform.debugGlobals();
|
||||
Reader reader = new StringReader(script);
|
||||
LuaValue chunk ;
|
||||
switch ( TEST_TYPE ) {
|
||||
case TEST_TYPE_LUAJC:
|
||||
LuaJC.install(globals);
|
||||
chunk = globals.load(reader, name);
|
||||
break;
|
||||
default:
|
||||
Prototype p = globals.compilePrototype(reader, name);
|
||||
chunk = new LuaClosure(p, globals);
|
||||
Print.print(p);
|
||||
break;
|
||||
}
|
||||
Varargs actual = chunk.invoke();
|
||||
assertEquals( expected.narg(), actual.narg() );
|
||||
for ( int i=1; i<=actual.narg(); i++ )
|
||||
assertEquals( expected.arg(i), actual.arg(i) );
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void testFirstArgNilExtended() {
|
||||
runFragment( LuaValue.NIL,
|
||||
"function f1(a) print( 'f1:', a ) return a end\n" +
|
||||
"b = f1()\n" +
|
||||
"return b" );
|
||||
}
|
||||
|
||||
public void testSimpleForloop() {
|
||||
runFragment( LuaValue.valueOf(77),
|
||||
"for n,p in ipairs({77}) do\n"+
|
||||
" print('n,p',n,p)\n"+
|
||||
" return p\n"+
|
||||
"end\n");
|
||||
|
||||
}
|
||||
|
||||
public void testForloopParamUpvalues() {
|
||||
runFragment( LuaValue.varargsOf(new LuaValue[] {
|
||||
LuaValue.valueOf(77),
|
||||
LuaValue.valueOf(1) } ),
|
||||
"for n,p in ipairs({77}) do\n"+
|
||||
" print('n,p',n,p)\n"+
|
||||
" foo = function()\n"+
|
||||
" return p,n\n"+
|
||||
" end\n"+
|
||||
" return foo()\n"+
|
||||
"end\n");
|
||||
|
||||
}
|
||||
|
||||
public void testArgVarargsUseBoth() {
|
||||
runFragment( LuaValue.varargsOf( new LuaValue[] {
|
||||
LuaValue.valueOf("a"),
|
||||
LuaValue.valueOf("b"),
|
||||
LuaValue.valueOf("c")}),
|
||||
"function v(arg,...)\n" +
|
||||
" return arg,...\n" +
|
||||
"end\n" +
|
||||
"return v('a','b','c')\n" );
|
||||
}
|
||||
|
||||
public void testArgParamUseNone() {
|
||||
runFragment( LuaValue.valueOf("string"),
|
||||
"function v(arg,...)\n" +
|
||||
" return type(arg)\n" +
|
||||
"end\n" +
|
||||
"return v('abc')\n" );
|
||||
}
|
||||
|
||||
public void testSetlistVarargs() {
|
||||
runFragment( LuaValue.valueOf("abc"),
|
||||
"local f = function() return 'abc' end\n" +
|
||||
"local g = { f() }\n" +
|
||||
"return g[1]\n" );
|
||||
}
|
||||
|
||||
public void testSelfOp() {
|
||||
runFragment( LuaValue.valueOf("bcd"),
|
||||
"local s = 'abcde'\n"+
|
||||
"return s:sub(2,4)\n" );
|
||||
}
|
||||
|
||||
public void testSetListWithOffsetAndVarargs() {
|
||||
runFragment( LuaValue.valueOf(1003),
|
||||
"local bar = {1000, math.sqrt(9)}\n"+
|
||||
"return bar[1]+bar[2]\n" );
|
||||
}
|
||||
|
||||
public void testMultiAssign() {
|
||||
// arargs evaluations are all done before assignments
|
||||
runFragment( LuaValue.varargsOf(new LuaValue[]{
|
||||
LuaValue.valueOf(111),
|
||||
LuaValue.valueOf(111),
|
||||
LuaValue.valueOf(111)}),
|
||||
"a,b,c = 1,10,100\n" +
|
||||
"a,b,c = a+b+c, a+b+c, a+b+c\n" +
|
||||
"return a,b,c\n" );
|
||||
}
|
||||
|
||||
public void testUpvalues() {
|
||||
runFragment( LuaValue.valueOf(999),
|
||||
"local a = function(x)\n" +
|
||||
" return function(y)\n" +
|
||||
" return x + y\n" +
|
||||
" end\n" +
|
||||
"end\n" +
|
||||
"local b = a(222)\n" +
|
||||
"local c = b(777)\n" +
|
||||
"print( 'c=', c )\n" +
|
||||
"return c\n" );
|
||||
}
|
||||
|
||||
public void testNonAsciiStringLiterals() {
|
||||
runFragment( LuaValue.valueOf("7,8,12,10,9,11,133,222"),
|
||||
"local a='\\a\\b\\f\\n\\t\\v\\133\\222'\n"+
|
||||
"local t={string.byte(a,1,#a)}\n"+
|
||||
"return table.concat(t,',')\n" );
|
||||
}
|
||||
|
||||
public void testControlCharStringLiterals() {
|
||||
runFragment( LuaValue.valueOf("97,0,98,18,99,18,100,18,48,101"),
|
||||
"local a='a\\0b\\18c\\018d\\0180e'\n"+
|
||||
"local t={string.byte(a,1,#a)}\n"+
|
||||
"return table.concat(t,',')\n" );
|
||||
}
|
||||
|
||||
public void testLoopVarNames() {
|
||||
runFragment( LuaValue.valueOf(" 234,1,aa 234,2,bb"),
|
||||
"local w = ''\n"+
|
||||
"function t()\n"+
|
||||
" for f,var in ipairs({'aa','bb'}) do\n"+
|
||||
" local s = 234\n"+
|
||||
" w = w..' '..s..','..f..','..var\n"+
|
||||
" end\n"+
|
||||
"end\n" +
|
||||
"t()\n" +
|
||||
"return w\n" );
|
||||
|
||||
}
|
||||
|
||||
public void testForLoops() {
|
||||
runFragment( LuaValue.valueOf("12345 357 963"),
|
||||
"local s,t,u = '','',''\n"+
|
||||
"for m=1,5 do\n"+
|
||||
" s = s..m\n"+
|
||||
"end\n"+
|
||||
"for m=3,7,2 do\n"+
|
||||
" t = t..m\n"+
|
||||
"end\n"+
|
||||
"for m=9,3,-3 do\n"+
|
||||
" u = u..m\n"+
|
||||
"end\n"+
|
||||
"return s..' '..t..' '..u\n" );
|
||||
}
|
||||
|
||||
public void testLocalFunctionDeclarations() {
|
||||
runFragment( LuaValue.varargsOf(LuaValue.valueOf("function"),LuaValue.valueOf("nil")),
|
||||
"local function aaa()\n"+
|
||||
" return type(aaa)\n"+
|
||||
"end\n"+
|
||||
"local bbb = function()\n"+
|
||||
" return type(bbb)\n"+
|
||||
"end\n"+
|
||||
"return aaa(),bbb()\n" );
|
||||
}
|
||||
|
||||
public void testNilsInTableConstructor() {
|
||||
runFragment( LuaValue.valueOf("1=111 2=222 3=333 "),
|
||||
"local t = { 111, 222, 333, nil, nil }\n"+
|
||||
"local s = ''\n"+
|
||||
"for i,v in ipairs(t) do \n" +
|
||||
" s=s..tostring(i)..'='..tostring(v)..' '\n" +
|
||||
"end\n"+
|
||||
"return s\n" );
|
||||
|
||||
}
|
||||
|
||||
public void testUnreachableCode() {
|
||||
runFragment( LuaValue.valueOf(66),
|
||||
"local function foo(x) return x * 2 end\n" +
|
||||
"local function bar(x, y)\n" +
|
||||
" if x==y then\n" +
|
||||
" return y\n" +
|
||||
" else\n" +
|
||||
" return foo(x)\n" +
|
||||
" end\n" +
|
||||
"end\n" +
|
||||
"return bar(33,44)\n" );
|
||||
|
||||
}
|
||||
public void testVarargsWithParameters() {
|
||||
runFragment( LuaValue.valueOf(222),
|
||||
"local func = function(t,...)\n"+
|
||||
" return (...)\n"+
|
||||
"end\n"+
|
||||
"return func(111,222,333)\n" );
|
||||
}
|
||||
|
||||
public void testNoReturnValuesPlainCall() {
|
||||
runFragment( LuaValue.TRUE,
|
||||
"local testtable = {}\n"+
|
||||
"return pcall( function() testtable[1]=2 end )\n" );
|
||||
}
|
||||
|
||||
public void testVarargsInTableConstructor() {
|
||||
runFragment( LuaValue.valueOf(222),
|
||||
"local function foo() return 111,222,333 end\n"+
|
||||
"local t = {'a','b',c='c',foo()}\n"+
|
||||
"return t[4]\n" );
|
||||
}
|
||||
|
||||
public void testVarargsInFirstArg() {
|
||||
runFragment( LuaValue.valueOf(123),
|
||||
"function aaa(x) return x end\n" +
|
||||
"function bbb(y) return y end\n" +
|
||||
"function ccc(z) return z end\n" +
|
||||
"return ccc( aaa(bbb(123)), aaa(456) )\n" );
|
||||
}
|
||||
|
||||
public void testSetUpvalueTableInitializer() {
|
||||
runFragment( LuaValue.valueOf("b"),
|
||||
"local aliases = {a='b'}\n" +
|
||||
"local foo = function()\n" +
|
||||
" return aliases\n" +
|
||||
"end\n" +
|
||||
"return foo().a\n" );
|
||||
}
|
||||
|
||||
|
||||
public void testLoadNilUpvalue() {
|
||||
runFragment( LuaValue.NIL,
|
||||
"tostring = function() end\n" +
|
||||
"local pc \n" +
|
||||
"local pcall = function(...)\n" +
|
||||
" pc(...)\n" +
|
||||
"end\n" +
|
||||
"return NIL\n" );
|
||||
}
|
||||
|
||||
public void testUpvalueClosure() {
|
||||
runFragment( LuaValue.NIL,
|
||||
"print()\n"+
|
||||
"local function f2() end\n"+
|
||||
"local function f3()\n"+
|
||||
" return f3\n"+
|
||||
"end\n" +
|
||||
"return NIL\n" );
|
||||
}
|
||||
|
||||
public void testUninitializedUpvalue() {
|
||||
runFragment( LuaValue.NIL,
|
||||
"local f\n"+
|
||||
"do\n"+
|
||||
" function g()\n"+
|
||||
" print(f())\n"+
|
||||
" end\n"+
|
||||
"end\n" +
|
||||
"return NIL\n" );
|
||||
}
|
||||
|
||||
public void testTestOpUpvalues() {
|
||||
runFragment( LuaValue.varargsOf(LuaValue.valueOf(1),LuaValue.valueOf(2),LuaValue.valueOf(3)),
|
||||
"print( nil and 'T' or 'F' )\n"+
|
||||
"local a,b,c = 1,2,3\n"+
|
||||
"function foo()\n"+
|
||||
" return a,b,c\n"+
|
||||
"end\n" +
|
||||
"return foo()\n" );
|
||||
}
|
||||
public void testTestSimpleBinops() {
|
||||
runFragment( LuaValue.varargsOf(new LuaValue[] {
|
||||
LuaValue.FALSE, LuaValue.FALSE, LuaValue.TRUE, LuaValue.TRUE, LuaValue.FALSE }),
|
||||
"local a,b,c = 2,-2.5,0\n" +
|
||||
"return (a==c), (b==c), (a==a), (a>c), (b>0)\n" );
|
||||
}
|
||||
|
||||
public void testNumericForUpvalues() {
|
||||
runFragment( LuaValue.valueOf(8),
|
||||
"for i = 3,4 do\n"+
|
||||
" i = i + 5\n"+
|
||||
" local a = function()\n"+
|
||||
" return i\n"+
|
||||
" end\n" +
|
||||
" return a()\n"+
|
||||
"end\n");
|
||||
}
|
||||
|
||||
public void testNumericForUpvalues2() {
|
||||
runFragment( LuaValue.valueOf("222 222"),
|
||||
"local t = {}\n"+
|
||||
"local template = [[123 456]]\n"+
|
||||
"for i = 1,2 do\n"+
|
||||
" t[i] = template:gsub('%d', function(s)\n"+
|
||||
" return i\n"+
|
||||
" end)\n"+
|
||||
"end\n" +
|
||||
"return t[2]\n");
|
||||
}
|
||||
|
||||
public void testReturnUpvalue() {
|
||||
runFragment( LuaValue.varargsOf(new LuaValue[] { LuaValue.ONE, LuaValue.valueOf(5), }),
|
||||
"local a = 1\n"+
|
||||
"local b\n"+
|
||||
"function c()\n"+
|
||||
" b=5\n" +
|
||||
" return a\n"+
|
||||
"end\n"+
|
||||
"return c(),b\n" );
|
||||
}
|
||||
|
||||
public void testUninitializedAroundBranch() {
|
||||
runFragment( LuaValue.valueOf(333),
|
||||
"local state\n"+
|
||||
"if _G then\n"+
|
||||
" state = 333\n"+
|
||||
"end\n"+
|
||||
"return state\n" );
|
||||
}
|
||||
|
||||
public void testLoadedNilUpvalue() {
|
||||
runFragment( LuaValue.NIL,
|
||||
"local a = print()\n"+
|
||||
"local b = c and { d = e }\n"+
|
||||
"local f\n"+
|
||||
"local function g()\n"+
|
||||
" return f\n"+
|
||||
"end\n" +
|
||||
"return g()\n" );
|
||||
}
|
||||
|
||||
public void testUpvalueInFirstSlot() {
|
||||
runFragment( LuaValue.valueOf("foo"),
|
||||
"local p = {'foo'}\n"+
|
||||
"bar = function()\n"+
|
||||
" return p \n"+
|
||||
"end\n"+
|
||||
"for i,key in ipairs(p) do\n"+
|
||||
" print()\n"+
|
||||
"end\n" +
|
||||
"return bar()[1]");
|
||||
}
|
||||
|
||||
public void testReadOnlyAndReadWriteUpvalues() {
|
||||
runFragment( LuaValue.varargsOf( new LuaValue[] { LuaValue.valueOf(333), LuaValue.valueOf(222) } ),
|
||||
"local a = 111\n" +
|
||||
"local b = 222\n" +
|
||||
"local c = function()\n"+
|
||||
" a = a + b\n" +
|
||||
" return a,b\n"+
|
||||
"end\n" +
|
||||
"return c()\n" );
|
||||
}
|
||||
|
||||
public void testNestedUpvalues() {
|
||||
runFragment( LuaValue.varargsOf( new LuaValue[] { LuaValue.valueOf(5), LuaValue.valueOf(8), LuaValue.valueOf(9) } ),
|
||||
"local x = 3\n"+
|
||||
"local y = 5\n"+
|
||||
"local function f()\n"+
|
||||
" return y\n"+
|
||||
"end\n"+
|
||||
"local function g(x1, y1)\n"+
|
||||
" x = x1\n"+
|
||||
" y = y1\n" +
|
||||
" return x,y\n"+
|
||||
"end\n"+
|
||||
"return f(), g(8,9)\n"+
|
||||
"\n" );
|
||||
}
|
||||
|
||||
public void testLoadBool() {
|
||||
runFragment( LuaValue.NONE,
|
||||
"print( type(foo)=='string' )\n"+
|
||||
"local a,b\n"+
|
||||
"if print() then\n"+
|
||||
" b = function()\n"+
|
||||
" return a\n"+
|
||||
" end\n"+
|
||||
"end\n" );
|
||||
}
|
||||
|
||||
public void testBasicForLoop() {
|
||||
runFragment( LuaValue.valueOf(2),
|
||||
"local data\n"+
|
||||
"for i = 1, 2 do\n"+
|
||||
" data = i\n"+
|
||||
"end\n"+
|
||||
"local bar = function()\n"+
|
||||
" return data\n"+
|
||||
"end\n" +
|
||||
"return bar()\n" );
|
||||
}
|
||||
|
||||
public void testGenericForMultipleValues() {
|
||||
runFragment( LuaValue.varargsOf(LuaValue.valueOf(3),LuaValue.valueOf(2),LuaValue.valueOf(1)),
|
||||
"local iter = function() return 1,2,3,4 end\n" +
|
||||
"local foo = function() return iter,5 end\n" +
|
||||
"for a,b,c in foo() do\n" +
|
||||
" return c,b,a\n" +
|
||||
"end\n" );
|
||||
}
|
||||
|
||||
public void testPhiUpvalue() {
|
||||
runFragment( LuaValue.valueOf(6),
|
||||
"local a = foo or 0\n"+
|
||||
"local function b(c)\n"+
|
||||
" if c > a then a = c end\n" +
|
||||
" return a\n"+
|
||||
"end\n" +
|
||||
"b(6)\n" +
|
||||
"return a\n" );
|
||||
}
|
||||
|
||||
public void testAssignReferUpvalues() {
|
||||
runFragment( LuaValue.valueOf(123),
|
||||
"local entity = 234\n" +
|
||||
"local function c()\n" +
|
||||
" return entity\n" +
|
||||
"end\n" +
|
||||
"entity = (a == b) and 123\n" +
|
||||
"if entity then\n" +
|
||||
" return entity\n" +
|
||||
"end\n" );
|
||||
}
|
||||
|
||||
public void testSimpleRepeatUntil() {
|
||||
runFragment( LuaValue.valueOf(5),
|
||||
"local a\n"+
|
||||
"local w\n"+
|
||||
"repeat\n"+
|
||||
" a = w\n"+
|
||||
"until not a\n" +
|
||||
"return 5\n" );
|
||||
}
|
||||
|
||||
public void testLoopVarUpvalues() {
|
||||
runFragment( LuaValue.valueOf("b"),
|
||||
"local env = {}\n" +
|
||||
"for a,b in pairs(_G) do\n" +
|
||||
" c = function()\n" +
|
||||
" return b\n" +
|
||||
" end\n" +
|
||||
"end\n" +
|
||||
"local e = env\n" +
|
||||
"local f = {a='b'}\n" +
|
||||
"for k,v in pairs(f) do\n" +
|
||||
" return env[k] or v\n" +
|
||||
"end\n");
|
||||
}
|
||||
|
||||
public void testPhiVarUpvalue() {
|
||||
runFragment( LuaValue.valueOf(2),
|
||||
"local a = 1\n"+
|
||||
"local function b()\n"+
|
||||
" a = a + 1\n"+
|
||||
" return function() end\n"+
|
||||
"end\n"+
|
||||
"for i in b() do\n"+
|
||||
" a = 3\n"+
|
||||
"end\n" +
|
||||
"return a\n");
|
||||
}
|
||||
|
||||
public void testUpvaluesInElseClauses() {
|
||||
runFragment( LuaValue.valueOf(111),
|
||||
"if a then\n" +
|
||||
" foo(bar)\n" +
|
||||
"elseif _G then\n" +
|
||||
" local x = 111\n" +
|
||||
" if d then\n" +
|
||||
" foo(bar)\n" +
|
||||
" else\n" +
|
||||
" local y = function()\n" +
|
||||
" return x\n" +
|
||||
" end\n" +
|
||||
" return y()\n" +
|
||||
" end\n" +
|
||||
"end\n");
|
||||
}
|
||||
|
||||
public void testUpvalueInDoBlock() {
|
||||
runFragment( LuaValue.NONE, "do\n"+
|
||||
" local x = 10\n"+
|
||||
" function g()\n"+
|
||||
" return x\n"+
|
||||
" end\n"+
|
||||
"end\n"+
|
||||
"g()\n");
|
||||
}
|
||||
|
||||
public void testNullError() {
|
||||
runFragment( LuaValue.varargsOf(LuaValue.FALSE, LuaValue.NIL),
|
||||
"return pcall(error)\n");
|
||||
}
|
||||
|
||||
public void testFindWithOffset() {
|
||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf(8), LuaValue.valueOf(5)),
|
||||
"string = \"abcdef:ghi\"\n" +
|
||||
"substring = string:sub(3)\n" +
|
||||
"idx = substring:find(\":\")\n" +
|
||||
"return #substring, idx\n");
|
||||
}
|
||||
|
||||
public void testErrorArgIsString() {
|
||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("string"), LuaValue.valueOf("c")),
|
||||
"a,b = pcall(error, 'c'); return type(b), b\n");
|
||||
}
|
||||
public void testErrorArgIsNil() {
|
||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("nil"), LuaValue.NIL),
|
||||
"a,b = pcall(error); return type(b), b\n");
|
||||
}
|
||||
public void testErrorArgIsTable() {
|
||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("table"), LuaValue.valueOf("d")),
|
||||
"a,b = pcall(error, {c='d'}); return type(b), b.c\n");
|
||||
}
|
||||
public void testErrorArgIsNumber() {
|
||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("string"), LuaValue.valueOf("1")),
|
||||
"a,b = pcall(error, 1); return type(b), b\n");
|
||||
}
|
||||
public void testErrorArgIsBool() {
|
||||
runFragment(LuaValue.varargsOf(LuaValue.valueOf("boolean"), LuaValue.TRUE),
|
||||
"a,b = pcall(error, true); return type(b), b\n");
|
||||
}
|
||||
public void testBalancedMatchOnEmptyString() {
|
||||
runFragment(LuaValue.NIL, "return (\"\"):match(\"%b''\")\n");
|
||||
}
|
||||
public void testReturnValueForTableRemove() {
|
||||
runFragment(LuaValue.NONE, "return table.remove({ })");
|
||||
}
|
||||
public void testTypeOfTableRemoveReturnValue() {
|
||||
runFragment(LuaValue.valueOf("nil"), "local k = table.remove({ }) return type(k)");
|
||||
}
|
||||
public void testVarargBugReport() {
|
||||
runFragment(LuaValue.varargsOf(new LuaValue[] {
|
||||
LuaValue.valueOf(1), LuaValue.valueOf(2), LuaValue.valueOf(3) }),
|
||||
"local i = function(...) return ... end\n"
|
||||
+ "local v1, v2, v3 = i(1, 2, 3)\n"
|
||||
+ "return v1, v2, v3");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
70
luaj-test/src/test/java/org/luaj/vm2/LoadOrderTest.java
Normal file
70
luaj-test/src/test/java/org/luaj/vm2/LoadOrderTest.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2015 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;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
import org.luaj.vm2.server.Launcher;
|
||||
import org.luaj.vm2.server.LuajClassLoader;
|
||||
|
||||
// Tests using class loading orders that have caused problems for some use cases.
|
||||
public class LoadOrderTest extends TestCase {
|
||||
|
||||
public void testLoadGlobalsFirst() {
|
||||
Globals g = JsePlatform.standardGlobals();
|
||||
assertNotNull(g);
|
||||
}
|
||||
|
||||
public void testLoadStringFirst() {
|
||||
LuaString BAR = LuaString.valueOf("bar");
|
||||
assertNotNull(BAR);
|
||||
}
|
||||
|
||||
public static class TestLauncherLoadStringFirst implements Launcher {
|
||||
// Static initializer that causes LuaString->LuaValue->LuaString
|
||||
private static final LuaString FOO = LuaString.valueOf("foo");
|
||||
|
||||
public Object[] launch(String script, Object[] arg) {
|
||||
return new Object[] { FOO };
|
||||
}
|
||||
|
||||
public Object[] launch(InputStream script, Object[] arg) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object[] launch(Reader script, Object[] arg) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void testClassLoadsStringFirst() throws Exception {
|
||||
Launcher launcher = LuajClassLoader
|
||||
.NewLauncher(TestLauncherLoadStringFirst.class);
|
||||
Object[] results = launcher.launch("foo", null);
|
||||
assertNotNull(results);
|
||||
}
|
||||
|
||||
}
|
||||
176
luaj-test/src/test/java/org/luaj/vm2/LuaOperationsTest.java
Normal file
176
luaj-test/src/test/java/org/luaj/vm2/LuaOperationsTest.java
Normal file
@@ -0,0 +1,176 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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;
|
||||
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.TypeTest.MyData;
|
||||
import org.luaj.vm2.compiler.LuaC;
|
||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
||||
|
||||
public class LuaOperationsTest extends TestCase {
|
||||
|
||||
private final int sampleint = 77;
|
||||
private final long samplelong = 123400000000L;
|
||||
private final double sampledouble = 55.25;
|
||||
private final String samplestringstring = "abcdef";
|
||||
private final String samplestringint = String.valueOf(sampleint);
|
||||
private final String samplestringlong = String.valueOf(samplelong);
|
||||
private final String samplestringdouble = String.valueOf(sampledouble);
|
||||
private final Object sampleobject = new Object();
|
||||
private final MyData sampledata = new MyData();
|
||||
|
||||
private final LuaValue somenil = LuaValue.NIL;
|
||||
private final LuaValue sometrue = LuaValue.TRUE;
|
||||
private final LuaValue somefalse = LuaValue.FALSE;
|
||||
private final LuaValue zero = LuaValue.ZERO;
|
||||
private final LuaValue intint = LuaValue.valueOf(sampleint);
|
||||
private final LuaValue longdouble = LuaValue.valueOf(samplelong);
|
||||
private final LuaValue doubledouble = LuaValue.valueOf(sampledouble);
|
||||
private final LuaValue stringstring = LuaValue.valueOf(samplestringstring);
|
||||
private final LuaValue stringint = LuaValue.valueOf(samplestringint);
|
||||
private final LuaValue stringlong = LuaValue.valueOf(samplestringlong);
|
||||
private final LuaValue stringdouble = LuaValue.valueOf(samplestringdouble);
|
||||
private final LuaTable table = LuaValue.listOf( new LuaValue[] { LuaValue.valueOf("aaa"), LuaValue.valueOf("bbb") } );
|
||||
private final LuaValue somefunc = new ZeroArgFunction() { public LuaValue call() { return NONE;}};
|
||||
private final LuaThread thread = new LuaThread(new Globals(), somefunc);
|
||||
private final Prototype proto = new Prototype(1);
|
||||
private final LuaClosure someclosure = new LuaClosure(proto,table);
|
||||
private final LuaUserdata userdataobj = LuaValue.userdataOf(sampleobject);
|
||||
private final LuaUserdata userdatacls = LuaValue.userdataOf(sampledata);
|
||||
|
||||
private void throwsLuaError(String methodName, Object obj) {
|
||||
try {
|
||||
LuaValue.class.getMethod(methodName).invoke(obj);
|
||||
fail("failed to throw LuaError as required");
|
||||
} catch (InvocationTargetException e) {
|
||||
if ( ! (e.getTargetException() instanceof LuaError) )
|
||||
fail("not a LuaError: "+e.getTargetException());
|
||||
return; // pass
|
||||
} catch ( Exception e ) {
|
||||
fail( "bad exception: "+e );
|
||||
}
|
||||
}
|
||||
|
||||
private void throwsLuaError(String methodName, Object obj, Object arg) {
|
||||
try {
|
||||
LuaValue.class.getMethod(methodName,LuaValue.class).invoke(obj,arg);
|
||||
fail("failed to throw LuaError as required");
|
||||
} catch (InvocationTargetException e) {
|
||||
if ( ! (e.getTargetException() instanceof LuaError) )
|
||||
fail("not a LuaError: "+e.getTargetException());
|
||||
return; // pass
|
||||
} catch ( Exception e ) {
|
||||
fail( "bad exception: "+e );
|
||||
}
|
||||
}
|
||||
|
||||
public void testLen() {
|
||||
throwsLuaError( "len", somenil );
|
||||
throwsLuaError( "len", sometrue );
|
||||
throwsLuaError( "len", somefalse );
|
||||
throwsLuaError( "len", zero );
|
||||
throwsLuaError( "len", intint );
|
||||
throwsLuaError( "len", longdouble );
|
||||
throwsLuaError( "len", doubledouble );
|
||||
assertEquals( LuaInteger.valueOf(samplestringstring.length()), stringstring.len() );
|
||||
assertEquals( LuaInteger.valueOf(samplestringint.length()), stringint.len() );
|
||||
assertEquals( LuaInteger.valueOf(samplestringlong.length()), stringlong.len() );
|
||||
assertEquals( LuaInteger.valueOf(samplestringdouble.length()), stringdouble.len() );
|
||||
assertEquals( LuaInteger.valueOf(2), table.len() );
|
||||
throwsLuaError( "len", somefunc );
|
||||
throwsLuaError( "len", thread );
|
||||
throwsLuaError( "len", someclosure );
|
||||
throwsLuaError( "len", userdataobj );
|
||||
throwsLuaError( "len", userdatacls );
|
||||
}
|
||||
|
||||
public void testLength() {
|
||||
throwsLuaError( "length", somenil );
|
||||
throwsLuaError( "length", sometrue );
|
||||
throwsLuaError( "length", somefalse );
|
||||
throwsLuaError( "length", zero );
|
||||
throwsLuaError( "length", intint );
|
||||
throwsLuaError( "length", longdouble );
|
||||
throwsLuaError( "length", doubledouble );
|
||||
assertEquals( samplestringstring.length(), stringstring.length() );
|
||||
assertEquals( samplestringint.length(), stringint.length() );
|
||||
assertEquals( samplestringlong.length(), stringlong.length() );
|
||||
assertEquals( samplestringdouble.length(), stringdouble.length() );
|
||||
assertEquals( 2, table.length() );
|
||||
throwsLuaError( "length", somefunc );
|
||||
throwsLuaError( "length", thread );
|
||||
throwsLuaError( "length", someclosure );
|
||||
throwsLuaError( "length", userdataobj );
|
||||
throwsLuaError( "length", userdatacls );
|
||||
}
|
||||
|
||||
public Prototype createPrototype( String script, String name ) {
|
||||
try {
|
||||
Globals globals = org.luaj.vm2.lib.jse.JsePlatform.standardGlobals();
|
||||
Reader reader = new StringReader(script);
|
||||
return globals.compilePrototype(reader, name);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
fail(e.toString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void testFunctionClosureThreadEnv() {
|
||||
|
||||
// set up suitable environments for execution
|
||||
LuaValue aaa = LuaValue.valueOf("aaa");
|
||||
LuaValue eee = LuaValue.valueOf("eee");
|
||||
final Globals globals = org.luaj.vm2.lib.jse.JsePlatform.standardGlobals();
|
||||
LuaTable newenv = LuaValue.tableOf( new LuaValue[] {
|
||||
LuaValue.valueOf("a"), LuaValue.valueOf("aaa"),
|
||||
LuaValue.valueOf("b"), LuaValue.valueOf("bbb"), } );
|
||||
LuaTable mt = LuaValue.tableOf( new LuaValue[] { LuaValue.INDEX, globals } );
|
||||
newenv.setmetatable(mt);
|
||||
globals.set("a", aaa);
|
||||
newenv.set("a", eee);
|
||||
|
||||
// function tests
|
||||
{
|
||||
LuaFunction f = new ZeroArgFunction() { public LuaValue call() { return globals.get("a");}};
|
||||
assertEquals( aaa, f.call() );
|
||||
}
|
||||
|
||||
// closure tests
|
||||
{
|
||||
Prototype p = createPrototype( "return a\n", "closuretester" );
|
||||
LuaClosure c = new LuaClosure(p, globals);
|
||||
|
||||
// Test that a clusure with a custom enviroment uses that environment.
|
||||
assertEquals( aaa, c.call() );
|
||||
c = new LuaClosure(p, newenv);
|
||||
assertEquals( newenv, c.upValues[0].getValue() );
|
||||
assertEquals( eee, c.call() );
|
||||
}
|
||||
}
|
||||
}
|
||||
232
luaj-test/src/test/java/org/luaj/vm2/MathLibTest.java
Normal file
232
luaj-test/src/test/java/org/luaj/vm2/MathLibTest.java
Normal file
@@ -0,0 +1,232 @@
|
||||
package org.luaj.vm2;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.lib.jme.JmePlatform;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
|
||||
public class MathLibTest extends TestCase {
|
||||
|
||||
private LuaValue j2se;
|
||||
private LuaValue j2me;
|
||||
private boolean supportedOnJ2me;
|
||||
|
||||
public MathLibTest() {
|
||||
j2se = JsePlatform.standardGlobals().get("math");
|
||||
j2me = JmePlatform.standardGlobals().get("math");
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
supportedOnJ2me = true;
|
||||
}
|
||||
|
||||
public void testMathDPow() {
|
||||
assertEquals( 1, j2mepow(2, 0), 0 );
|
||||
assertEquals( 2, j2mepow(2, 1), 0 );
|
||||
assertEquals( 8, j2mepow(2, 3), 0 );
|
||||
assertEquals( -8, j2mepow(-2, 3), 0 );
|
||||
assertEquals( 1/8., j2mepow(2, -3), 0 );
|
||||
assertEquals( -1/8., j2mepow(-2, -3), 0 );
|
||||
assertEquals( 16, j2mepow(256, .5), 0 );
|
||||
assertEquals( 4, j2mepow(256, .25), 0 );
|
||||
assertEquals( 64, j2mepow(256, .75), 0 );
|
||||
assertEquals( 1./16, j2mepow(256, - .5), 0 );
|
||||
assertEquals( 1./ 4, j2mepow(256, -.25), 0 );
|
||||
assertEquals( 1./64, j2mepow(256, -.75), 0 );
|
||||
assertEquals( Double.NaN, j2mepow(-256, .5), 0 );
|
||||
assertEquals( 1, j2mepow(.5, 0), 0 );
|
||||
assertEquals( .5, j2mepow(.5, 1), 0 );
|
||||
assertEquals(.125, j2mepow(.5, 3), 0 );
|
||||
assertEquals( 2, j2mepow(.5, -1), 0 );
|
||||
assertEquals( 8, j2mepow(.5, -3), 0 );
|
||||
assertEquals(1, j2mepow(0.0625, 0), 0 );
|
||||
assertEquals(0.00048828125, j2mepow(0.0625, 2.75), 0 );
|
||||
}
|
||||
|
||||
private double j2mepow(double x, double y) {
|
||||
return j2me.get("pow").call(LuaValue.valueOf(x),LuaValue.valueOf(y)).todouble();
|
||||
}
|
||||
|
||||
public void testAbs() {
|
||||
tryMathOp( "abs", 23.45 );
|
||||
tryMathOp( "abs", -23.45 );
|
||||
}
|
||||
|
||||
public void testCos() {
|
||||
tryTrigOps( "cos" );
|
||||
}
|
||||
|
||||
public void testCosh() {
|
||||
supportedOnJ2me = false;
|
||||
tryTrigOps( "cosh" );
|
||||
}
|
||||
|
||||
public void testDeg() {
|
||||
tryTrigOps( "deg" );
|
||||
}
|
||||
|
||||
public void testExp() {
|
||||
//supportedOnJ2me = false;
|
||||
tryMathOp( "exp", 0 );
|
||||
tryMathOp( "exp", 0.1 );
|
||||
tryMathOp( "exp", .9 );
|
||||
tryMathOp( "exp", 1. );
|
||||
tryMathOp( "exp", 9 );
|
||||
tryMathOp( "exp", -.1 );
|
||||
tryMathOp( "exp", -.9 );
|
||||
tryMathOp( "exp", -1. );
|
||||
tryMathOp( "exp", -9 );
|
||||
}
|
||||
|
||||
public void testLog() {
|
||||
supportedOnJ2me = false;
|
||||
tryMathOp( "log", 0.1 );
|
||||
tryMathOp( "log", .9 );
|
||||
tryMathOp( "log", 1. );
|
||||
tryMathOp( "log", 9 );
|
||||
tryMathOp( "log", -.1 );
|
||||
tryMathOp( "log", -.9 );
|
||||
tryMathOp( "log", -1. );
|
||||
tryMathOp( "log", -9 );
|
||||
}
|
||||
|
||||
public void testRad() {
|
||||
tryMathOp( "rad", 0 );
|
||||
tryMathOp( "rad", 0.1 );
|
||||
tryMathOp( "rad", .9 );
|
||||
tryMathOp( "rad", 1. );
|
||||
tryMathOp( "rad", 9 );
|
||||
tryMathOp( "rad", 10 );
|
||||
tryMathOp( "rad", 100 );
|
||||
tryMathOp( "rad", -.1 );
|
||||
tryMathOp( "rad", -.9 );
|
||||
tryMathOp( "rad", -1. );
|
||||
tryMathOp( "rad", -9 );
|
||||
tryMathOp( "rad", -10 );
|
||||
tryMathOp( "rad", -100 );
|
||||
}
|
||||
|
||||
public void testSin() {
|
||||
tryTrigOps( "sin" );
|
||||
}
|
||||
|
||||
public void testSinh() {
|
||||
supportedOnJ2me = false;
|
||||
tryTrigOps( "sinh" );
|
||||
}
|
||||
|
||||
public void testSqrt() {
|
||||
tryMathOp( "sqrt", 0 );
|
||||
tryMathOp( "sqrt", 0.1 );
|
||||
tryMathOp( "sqrt", .9 );
|
||||
tryMathOp( "sqrt", 1. );
|
||||
tryMathOp( "sqrt", 9 );
|
||||
tryMathOp( "sqrt", 10 );
|
||||
tryMathOp( "sqrt", 100 );
|
||||
}
|
||||
public void testTan() {
|
||||
tryTrigOps( "tan" );
|
||||
}
|
||||
|
||||
public void testTanh() {
|
||||
supportedOnJ2me = false;
|
||||
tryTrigOps( "tanh" );
|
||||
}
|
||||
|
||||
public void testAtan2() {
|
||||
supportedOnJ2me = false;
|
||||
tryDoubleOps( "atan2", false );
|
||||
}
|
||||
|
||||
public void testFmod() {
|
||||
tryDoubleOps( "fmod", false );
|
||||
}
|
||||
|
||||
public void testPow() {
|
||||
tryDoubleOps( "pow", true );
|
||||
}
|
||||
|
||||
private void tryDoubleOps( String op, boolean positiveOnly ) {
|
||||
// y>0, x>0
|
||||
tryMathOp( op, 0.1, 4.0 );
|
||||
tryMathOp( op, .9, 4.0 );
|
||||
tryMathOp( op, 1., 4.0 );
|
||||
tryMathOp( op, 9, 4.0 );
|
||||
tryMathOp( op, 10, 4.0 );
|
||||
tryMathOp( op, 100, 4.0 );
|
||||
|
||||
// y>0, x<0
|
||||
tryMathOp( op, 0.1, -4.0 );
|
||||
tryMathOp( op, .9, -4.0 );
|
||||
tryMathOp( op, 1., -4.0 );
|
||||
tryMathOp( op, 9, -4.0 );
|
||||
tryMathOp( op, 10, -4.0 );
|
||||
tryMathOp( op, 100, -4.0 );
|
||||
|
||||
if ( ! positiveOnly ) {
|
||||
// y<0, x>0
|
||||
tryMathOp( op, -0.1, 4.0 );
|
||||
tryMathOp( op, -.9, 4.0 );
|
||||
tryMathOp( op, -1., 4.0 );
|
||||
tryMathOp( op, -9, 4.0 );
|
||||
tryMathOp( op, -10, 4.0 );
|
||||
tryMathOp( op, -100, 4.0 );
|
||||
|
||||
// y<0, x<0
|
||||
tryMathOp( op, -0.1, -4.0 );
|
||||
tryMathOp( op, -.9, -4.0 );
|
||||
tryMathOp( op, -1., -4.0 );
|
||||
tryMathOp( op, -9, -4.0 );
|
||||
tryMathOp( op, -10, -4.0 );
|
||||
tryMathOp( op, -100, -4.0 );
|
||||
}
|
||||
|
||||
// degenerate cases
|
||||
tryMathOp( op, 0, 1 );
|
||||
tryMathOp( op, 1, 0 );
|
||||
tryMathOp( op, -1, 0 );
|
||||
tryMathOp( op, 0, -1 );
|
||||
tryMathOp( op, 0, 0 );
|
||||
}
|
||||
|
||||
private void tryTrigOps(String op) {
|
||||
tryMathOp( op, 0 );
|
||||
tryMathOp( op, Math.PI/8 );
|
||||
tryMathOp( op, Math.PI*7/8 );
|
||||
tryMathOp( op, Math.PI*8/8 );
|
||||
tryMathOp( op, Math.PI*9/8 );
|
||||
tryMathOp( op, -Math.PI/8 );
|
||||
tryMathOp( op, -Math.PI*7/8 );
|
||||
tryMathOp( op, -Math.PI*8/8 );
|
||||
tryMathOp( op, -Math.PI*9/8 );
|
||||
}
|
||||
|
||||
private void tryMathOp(String op, double x) {
|
||||
try {
|
||||
double expected = j2se.get(op).call( LuaValue.valueOf(x)).todouble();
|
||||
double actual = j2me.get(op).call( LuaValue.valueOf(x)).todouble();
|
||||
if ( supportedOnJ2me )
|
||||
assertEquals( expected, actual, 1.e-4 );
|
||||
else
|
||||
fail("j2me should throw exception for math."+op+" but returned "+actual);
|
||||
} catch ( LuaError lee ) {
|
||||
if ( supportedOnJ2me )
|
||||
throw lee;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void tryMathOp(String op, double a, double b) {
|
||||
try {
|
||||
double expected = j2se.get(op).call( LuaValue.valueOf(a), LuaValue.valueOf(b)).todouble();
|
||||
double actual = j2me.get(op).call( LuaValue.valueOf(a), LuaValue.valueOf(b)).todouble();
|
||||
if ( supportedOnJ2me )
|
||||
assertEquals( expected, actual, 1.e-5 );
|
||||
else
|
||||
fail("j2me should throw exception for math."+op+" but returned "+actual);
|
||||
} catch ( LuaError lee ) {
|
||||
if ( supportedOnJ2me )
|
||||
throw lee;
|
||||
}
|
||||
}
|
||||
}
|
||||
366
luaj-test/src/test/java/org/luaj/vm2/MetatableTest.java
Normal file
366
luaj-test/src/test/java/org/luaj/vm2/MetatableTest.java
Normal file
@@ -0,0 +1,366 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.TypeTest.MyData;
|
||||
import org.luaj.vm2.lib.StringLib;
|
||||
import org.luaj.vm2.lib.ThreeArgFunction;
|
||||
import org.luaj.vm2.lib.TwoArgFunction;
|
||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
||||
|
||||
public class MetatableTest extends TestCase {
|
||||
|
||||
private final String samplestring = "abcdef";
|
||||
private final Object sampleobject = new Object();
|
||||
private final MyData sampledata = new MyData();
|
||||
|
||||
private final LuaValue string = LuaValue.valueOf(samplestring);
|
||||
private final LuaTable table = LuaValue.tableOf();
|
||||
private final LuaFunction function = new ZeroArgFunction() { public LuaValue call() { return NONE;}};
|
||||
private final LuaThread thread = new LuaThread(new Globals(), function);
|
||||
private final LuaClosure closure = new LuaClosure(new Prototype(), new LuaTable());
|
||||
private final LuaUserdata userdata = LuaValue.userdataOf(sampleobject);
|
||||
private final LuaUserdata userdatamt = LuaValue.userdataOf(sampledata,table);
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
// needed for metatable ops to work on strings
|
||||
new StringLib();
|
||||
}
|
||||
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
LuaBoolean.s_metatable = null;
|
||||
LuaFunction.s_metatable = null;
|
||||
LuaNil.s_metatable = null;
|
||||
LuaNumber.s_metatable = null;
|
||||
// LuaString.s_metatable = null;
|
||||
LuaThread.s_metatable = null;
|
||||
}
|
||||
|
||||
public void testGetMetatable() {
|
||||
assertEquals( null, LuaValue.NIL.getmetatable() );
|
||||
assertEquals( null, LuaValue.TRUE.getmetatable() );
|
||||
assertEquals( null, LuaValue.ONE.getmetatable() );
|
||||
// assertEquals( null, string.getmetatable() );
|
||||
assertEquals( null, table.getmetatable() );
|
||||
assertEquals( null, function.getmetatable() );
|
||||
assertEquals( null, thread.getmetatable() );
|
||||
assertEquals( null, closure.getmetatable() );
|
||||
assertEquals( null, userdata.getmetatable() );
|
||||
assertEquals( table, userdatamt.getmetatable() );
|
||||
}
|
||||
|
||||
public void testSetMetatable() {
|
||||
LuaValue mt = LuaValue.tableOf();
|
||||
assertEquals( null, table.getmetatable() );
|
||||
assertEquals( null, userdata.getmetatable() );
|
||||
assertEquals( table, userdatamt.getmetatable() );
|
||||
assertEquals( table, table.setmetatable(mt) );
|
||||
assertEquals( userdata, userdata.setmetatable(mt) );
|
||||
assertEquals( userdatamt, userdatamt.setmetatable(mt) );
|
||||
assertEquals( mt, table.getmetatable() );
|
||||
assertEquals( mt, userdata.getmetatable() );
|
||||
assertEquals( mt, userdatamt.getmetatable() );
|
||||
|
||||
// these all get metatable behind-the-scenes
|
||||
assertEquals( null, LuaValue.NIL.getmetatable() );
|
||||
assertEquals( null, LuaValue.TRUE.getmetatable() );
|
||||
assertEquals( null, LuaValue.ONE.getmetatable() );
|
||||
// assertEquals( null, string.getmetatable() );
|
||||
assertEquals( null, function.getmetatable() );
|
||||
assertEquals( null, thread.getmetatable() );
|
||||
assertEquals( null, closure.getmetatable() );
|
||||
LuaNil.s_metatable = mt;
|
||||
assertEquals( mt, LuaValue.NIL.getmetatable() );
|
||||
assertEquals( null, LuaValue.TRUE.getmetatable() );
|
||||
assertEquals( null, LuaValue.ONE.getmetatable() );
|
||||
// assertEquals( null, string.getmetatable() );
|
||||
assertEquals( null, function.getmetatable() );
|
||||
assertEquals( null, thread.getmetatable() );
|
||||
assertEquals( null, closure.getmetatable() );
|
||||
LuaBoolean.s_metatable = mt;
|
||||
assertEquals( mt, LuaValue.TRUE.getmetatable() );
|
||||
assertEquals( null, LuaValue.ONE.getmetatable() );
|
||||
// assertEquals( null, string.getmetatable() );
|
||||
assertEquals( null, function.getmetatable() );
|
||||
assertEquals( null, thread.getmetatable() );
|
||||
assertEquals( null, closure.getmetatable() );
|
||||
LuaNumber.s_metatable = mt;
|
||||
assertEquals( mt, LuaValue.ONE.getmetatable() );
|
||||
assertEquals( mt, LuaValue.valueOf(1.25).getmetatable() );
|
||||
// assertEquals( null, string.getmetatable() );
|
||||
assertEquals( null, function.getmetatable() );
|
||||
assertEquals( null, thread.getmetatable() );
|
||||
assertEquals( null, closure.getmetatable() );
|
||||
// LuaString.s_metatable = mt;
|
||||
// assertEquals( mt, string.getmetatable() );
|
||||
assertEquals( null, function.getmetatable() );
|
||||
assertEquals( null, thread.getmetatable() );
|
||||
assertEquals( null, closure.getmetatable() );
|
||||
LuaFunction.s_metatable = mt;
|
||||
assertEquals( mt, function.getmetatable() );
|
||||
assertEquals( null, thread.getmetatable() );
|
||||
LuaThread.s_metatable = mt;
|
||||
assertEquals( mt, thread.getmetatable() );
|
||||
}
|
||||
|
||||
public void testMetatableIndex() {
|
||||
assertEquals( table, table.setmetatable(null) );
|
||||
assertEquals( userdata, userdata.setmetatable(null) );
|
||||
assertEquals( userdatamt, userdatamt.setmetatable(null) );
|
||||
assertEquals( LuaValue.NIL, table.get(1) );
|
||||
assertEquals( LuaValue.NIL, userdata.get(1) );
|
||||
assertEquals( LuaValue.NIL, userdatamt.get(1) );
|
||||
|
||||
// empty metatable
|
||||
LuaValue mt = LuaValue.tableOf();
|
||||
assertEquals( table, table.setmetatable(mt) );
|
||||
assertEquals( userdata, userdata.setmetatable(mt) );
|
||||
LuaBoolean.s_metatable = mt;
|
||||
LuaFunction.s_metatable = mt;
|
||||
LuaNil.s_metatable = mt;
|
||||
LuaNumber.s_metatable = mt;
|
||||
// LuaString.s_metatable = mt;
|
||||
LuaThread.s_metatable = mt;
|
||||
assertEquals( mt, table.getmetatable() );
|
||||
assertEquals( mt, userdata.getmetatable() );
|
||||
assertEquals( mt, LuaValue.NIL.getmetatable() );
|
||||
assertEquals( mt, LuaValue.TRUE.getmetatable() );
|
||||
assertEquals( mt, LuaValue.ONE.getmetatable() );
|
||||
// assertEquals( StringLib.instance, string.getmetatable() );
|
||||
assertEquals( mt, function.getmetatable() );
|
||||
assertEquals( mt, thread.getmetatable() );
|
||||
|
||||
// plain metatable
|
||||
LuaValue abc = LuaValue.valueOf("abc");
|
||||
mt.set( LuaValue.INDEX, LuaValue.listOf(new LuaValue[] { abc } ) );
|
||||
assertEquals( abc, table.get(1) );
|
||||
assertEquals( abc, userdata.get(1) );
|
||||
assertEquals( abc, LuaValue.NIL.get(1) );
|
||||
assertEquals( abc, LuaValue.TRUE.get(1) );
|
||||
assertEquals( abc, LuaValue.ONE.get(1) );
|
||||
// assertEquals( abc, string.get(1) );
|
||||
assertEquals( abc, function.get(1) );
|
||||
assertEquals( abc, thread.get(1) );
|
||||
|
||||
// plain metatable
|
||||
mt.set( LuaValue.INDEX, new TwoArgFunction() {
|
||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||
return LuaValue.valueOf( arg1.typename()+"["+arg2.tojstring()+"]=xyz" );
|
||||
}
|
||||
|
||||
});
|
||||
assertEquals( "table[1]=xyz", table.get(1).tojstring() );
|
||||
assertEquals( "userdata[1]=xyz", userdata.get(1).tojstring() );
|
||||
assertEquals( "nil[1]=xyz", LuaValue.NIL.get(1).tojstring() );
|
||||
assertEquals( "boolean[1]=xyz", LuaValue.TRUE.get(1).tojstring() );
|
||||
assertEquals( "number[1]=xyz", LuaValue.ONE.get(1).tojstring() );
|
||||
// assertEquals( "string[1]=xyz", string.get(1).tojstring() );
|
||||
assertEquals( "function[1]=xyz", function.get(1).tojstring() );
|
||||
assertEquals( "thread[1]=xyz", thread.get(1).tojstring() );
|
||||
}
|
||||
|
||||
|
||||
public void testMetatableNewIndex() {
|
||||
// empty metatable
|
||||
LuaValue mt = LuaValue.tableOf();
|
||||
assertEquals( table, table.setmetatable(mt) );
|
||||
assertEquals( userdata, userdata.setmetatable(mt) );
|
||||
LuaBoolean.s_metatable = mt;
|
||||
LuaFunction.s_metatable = mt;
|
||||
LuaNil.s_metatable = mt;
|
||||
LuaNumber.s_metatable = mt;
|
||||
// LuaString.s_metatable = mt;
|
||||
LuaThread.s_metatable = mt;
|
||||
|
||||
// plain metatable
|
||||
final LuaValue fallback = LuaValue.tableOf();
|
||||
LuaValue abc = LuaValue.valueOf("abc");
|
||||
mt.set( LuaValue.NEWINDEX, fallback );
|
||||
table.set(2,abc);
|
||||
userdata.set(3,abc);
|
||||
LuaValue.NIL.set(4,abc);
|
||||
LuaValue.TRUE.set(5,abc);
|
||||
LuaValue.ONE.set(6,abc);
|
||||
// string.set(7,abc);
|
||||
function.set(8,abc);
|
||||
thread.set(9,abc);
|
||||
assertEquals( abc, fallback.get(2) );
|
||||
assertEquals( abc, fallback.get(3) );
|
||||
assertEquals( abc, fallback.get(4) );
|
||||
assertEquals( abc, fallback.get(5) );
|
||||
assertEquals( abc, fallback.get(6) );
|
||||
// assertEquals( abc, StringLib.instance.get(7) );
|
||||
assertEquals( abc, fallback.get(8) );
|
||||
assertEquals( abc, fallback.get(9) );
|
||||
|
||||
// metatable with function call
|
||||
mt.set( LuaValue.NEWINDEX, new ThreeArgFunction() {
|
||||
public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
|
||||
fallback.rawset(arg2, LuaValue.valueOf( "via-func-"+arg3 ));
|
||||
return NONE;
|
||||
}
|
||||
|
||||
});
|
||||
table.set(12,abc);
|
||||
userdata.set(13,abc);
|
||||
LuaValue.NIL.set(14,abc);
|
||||
LuaValue.TRUE.set(15,abc);
|
||||
LuaValue.ONE.set(16,abc);
|
||||
// string.set(17,abc);
|
||||
function.set(18,abc);
|
||||
thread.set(19,abc);
|
||||
LuaValue via = LuaValue.valueOf( "via-func-abc" );
|
||||
assertEquals( via, fallback.get(12) );
|
||||
assertEquals( via, fallback.get(13) );
|
||||
assertEquals( via, fallback.get(14) );
|
||||
assertEquals( via, fallback.get(15) );
|
||||
assertEquals( via, fallback.get(16) );
|
||||
// assertEquals( via, StringLib.instance.get(17) );
|
||||
assertEquals( via, fallback.get(18) );
|
||||
assertEquals( via, fallback.get(19) );
|
||||
}
|
||||
|
||||
|
||||
private void checkTable( LuaValue t,
|
||||
LuaValue aa, LuaValue bb, LuaValue cc, LuaValue dd, LuaValue ee, LuaValue ff, LuaValue gg,
|
||||
LuaValue ra, LuaValue rb, LuaValue rc, LuaValue rd, LuaValue re, LuaValue rf, LuaValue rg ) {
|
||||
assertEquals( aa, t.get("aa") );
|
||||
assertEquals( bb, t.get("bb") );
|
||||
assertEquals( cc, t.get("cc") );
|
||||
assertEquals( dd, t.get("dd") );
|
||||
assertEquals( ee, t.get("ee") );
|
||||
assertEquals( ff, t.get("ff") );
|
||||
assertEquals( gg, t.get("gg") );
|
||||
assertEquals( ra, t.rawget("aa") );
|
||||
assertEquals( rb, t.rawget("bb") );
|
||||
assertEquals( rc, t.rawget("cc") );
|
||||
assertEquals( rd, t.rawget("dd") );
|
||||
assertEquals( re, t.rawget("ee") );
|
||||
assertEquals( rf, t.rawget("ff") );
|
||||
assertEquals( rg, t.rawget("gg") );
|
||||
}
|
||||
|
||||
private LuaValue makeTable( String key1, String val1, String key2, String val2 ) {
|
||||
return LuaValue.tableOf( new LuaValue[] {
|
||||
LuaValue.valueOf(key1), LuaValue.valueOf(val1),
|
||||
LuaValue.valueOf(key2), LuaValue.valueOf(val2),
|
||||
} );
|
||||
}
|
||||
|
||||
public void testRawsetMetatableSet() {
|
||||
// set up tables
|
||||
LuaValue m = makeTable( "aa", "aaa", "bb", "bbb" );
|
||||
m.set(LuaValue.INDEX, m);
|
||||
m.set(LuaValue.NEWINDEX, m);
|
||||
LuaValue s = makeTable( "cc", "ccc", "dd", "ddd" );
|
||||
LuaValue t = makeTable( "cc", "ccc", "dd", "ddd" );
|
||||
t.setmetatable(m);
|
||||
LuaValue aaa = LuaValue.valueOf("aaa");
|
||||
LuaValue bbb = LuaValue.valueOf("bbb");
|
||||
LuaValue ccc = LuaValue.valueOf("ccc");
|
||||
LuaValue ddd = LuaValue.valueOf("ddd");
|
||||
LuaValue ppp = LuaValue.valueOf("ppp");
|
||||
LuaValue qqq = LuaValue.valueOf("qqq");
|
||||
LuaValue rrr = LuaValue.valueOf("rrr");
|
||||
LuaValue sss = LuaValue.valueOf("sss");
|
||||
LuaValue ttt = LuaValue.valueOf("ttt");
|
||||
LuaValue www = LuaValue.valueOf("www");
|
||||
LuaValue xxx = LuaValue.valueOf("xxx");
|
||||
LuaValue yyy = LuaValue.valueOf("yyy");
|
||||
LuaValue zzz = LuaValue.valueOf("zzz");
|
||||
LuaValue nil = LuaValue.NIL;
|
||||
|
||||
// check initial values
|
||||
// values via "bet()" values via "rawget()"
|
||||
checkTable( s, nil,nil,ccc,ddd,nil,nil,nil, nil,nil,ccc,ddd,nil,nil,nil );
|
||||
checkTable( t, aaa,bbb,ccc,ddd,nil,nil,nil, nil,nil,ccc,ddd,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,nil,nil, aaa,bbb,nil,nil,nil,nil,nil );
|
||||
|
||||
// rawset()
|
||||
s.rawset("aa", www);
|
||||
checkTable( s, www,nil,ccc,ddd,nil,nil,nil, www,nil,ccc,ddd,nil,nil,nil );
|
||||
checkTable( t, aaa,bbb,ccc,ddd,nil,nil,nil, nil,nil,ccc,ddd,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,nil,nil, aaa,bbb,nil,nil,nil,nil,nil );
|
||||
s.rawset("cc", xxx);
|
||||
checkTable( s, www,nil,xxx,ddd,nil,nil,nil, www,nil,xxx,ddd,nil,nil,nil );
|
||||
checkTable( t, aaa,bbb,ccc,ddd,nil,nil,nil, nil,nil,ccc,ddd,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,nil,nil, aaa,bbb,nil,nil,nil,nil,nil );
|
||||
t.rawset("bb", yyy);
|
||||
checkTable( s, www,nil,xxx,ddd,nil,nil,nil, www,nil,xxx,ddd,nil,nil,nil );
|
||||
checkTable( t, aaa,yyy,ccc,ddd,nil,nil,nil, nil,yyy,ccc,ddd,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,nil,nil, aaa,bbb,nil,nil,nil,nil,nil );
|
||||
t.rawset("dd", zzz);
|
||||
checkTable( s, www,nil,xxx,ddd,nil,nil,nil, www,nil,xxx,ddd,nil,nil,nil );
|
||||
checkTable( t, aaa,yyy,ccc,zzz,nil,nil,nil, nil,yyy,ccc,zzz,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,nil,nil, aaa,bbb,nil,nil,nil,nil,nil );
|
||||
|
||||
// set() invoking metatables
|
||||
s.set("ee", ppp);
|
||||
checkTable( s, www,nil,xxx,ddd,ppp,nil,nil, www,nil,xxx,ddd,ppp,nil,nil );
|
||||
checkTable( t, aaa,yyy,ccc,zzz,nil,nil,nil, nil,yyy,ccc,zzz,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,nil,nil, aaa,bbb,nil,nil,nil,nil,nil );
|
||||
s.set("cc", qqq);
|
||||
checkTable( s, www,nil,qqq,ddd,ppp,nil,nil, www,nil,qqq,ddd,ppp,nil,nil );
|
||||
checkTable( t, aaa,yyy,ccc,zzz,nil,nil,nil, nil,yyy,ccc,zzz,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,nil,nil, aaa,bbb,nil,nil,nil,nil,nil );
|
||||
t.set("ff", rrr);
|
||||
checkTable( s, www,nil,qqq,ddd,ppp,nil,nil, www,nil,qqq,ddd,ppp,nil,nil );
|
||||
checkTable( t, aaa,yyy,ccc,zzz,nil,rrr,nil, nil,yyy,ccc,zzz,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,rrr,nil, aaa,bbb,nil,nil,nil,rrr,nil );
|
||||
t.set("dd", sss);
|
||||
checkTable( s, www,nil,qqq,ddd,ppp,nil,nil, www,nil,qqq,ddd,ppp,nil,nil );
|
||||
checkTable( t, aaa,yyy,ccc,sss,nil,rrr,nil, nil,yyy,ccc,sss,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,rrr,nil, aaa,bbb,nil,nil,nil,rrr,nil );
|
||||
m.set("gg", ttt);
|
||||
checkTable( s, www,nil,qqq,ddd,ppp,nil,nil, www,nil,qqq,ddd,ppp,nil,nil );
|
||||
checkTable( t, aaa,yyy,ccc,sss,nil,rrr,ttt, nil,yyy,ccc,sss,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,rrr,ttt, aaa,bbb,nil,nil,nil,rrr,ttt );
|
||||
|
||||
// make s fall back to t
|
||||
s.setmetatable(LuaValue.tableOf(new LuaValue[] {LuaValue.INDEX,t,LuaValue.NEWINDEX,t}));
|
||||
checkTable( s, www,yyy,qqq,ddd,ppp,rrr,ttt, www,nil,qqq,ddd,ppp,nil,nil );
|
||||
checkTable( t, aaa,yyy,ccc,sss,nil,rrr,ttt, nil,yyy,ccc,sss,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,rrr,ttt, aaa,bbb,nil,nil,nil,rrr,ttt );
|
||||
s.set("aa", www);
|
||||
checkTable( s, www,yyy,qqq,ddd,ppp,rrr,ttt, www,nil,qqq,ddd,ppp,nil,nil );
|
||||
checkTable( t, aaa,yyy,ccc,sss,nil,rrr,ttt, nil,yyy,ccc,sss,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,rrr,ttt, aaa,bbb,nil,nil,nil,rrr,ttt );
|
||||
s.set("bb", zzz);
|
||||
checkTable( s, www,zzz,qqq,ddd,ppp,rrr,ttt, www,nil,qqq,ddd,ppp,nil,nil );
|
||||
checkTable( t, aaa,zzz,ccc,sss,nil,rrr,ttt, nil,zzz,ccc,sss,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,rrr,ttt, aaa,bbb,nil,nil,nil,rrr,ttt );
|
||||
s.set("ee", xxx);
|
||||
checkTable( s, www,zzz,qqq,ddd,xxx,rrr,ttt, www,nil,qqq,ddd,xxx,nil,nil );
|
||||
checkTable( t, aaa,zzz,ccc,sss,nil,rrr,ttt, nil,zzz,ccc,sss,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,rrr,ttt, aaa,bbb,nil,nil,nil,rrr,ttt );
|
||||
s.set("ff", yyy);
|
||||
checkTable( s, www,zzz,qqq,ddd,xxx,yyy,ttt, www,nil,qqq,ddd,xxx,nil,nil );
|
||||
checkTable( t, aaa,zzz,ccc,sss,nil,yyy,ttt, nil,zzz,ccc,sss,nil,nil,nil );
|
||||
checkTable( m, aaa,bbb,nil,nil,nil,yyy,ttt, aaa,bbb,nil,nil,nil,yyy,ttt );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
178
luaj-test/src/test/java/org/luaj/vm2/OrphanedThreadTest.java
Normal file
178
luaj-test/src/test/java/org/luaj/vm2/OrphanedThreadTest.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2012 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;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.lib.OneArgFunction;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
|
||||
|
||||
public class OrphanedThreadTest extends TestCase {
|
||||
|
||||
Globals globals;
|
||||
LuaThread luathread;
|
||||
WeakReference luathr_ref;
|
||||
LuaValue function;
|
||||
WeakReference func_ref;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
LuaThread.thread_orphan_check_interval = 5;
|
||||
globals = JsePlatform.standardGlobals();
|
||||
}
|
||||
|
||||
protected void tearDown() {
|
||||
LuaThread.thread_orphan_check_interval = 30000;
|
||||
}
|
||||
|
||||
public void testCollectOrphanedNormalThread() throws Exception {
|
||||
function = new NormalFunction(globals);
|
||||
doTest(LuaValue.TRUE, LuaValue.ZERO);
|
||||
}
|
||||
|
||||
public void testCollectOrphanedEarlyCompletionThread() throws Exception {
|
||||
function = new EarlyCompletionFunction(globals);
|
||||
doTest(LuaValue.TRUE, LuaValue.ZERO);
|
||||
}
|
||||
|
||||
public void testCollectOrphanedAbnormalThread() throws Exception {
|
||||
function = new AbnormalFunction(globals);
|
||||
doTest(LuaValue.FALSE, LuaValue.valueOf("abnormal condition"));
|
||||
}
|
||||
|
||||
public void testCollectOrphanedClosureThread() throws Exception {
|
||||
String script =
|
||||
"print('in closure, arg is '..(...))\n" +
|
||||
"arg = coroutine.yield(1)\n" +
|
||||
"print('in closure.2, arg is '..arg)\n" +
|
||||
"arg = coroutine.yield(0)\n" +
|
||||
"print('leakage in closure.3, arg is '..arg)\n" +
|
||||
"return 'done'\n";
|
||||
function = globals.load(script, "script");
|
||||
doTest(LuaValue.TRUE, LuaValue.ZERO);
|
||||
}
|
||||
|
||||
public void testCollectOrphanedPcallClosureThread() throws Exception {
|
||||
String script =
|
||||
"f = function(x)\n" +
|
||||
" print('in pcall-closure, arg is '..(x))\n" +
|
||||
" arg = coroutine.yield(1)\n" +
|
||||
" print('in pcall-closure.2, arg is '..arg)\n" +
|
||||
" arg = coroutine.yield(0)\n" +
|
||||
" print('leakage in pcall-closure.3, arg is '..arg)\n" +
|
||||
" return 'done'\n" +
|
||||
"end\n" +
|
||||
"print( 'pcall-closre.result:', pcall( f, ... ) )\n";
|
||||
function = globals.load(script, "script");
|
||||
doTest(LuaValue.TRUE, LuaValue.ZERO);
|
||||
}
|
||||
|
||||
public void testCollectOrphanedLoadCloasureThread() throws Exception {
|
||||
String script =
|
||||
"t = { \"print \", \"'hello, \", \"world'\", }\n" +
|
||||
"i = 0\n" +
|
||||
"arg = ...\n" +
|
||||
"f = function()\n" +
|
||||
" i = i + 1\n" +
|
||||
" print('in load-closure, arg is', arg, 'next is', t[i])\n" +
|
||||
" arg = coroutine.yield(1)\n" +
|
||||
" return t[i]\n" +
|
||||
"end\n" +
|
||||
"load(f)()\n";
|
||||
function = globals.load(script, "script");
|
||||
doTest(LuaValue.TRUE, LuaValue.ONE);
|
||||
}
|
||||
|
||||
private void doTest(LuaValue status2, LuaValue value2) throws Exception {
|
||||
luathread = new LuaThread(globals, function);
|
||||
luathr_ref = new WeakReference(luathread);
|
||||
func_ref = new WeakReference(function);
|
||||
assertNotNull(luathr_ref.get());
|
||||
|
||||
// resume two times
|
||||
Varargs a = luathread.resume(LuaValue.valueOf("foo"));
|
||||
assertEquals(LuaValue.ONE, a.arg(2));
|
||||
assertEquals(LuaValue.TRUE, a.arg1());
|
||||
a = luathread.resume(LuaValue.valueOf("bar"));
|
||||
assertEquals(value2, a.arg(2));
|
||||
assertEquals(status2, a.arg1());
|
||||
|
||||
// drop strong references
|
||||
luathread = null;
|
||||
function = null;
|
||||
|
||||
// gc
|
||||
for (int i=0; i<100 && (luathr_ref.get() != null || func_ref.get() != null); i++) {
|
||||
Runtime.getRuntime().gc();
|
||||
Thread.sleep(5);
|
||||
}
|
||||
|
||||
// check reference
|
||||
assertNull(luathr_ref.get());
|
||||
assertNull(func_ref.get());
|
||||
}
|
||||
|
||||
|
||||
static class NormalFunction extends OneArgFunction {
|
||||
final Globals globals;
|
||||
public NormalFunction(Globals globals) {
|
||||
this.globals = globals;
|
||||
}
|
||||
public LuaValue call(LuaValue arg) {
|
||||
System.out.println("in normal.1, arg is "+arg);
|
||||
arg = globals.yield(ONE).arg1();
|
||||
System.out.println("in normal.2, arg is "+arg);
|
||||
arg = globals.yield(ZERO).arg1();
|
||||
System.out.println("in normal.3, arg is "+arg);
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
static class EarlyCompletionFunction extends OneArgFunction {
|
||||
final Globals globals;
|
||||
public EarlyCompletionFunction(Globals globals) {
|
||||
this.globals = globals;
|
||||
}
|
||||
public LuaValue call(LuaValue arg) {
|
||||
System.out.println("in early.1, arg is "+arg);
|
||||
arg = globals.yield(ONE).arg1();
|
||||
System.out.println("in early.2, arg is "+arg);
|
||||
return ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
static class AbnormalFunction extends OneArgFunction {
|
||||
final Globals globals;
|
||||
public AbnormalFunction(Globals globals) {
|
||||
this.globals = globals;
|
||||
}
|
||||
public LuaValue call(LuaValue arg) {
|
||||
System.out.println("in abnormal.1, arg is "+arg);
|
||||
arg = globals.yield(ONE).arg1();
|
||||
System.out.println("in abnormal.2, arg is "+arg);
|
||||
error("abnormal condition");
|
||||
return ZERO;
|
||||
}
|
||||
}
|
||||
}
|
||||
89
luaj-test/src/test/java/org/luaj/vm2/RequireClassTest.java
Normal file
89
luaj-test/src/test/java/org/luaj/vm2/RequireClassTest.java
Normal file
@@ -0,0 +1,89 @@
|
||||
package org.luaj.vm2;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
import org.luaj.vm2.require.RequireSampleClassCastExcep;
|
||||
import org.luaj.vm2.require.RequireSampleLoadLuaError;
|
||||
import org.luaj.vm2.require.RequireSampleLoadRuntimeExcep;
|
||||
|
||||
public class RequireClassTest extends TestCase {
|
||||
|
||||
private LuaTable globals;
|
||||
private LuaValue require;
|
||||
|
||||
public void setUp() {
|
||||
globals = JsePlatform.standardGlobals();
|
||||
require = globals.get("require");
|
||||
}
|
||||
|
||||
public void testLoadClass() {
|
||||
LuaValue result = globals.load(new org.luaj.vm2.require.RequireSampleSuccess());
|
||||
assertEquals( "require-sample-success-", result.tojstring() );
|
||||
}
|
||||
|
||||
public void testRequireClassSuccess() {
|
||||
LuaValue result = require.call( LuaValue.valueOf("org.luaj.vm2.require.RequireSampleSuccess") );
|
||||
assertEquals( "require-sample-success-org.luaj.vm2.require.RequireSampleSuccess", result.tojstring() );
|
||||
result = require.call( LuaValue.valueOf("org.luaj.vm2.require.RequireSampleSuccess") );
|
||||
assertEquals( "require-sample-success-org.luaj.vm2.require.RequireSampleSuccess", result.tojstring() );
|
||||
}
|
||||
|
||||
public void testRequireClassLoadLuaError() {
|
||||
try {
|
||||
LuaValue result = require.call( LuaValue.valueOf(RequireSampleLoadLuaError.class.getName()) );
|
||||
fail( "incorrectly loaded class that threw lua error");
|
||||
} catch ( LuaError le ) {
|
||||
assertEquals(
|
||||
"sample-load-lua-error",
|
||||
le.getMessage() );
|
||||
}
|
||||
try {
|
||||
LuaValue result = require.call( LuaValue.valueOf(RequireSampleLoadLuaError.class.getName()) );
|
||||
fail( "incorrectly loaded class that threw lua error");
|
||||
} catch ( LuaError le ) {
|
||||
assertEquals(
|
||||
"loop or previous error loading module '"+RequireSampleLoadLuaError.class.getName()+"'",
|
||||
le.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
public void testRequireClassLoadRuntimeException() {
|
||||
try {
|
||||
LuaValue result = require.call( LuaValue.valueOf(RequireSampleLoadRuntimeExcep.class.getName()) );
|
||||
fail( "incorrectly loaded class that threw runtime exception");
|
||||
} catch ( RuntimeException le ) {
|
||||
assertEquals(
|
||||
"sample-load-runtime-exception",
|
||||
le.getMessage() );
|
||||
}
|
||||
try {
|
||||
LuaValue result = require.call( LuaValue.valueOf(RequireSampleLoadRuntimeExcep.class.getName()) );
|
||||
fail( "incorrectly loaded class that threw runtime exception");
|
||||
} catch ( LuaError le ) {
|
||||
assertEquals(
|
||||
"loop or previous error loading module '"+RequireSampleLoadRuntimeExcep.class.getName()+"'",
|
||||
le.getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testRequireClassClassCastException() {
|
||||
try {
|
||||
LuaValue result = require.call( LuaValue.valueOf(RequireSampleClassCastExcep.class.getName()) );
|
||||
fail( "incorrectly loaded class that threw class cast exception");
|
||||
} catch ( LuaError le ) {
|
||||
String msg = le.getMessage();
|
||||
if ( msg.indexOf("not found") < 0 )
|
||||
fail( "expected 'not found' message but got "+msg );
|
||||
}
|
||||
try {
|
||||
LuaValue result = require.call( LuaValue.valueOf(RequireSampleClassCastExcep.class.getName()) );
|
||||
fail( "incorrectly loaded class that threw class cast exception");
|
||||
} catch ( LuaError le ) {
|
||||
String msg = le.getMessage();
|
||||
if ( msg.indexOf("not found") < 0 )
|
||||
fail( "expected 'not found' message but got "+msg );
|
||||
}
|
||||
}
|
||||
}
|
||||
257
luaj-test/src/test/java/org/luaj/vm2/ScriptDrivenTest.java
Normal file
257
luaj-test/src/test/java/org/luaj/vm2/ScriptDrivenTest.java
Normal file
@@ -0,0 +1,257 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.lib.ResourceFinder;
|
||||
import org.luaj.vm2.lib.jse.JseProcess;
|
||||
import org.luaj.vm2.luajc.LuaJC;
|
||||
|
||||
abstract
|
||||
public class ScriptDrivenTest extends TestCase implements ResourceFinder {
|
||||
public static final boolean nocompile = "true".equals(System.getProperty("nocompile"));
|
||||
|
||||
public enum PlatformType {
|
||||
JME, JSE, LUAJIT,
|
||||
}
|
||||
|
||||
private final PlatformType platform;
|
||||
private final String subdir;
|
||||
protected Globals globals;
|
||||
|
||||
static final String zipdir = "test/lua/";
|
||||
static final String zipfile = "luaj3.0-tests.zip";
|
||||
|
||||
protected ScriptDrivenTest( PlatformType platform, String subdir ) {
|
||||
this.platform = platform;
|
||||
this.subdir = subdir;
|
||||
initGlobals();
|
||||
}
|
||||
|
||||
private void initGlobals() {
|
||||
switch ( platform ) {
|
||||
default:
|
||||
case JSE:
|
||||
case LUAJIT:
|
||||
globals = org.luaj.vm2.lib.jse.JsePlatform.debugGlobals();
|
||||
break;
|
||||
case JME:
|
||||
globals = org.luaj.vm2.lib.jme.JmePlatform.debugGlobals();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
initGlobals();
|
||||
globals.finder = this;
|
||||
}
|
||||
|
||||
// ResourceFinder implementation.
|
||||
public InputStream findResource(String filename) {
|
||||
InputStream is = findInPlainFile(filename);
|
||||
if (is != null) return is;
|
||||
is = findInPlainFileAsResource("",filename);
|
||||
if (is != null) return is;
|
||||
is = findInPlainFileAsResource("/",filename);
|
||||
if (is != null) return is;
|
||||
is = findInZipFileAsPlainFile(filename);
|
||||
if (is != null) return is;
|
||||
is = findInZipFileAsResource("",filename);
|
||||
if (is != null) return is;
|
||||
is = findInZipFileAsResource("/",filename);
|
||||
return is;
|
||||
}
|
||||
|
||||
private InputStream findInPlainFileAsResource(String prefix, String filename) {
|
||||
return getClass().getResourceAsStream(prefix + subdir + filename);
|
||||
}
|
||||
|
||||
private InputStream findInPlainFile(String filename) {
|
||||
try {
|
||||
File f = new File(zipdir+subdir+filename);
|
||||
if (f.exists())
|
||||
return new FileInputStream(f);
|
||||
} catch ( IOException ioe ) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private InputStream findInZipFileAsPlainFile(String filename) {
|
||||
URL zip;
|
||||
File file = new File(zipdir+zipfile);
|
||||
try {
|
||||
if ( file.exists() ) {
|
||||
zip = file.toURI().toURL();
|
||||
String path = "jar:"+zip.toExternalForm()+ "!/"+subdir+filename;
|
||||
URL url = new URL(path);
|
||||
return url.openStream();
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
} catch (FileNotFoundException e) {
|
||||
// Ignore and return null.
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private InputStream findInZipFileAsResource(String prefix, String filename) {
|
||||
URL zip = null;
|
||||
zip = getClass().getResource(zipfile);
|
||||
if ( zip != null )
|
||||
try {
|
||||
String path = "jar:"+zip.toExternalForm()+ "!/"+subdir+filename;
|
||||
URL url = new URL(path);
|
||||
return url.openStream();
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// */
|
||||
protected void runTest(String testName) {
|
||||
try {
|
||||
// override print()
|
||||
final ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
final PrintStream oldps = globals.STDOUT;
|
||||
final PrintStream ps = new PrintStream( output );
|
||||
globals.STDOUT = ps;
|
||||
|
||||
// run the script
|
||||
try {
|
||||
LuaValue chunk = loadScript(testName, globals);
|
||||
chunk.call(LuaValue.valueOf(platform.toString()));
|
||||
|
||||
ps.flush();
|
||||
String actualOutput = new String(output.toByteArray());
|
||||
String expectedOutput = getExpectedOutput(testName);
|
||||
actualOutput = actualOutput.replaceAll("\r\n", "\n");
|
||||
expectedOutput = expectedOutput.replaceAll("\r\n", "\n");
|
||||
|
||||
assertEquals(expectedOutput, actualOutput);
|
||||
} finally {
|
||||
globals.STDOUT = oldps;
|
||||
ps.close();
|
||||
}
|
||||
} catch ( IOException ioe ) {
|
||||
throw new RuntimeException(ioe.toString());
|
||||
} catch ( InterruptedException ie ) {
|
||||
throw new RuntimeException(ie.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected LuaValue loadScript(String name, Globals globals) throws IOException {
|
||||
InputStream script = this.findResource(name+".lua");
|
||||
if ( script == null )
|
||||
fail("Could not load script for test case: " + name);
|
||||
try {
|
||||
switch ( this.platform ) {
|
||||
case LUAJIT:
|
||||
if ( nocompile ) {
|
||||
LuaValue c = (LuaValue) Class.forName(name).newInstance();
|
||||
return c;
|
||||
} else {
|
||||
LuaJC.install(globals);
|
||||
return globals.load(script, name, "bt", globals);
|
||||
}
|
||||
default:
|
||||
return globals.load(script, "@"+name+".lua", "bt", globals);
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
throw new IOException( e.toString() );
|
||||
} finally {
|
||||
script.close();
|
||||
}
|
||||
}
|
||||
|
||||
private String getExpectedOutput(final String name) throws IOException,
|
||||
InterruptedException {
|
||||
InputStream output = this.findResource(name+".out");
|
||||
if (output != null)
|
||||
try {
|
||||
return readString(output);
|
||||
} finally {
|
||||
output.close();
|
||||
}
|
||||
String expectedOutput = executeLuaProcess(name);
|
||||
if (expectedOutput == null)
|
||||
throw new IOException("Failed to get comparison output or run process for "+name);
|
||||
return expectedOutput;
|
||||
}
|
||||
|
||||
private String executeLuaProcess(String name) throws IOException, InterruptedException {
|
||||
InputStream script = findResource(name+".lua");
|
||||
if ( script == null )
|
||||
throw new IOException("Failed to find source file "+script);
|
||||
try {
|
||||
String luaCommand = System.getProperty("LUA_COMMAND");
|
||||
if ( luaCommand == null )
|
||||
luaCommand = "lua";
|
||||
String[] args = new String[] { luaCommand, "-", platform.toString() };
|
||||
return collectProcessOutput(args, script);
|
||||
} finally {
|
||||
script.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static String collectProcessOutput(String[] cmd, final InputStream input)
|
||||
throws IOException, InterruptedException {
|
||||
Runtime r = Runtime.getRuntime();
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
new JseProcess(cmd, input, baos, System.err).waitFor();
|
||||
return new String(baos.toByteArray());
|
||||
}
|
||||
|
||||
private 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
381
luaj-test/src/test/java/org/luaj/vm2/StringTest.java
Normal file
381
luaj-test/src/test/java/org/luaj/vm2/StringTest.java
Normal file
@@ -0,0 +1,381 @@
|
||||
package org.luaj.vm2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
|
||||
public class StringTest extends TestCase {
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
JsePlatform.standardGlobals();
|
||||
}
|
||||
|
||||
public void testToInputStream() throws IOException {
|
||||
LuaString str = LuaString.valueOf("Hello");
|
||||
|
||||
InputStream is = str.toInputStream();
|
||||
|
||||
assertEquals( 'H', is.read() );
|
||||
assertEquals( 'e', is.read() );
|
||||
assertEquals( 2, is.skip( 2 ) );
|
||||
assertEquals( 'o', is.read() );
|
||||
assertEquals( -1, is.read() );
|
||||
|
||||
assertTrue( is.markSupported() );
|
||||
|
||||
is.reset();
|
||||
|
||||
assertEquals( 'H', is.read() );
|
||||
is.mark( 4 );
|
||||
|
||||
assertEquals( 'e', is.read() );
|
||||
is.reset();
|
||||
assertEquals( 'e', is.read() );
|
||||
|
||||
LuaString substr = str.substring( 1, 4 );
|
||||
assertEquals( 3, substr.length() );
|
||||
|
||||
is.close();
|
||||
is = substr.toInputStream();
|
||||
|
||||
assertEquals( 'e', is.read() );
|
||||
assertEquals( 'l', is.read() );
|
||||
assertEquals( 'l', is.read() );
|
||||
assertEquals( -1, is.read() );
|
||||
|
||||
is = substr.toInputStream();
|
||||
is.reset();
|
||||
|
||||
assertEquals( 'e', is.read() );
|
||||
}
|
||||
|
||||
|
||||
private static final String userFriendly( String s ) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for ( int i=0, n=s.length(); i<n; i++ ) {
|
||||
int c = s.charAt(i);
|
||||
if ( c < ' ' || c >= 0x80 ) {
|
||||
sb.append( "\\u"+Integer.toHexString(0x10000+c).substring(1) );
|
||||
} else {
|
||||
sb.append( (char) c );
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void testUtf820482051() throws UnsupportedEncodingException {
|
||||
int i = 2048;
|
||||
char[] c = { (char) (i+0), (char) (i+1), (char) (i+2), (char) (i+3) };
|
||||
String before = new String(c)+" "+i+"-"+(i+4);
|
||||
LuaString ls = LuaString.valueOf(before);
|
||||
String after = ls.tojstring();
|
||||
assertEquals( userFriendly( before ), userFriendly( after ) );
|
||||
}
|
||||
|
||||
public void testUtf8() {
|
||||
for ( int i=4; i<0xffff; i+=4 ) {
|
||||
char[] c = { (char) (i+0), (char) (i+1), (char) (i+2), (char) (i+3) };
|
||||
String before = new String(c)+" "+i+"-"+(i+4);
|
||||
LuaString ls = LuaString.valueOf(before);
|
||||
String after = ls.tojstring();
|
||||
assertEquals( userFriendly( before ), userFriendly( after ) );
|
||||
}
|
||||
char[] c = { (char) (1), (char) (2), (char) (3) };
|
||||
String before = new String(c)+" 1-3";
|
||||
LuaString ls = LuaString.valueOf(before);
|
||||
String after = ls.tojstring();
|
||||
assertEquals( userFriendly( before ), userFriendly( after ) );
|
||||
}
|
||||
|
||||
public void testSpotCheckUtf8() throws UnsupportedEncodingException {
|
||||
byte[] bytes = {(byte)194,(byte)160,(byte)194,(byte)161,(byte)194,(byte)162,(byte)194,(byte)163,(byte)194,(byte)164};
|
||||
String expected = new String(bytes, "UTF8");
|
||||
String actual = LuaString.valueOf(bytes).tojstring();
|
||||
char[] d = actual.toCharArray();
|
||||
assertEquals(160, d[0]);
|
||||
assertEquals(161, d[1]);
|
||||
assertEquals(162, d[2]);
|
||||
assertEquals(163, d[3]);
|
||||
assertEquals(164, d[4]);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
public void testNullTerminated() {
|
||||
char[] c = { 'a', 'b', 'c', '\0', 'd', 'e', 'f' };
|
||||
String before = new String(c);
|
||||
LuaString ls = LuaString.valueOf(before);
|
||||
String after = ls.tojstring();
|
||||
assertEquals( userFriendly( "abc\0def" ), userFriendly( after ) );
|
||||
}
|
||||
|
||||
public void testRecentStringsCacheDifferentHashcodes() {
|
||||
final byte[] abc = {'a', 'b', 'c' };
|
||||
final byte[] xyz = {'x', 'y', 'z' };
|
||||
final LuaString abc1 = LuaString.valueOf(abc);
|
||||
final LuaString xyz1 = LuaString.valueOf(xyz);
|
||||
final LuaString abc2 = LuaString.valueOf(abc);
|
||||
final LuaString xyz2 = LuaString.valueOf(xyz);
|
||||
final int mod = LuaString.RECENT_STRINGS_CACHE_SIZE;
|
||||
assertTrue(abc1.hashCode() % mod != xyz1.hashCode() % mod);
|
||||
assertSame(abc1, abc2);
|
||||
assertSame(xyz1, xyz2);
|
||||
}
|
||||
|
||||
public void testRecentStringsCacheHashCollisionCacheHit() {
|
||||
final byte[] abc = {'a', 'b', 'c' };
|
||||
final byte[] lyz = {'l', 'y', 'z' }; // chosen to have hash collision with 'abc'
|
||||
final LuaString abc1 = LuaString.valueOf(abc);
|
||||
final LuaString abc2 = LuaString.valueOf(abc); // in cache: 'abc'
|
||||
final LuaString lyz1 = LuaString.valueOf(lyz);
|
||||
final LuaString lyz2 = LuaString.valueOf(lyz); // in cache: 'lyz'
|
||||
final int mod = LuaString.RECENT_STRINGS_CACHE_SIZE;
|
||||
assertEquals(abc1.hashCode() % mod, lyz1.hashCode() % mod);
|
||||
assertNotSame(abc1, lyz1);
|
||||
assertFalse(abc1.equals(lyz1));
|
||||
assertSame(abc1, abc2);
|
||||
assertSame(lyz1, lyz2);
|
||||
}
|
||||
|
||||
public void testRecentStringsCacheHashCollisionCacheMiss() {
|
||||
final byte[] abc = {'a', 'b', 'c' };
|
||||
final byte[] lyz = {'l', 'y', 'z' }; // chosen to have hash collision with 'abc'
|
||||
final LuaString abc1 = LuaString.valueOf(abc);
|
||||
final LuaString lyz1 = LuaString.valueOf(lyz); // in cache: 'abc'
|
||||
final LuaString abc2 = LuaString.valueOf(abc); // in cache: 'lyz'
|
||||
final LuaString lyz2 = LuaString.valueOf(lyz); // in cache: 'abc'
|
||||
final int mod = LuaString.RECENT_STRINGS_CACHE_SIZE;
|
||||
assertEquals(abc1.hashCode() % mod, lyz1.hashCode() % mod);
|
||||
assertNotSame(abc1, lyz1);
|
||||
assertFalse(abc1.equals(lyz1));
|
||||
assertNotSame(abc1, abc2);
|
||||
assertNotSame(lyz1, lyz2);
|
||||
}
|
||||
|
||||
public void testRecentStringsLongStrings() {
|
||||
byte[] abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes();
|
||||
assertTrue(abc.length > LuaString.RECENT_STRINGS_MAX_LENGTH);
|
||||
LuaString abc1 = LuaString.valueOf(abc);
|
||||
LuaString abc2 = LuaString.valueOf(abc);
|
||||
assertNotSame(abc1, abc2);
|
||||
}
|
||||
|
||||
public void testRecentStringsUsingJavaStrings() {
|
||||
final String abc = "abc";
|
||||
final String lyz = "lyz"; // chosen to have hash collision with 'abc'
|
||||
final String xyz = "xyz";
|
||||
|
||||
final LuaString abc1 = LuaString.valueOf(abc);
|
||||
final LuaString abc2 = LuaString.valueOf(abc);
|
||||
final LuaString lyz1 = LuaString.valueOf(lyz);
|
||||
final LuaString lyz2 = LuaString.valueOf(lyz);
|
||||
final LuaString xyz1 = LuaString.valueOf(xyz);
|
||||
final LuaString xyz2 = LuaString.valueOf(xyz);
|
||||
final int mod = LuaString.RECENT_STRINGS_CACHE_SIZE;
|
||||
assertEquals(abc1.hashCode() % mod, lyz1.hashCode() % mod);
|
||||
assertFalse(abc1.hashCode() % mod == xyz1.hashCode() % mod);
|
||||
assertSame(abc1, abc2);
|
||||
assertSame(lyz1, lyz2);
|
||||
assertSame(xyz1, xyz2);
|
||||
|
||||
final LuaString abc3 = LuaString.valueOf(abc);
|
||||
final LuaString lyz3 = LuaString.valueOf(lyz);
|
||||
final LuaString xyz3 = LuaString.valueOf(xyz);
|
||||
|
||||
final LuaString abc4 = LuaString.valueOf(abc);
|
||||
final LuaString lyz4 = LuaString.valueOf(lyz);
|
||||
final LuaString xyz4 = LuaString.valueOf(xyz);
|
||||
assertNotSame(abc3, abc4); // because of hash collision
|
||||
assertNotSame(lyz3, lyz4); // because of hash collision
|
||||
assertSame(xyz3, xyz4); // because hashes do not collide
|
||||
}
|
||||
|
||||
public void testLongSubstringGetsOldBacking() {
|
||||
LuaString src = LuaString.valueOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
LuaString sub1 = src.substring(10, 40);
|
||||
assertSame(src.m_bytes, sub1.m_bytes);
|
||||
assertEquals(sub1.m_offset, 10);
|
||||
assertEquals(sub1.m_length, 30);
|
||||
}
|
||||
|
||||
public void testShortSubstringGetsNewBacking() {
|
||||
LuaString src = LuaString.valueOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
LuaString sub1 = src.substring(10, 20);
|
||||
LuaString sub2 = src.substring(10, 20);
|
||||
assertEquals(sub1.m_offset, 0);
|
||||
assertEquals(sub1.m_length, 10);
|
||||
assertSame(sub1, sub2);
|
||||
assertFalse(src.m_bytes == sub1.m_bytes);
|
||||
}
|
||||
|
||||
public void testShortSubstringOfVeryLongStringGetsNewBacking() {
|
||||
LuaString src = LuaString.valueOf(
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" );
|
||||
LuaString sub1 = src.substring(10, 50);
|
||||
LuaString sub2 = src.substring(10, 50);
|
||||
assertEquals(sub1.m_offset, 0);
|
||||
assertEquals(sub1.m_length, 40);
|
||||
assertFalse(sub1 == sub2);
|
||||
assertFalse(src.m_bytes == sub1.m_bytes);
|
||||
}
|
||||
|
||||
public void testIndexOfByteInSubstring() {
|
||||
LuaString str = LuaString.valueOf("abcdef:ghi");
|
||||
LuaString sub = str.substring(2, 10);
|
||||
assertEquals(10, str.m_length);
|
||||
assertEquals(8, sub.m_length);
|
||||
assertEquals(0, str.m_offset);
|
||||
assertEquals(2, sub.m_offset);
|
||||
|
||||
assertEquals(6, str.indexOf((byte) ':', 0));
|
||||
assertEquals(6, str.indexOf((byte) ':', 2));
|
||||
assertEquals(6, str.indexOf((byte) ':', 6));
|
||||
assertEquals(-1, str.indexOf((byte) ':', 7));
|
||||
assertEquals(-1, str.indexOf((byte) ':', 9));
|
||||
assertEquals(9, str.indexOf((byte) 'i', 0));
|
||||
assertEquals(9, str.indexOf((byte) 'i', 2));
|
||||
assertEquals(9, str.indexOf((byte) 'i', 9));
|
||||
assertEquals(-1, str.indexOf((byte) 'z', 0));
|
||||
assertEquals(-1, str.indexOf((byte) 'z', 2));
|
||||
assertEquals(-1, str.indexOf((byte) 'z', 9));
|
||||
|
||||
assertEquals(4, sub.indexOf((byte) ':', 0));
|
||||
assertEquals(4, sub.indexOf((byte) ':', 2));
|
||||
assertEquals(4, sub.indexOf((byte) ':', 4));
|
||||
assertEquals(-1, sub.indexOf((byte) ':', 5));
|
||||
assertEquals(-1, sub.indexOf((byte) ':', 7));
|
||||
assertEquals(7, sub.indexOf((byte) 'i', 0));
|
||||
assertEquals(7, sub.indexOf((byte) 'i', 2));
|
||||
assertEquals(7, sub.indexOf((byte) 'i', 7));
|
||||
assertEquals(-1, sub.indexOf((byte) 'z', 0));
|
||||
assertEquals(-1, sub.indexOf((byte) 'z', 2));
|
||||
assertEquals(-1, sub.indexOf((byte) 'z', 7));
|
||||
}
|
||||
|
||||
public void testIndexOfPatternInSubstring() {
|
||||
LuaString str = LuaString.valueOf("abcdef:ghi");
|
||||
LuaString sub = str.substring(2, 10);
|
||||
assertEquals(10, str.m_length);
|
||||
assertEquals(8, sub.m_length);
|
||||
assertEquals(0, str.m_offset);
|
||||
assertEquals(2, sub.m_offset);
|
||||
|
||||
LuaString pat = LuaString.valueOf(":");
|
||||
LuaString i = LuaString.valueOf("i");
|
||||
LuaString xyz = LuaString.valueOf("xyz");
|
||||
|
||||
assertEquals(6, str.indexOf(pat, 0));
|
||||
assertEquals(6, str.indexOf(pat, 2));
|
||||
assertEquals(6, str.indexOf(pat, 6));
|
||||
assertEquals(-1, str.indexOf(pat, 7));
|
||||
assertEquals(-1, str.indexOf(pat, 9));
|
||||
assertEquals(9, str.indexOf(i, 0));
|
||||
assertEquals(9, str.indexOf(i, 2));
|
||||
assertEquals(9, str.indexOf(i, 9));
|
||||
assertEquals(-1, str.indexOf(xyz, 0));
|
||||
assertEquals(-1, str.indexOf(xyz, 2));
|
||||
assertEquals(-1, str.indexOf(xyz, 9));
|
||||
|
||||
assertEquals(4, sub.indexOf(pat, 0));
|
||||
assertEquals(4, sub.indexOf(pat, 2));
|
||||
assertEquals(4, sub.indexOf(pat, 4));
|
||||
assertEquals(-1, sub.indexOf(pat, 5));
|
||||
assertEquals(-1, sub.indexOf(pat, 7));
|
||||
assertEquals(7, sub.indexOf(i, 0));
|
||||
assertEquals(7, sub.indexOf(i, 2));
|
||||
assertEquals(7, sub.indexOf(i, 7));
|
||||
assertEquals(-1, sub.indexOf(xyz, 0));
|
||||
assertEquals(-1, sub.indexOf(xyz, 2));
|
||||
assertEquals(-1, sub.indexOf(xyz, 7));
|
||||
}
|
||||
|
||||
public void testLastIndexOfPatternInSubstring() {
|
||||
LuaString str = LuaString.valueOf("abcdef:ghi");
|
||||
LuaString sub = str.substring(2, 10);
|
||||
assertEquals(10, str.m_length);
|
||||
assertEquals(8, sub.m_length);
|
||||
assertEquals(0, str.m_offset);
|
||||
assertEquals(2, sub.m_offset);
|
||||
|
||||
LuaString pat = LuaString.valueOf(":");
|
||||
LuaString i = LuaString.valueOf("i");
|
||||
LuaString xyz = LuaString.valueOf("xyz");
|
||||
|
||||
assertEquals(6, str.lastIndexOf(pat));
|
||||
assertEquals(9, str.lastIndexOf(i));
|
||||
assertEquals(-1, str.lastIndexOf(xyz));
|
||||
|
||||
assertEquals(4, sub.lastIndexOf(pat));
|
||||
assertEquals(7, sub.lastIndexOf(i));
|
||||
assertEquals(-1, sub.lastIndexOf(xyz));
|
||||
}
|
||||
|
||||
public void testIndexOfAnyInSubstring() {
|
||||
LuaString str = LuaString.valueOf("abcdef:ghi");
|
||||
LuaString sub = str.substring(2, 10);
|
||||
assertEquals(10, str.m_length);
|
||||
assertEquals(8, sub.m_length);
|
||||
assertEquals(0, str.m_offset);
|
||||
assertEquals(2, sub.m_offset);
|
||||
|
||||
LuaString ghi = LuaString.valueOf("ghi");
|
||||
LuaString ihg = LuaString.valueOf("ihg");
|
||||
LuaString ijk = LuaString.valueOf("ijk");
|
||||
LuaString kji= LuaString.valueOf("kji");
|
||||
LuaString xyz = LuaString.valueOf("xyz");
|
||||
LuaString ABCdEFGHIJKL = LuaString.valueOf("ABCdEFGHIJKL");
|
||||
LuaString EFGHIJKL = ABCdEFGHIJKL.substring(4, 12);
|
||||
LuaString CdEFGHIJ = ABCdEFGHIJKL.substring(2, 10);
|
||||
assertEquals(4, EFGHIJKL.m_offset);
|
||||
assertEquals(2, CdEFGHIJ.m_offset);
|
||||
|
||||
assertEquals(7, str.indexOfAny(ghi));
|
||||
assertEquals(7, str.indexOfAny(ihg));
|
||||
assertEquals(9, str.indexOfAny(ijk));
|
||||
assertEquals(9, str.indexOfAny(kji));
|
||||
assertEquals(-1, str.indexOfAny(xyz));
|
||||
assertEquals(3, str.indexOfAny(CdEFGHIJ));
|
||||
assertEquals(-1, str.indexOfAny(EFGHIJKL));
|
||||
|
||||
assertEquals(5, sub.indexOfAny(ghi));
|
||||
assertEquals(5, sub.indexOfAny(ihg));
|
||||
assertEquals(7, sub.indexOfAny(ijk));
|
||||
assertEquals(7, sub.indexOfAny(kji));
|
||||
assertEquals(-1, sub.indexOfAny(xyz));
|
||||
assertEquals(1, sub.indexOfAny(CdEFGHIJ));
|
||||
assertEquals(-1, sub.indexOfAny(EFGHIJKL));
|
||||
}
|
||||
|
||||
public void testMatchShortPatterns() {
|
||||
LuaValue[] args = { LuaString.valueOf("%bxy") };
|
||||
LuaString _ = LuaString.valueOf("");
|
||||
|
||||
LuaString a = LuaString.valueOf("a");
|
||||
LuaString ax = LuaString.valueOf("ax");
|
||||
LuaString axb = LuaString.valueOf("axb");
|
||||
LuaString axby = LuaString.valueOf("axby");
|
||||
LuaString xbya = LuaString.valueOf("xbya");
|
||||
LuaString bya = LuaString.valueOf("bya");
|
||||
LuaString xby = LuaString.valueOf("xby");
|
||||
LuaString axbya = LuaString.valueOf("axbya");
|
||||
LuaValue nil = LuaValue.NIL;
|
||||
|
||||
assertEquals(nil, _.invokemethod("match", args));
|
||||
assertEquals(nil, a.invokemethod("match", args));
|
||||
assertEquals(nil, ax.invokemethod("match", args));
|
||||
assertEquals(nil, axb.invokemethod("match", args));
|
||||
assertEquals(xby, axby.invokemethod("match", args));
|
||||
assertEquals(xby, xbya.invokemethod("match", args));
|
||||
assertEquals(nil, bya.invokemethod("match", args));
|
||||
assertEquals(xby, xby.invokemethod("match", args));
|
||||
assertEquals(xby, axbya.invokemethod("match", args));
|
||||
assertEquals(xby, axbya.substring(0,4).invokemethod("match", args));
|
||||
assertEquals(nil, axbya.substring(0,3).invokemethod("match", args));
|
||||
assertEquals(xby, axbya.substring(1,5).invokemethod("match", args));
|
||||
assertEquals(nil, axbya.substring(2,5).invokemethod("match", args));
|
||||
}
|
||||
}
|
||||
320
luaj-test/src/test/java/org/luaj/vm2/TableHashTest.java
Normal file
320
luaj-test/src/test/java/org/luaj/vm2/TableHashTest.java
Normal file
@@ -0,0 +1,320 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.LuaString;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.TwoArgFunction;
|
||||
|
||||
/**
|
||||
* Tests for tables used as lists.
|
||||
*/
|
||||
public class TableHashTest extends TestCase {
|
||||
|
||||
protected LuaTable new_Table() {
|
||||
return new LuaTable();
|
||||
}
|
||||
|
||||
protected LuaTable new_Table(int n,int m) {
|
||||
return new LuaTable(n,m);
|
||||
}
|
||||
|
||||
public void testSetRemove() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
assertEquals( 0, t.getHashLength() );
|
||||
assertEquals( 0, t.length() );
|
||||
assertEquals( 0, t.keyCount() );
|
||||
|
||||
String[] keys = { "abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "wxy", "z01",
|
||||
"cd", "ef", "g", "hi", "jk", "lm", "no", "pq", "rs", };
|
||||
int[] capacities = { 0, 2, 2, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 32, 32, 32 };
|
||||
for ( int i = 0; i < keys.length; ++i ) {
|
||||
assertEquals( capacities[i], t.getHashLength() );
|
||||
String si = "Test Value! "+i;
|
||||
t.set( keys[i], si );
|
||||
assertEquals( 0, t.length() );
|
||||
assertEquals( i+1, t.keyCount() );
|
||||
}
|
||||
assertEquals( capacities[keys.length], t.getHashLength() );
|
||||
for ( int i = 0; i < keys.length; ++i ) {
|
||||
LuaValue vi = LuaString.valueOf( "Test Value! "+i );
|
||||
assertEquals( vi, t.get( keys[i] ) );
|
||||
assertEquals( vi, t.get( LuaString.valueOf(keys[i]) ) );
|
||||
assertEquals( vi, t.rawget( keys[i] ) );
|
||||
assertEquals( vi, t.rawget( keys[i] ) );
|
||||
}
|
||||
|
||||
// replace with new values
|
||||
for ( int i = 0; i < keys.length; ++i ) {
|
||||
t.set( keys[i], LuaString.valueOf( "Replacement Value! "+i ) );
|
||||
assertEquals( 0, t.length() );
|
||||
assertEquals( keys.length, t.keyCount() );
|
||||
assertEquals( capacities[keys.length], t.getHashLength() );
|
||||
}
|
||||
for ( int i = 0; i < keys.length; ++i ) {
|
||||
LuaValue vi = LuaString.valueOf( "Replacement Value! "+i );
|
||||
assertEquals( vi, t.get( keys[i] ) );
|
||||
}
|
||||
|
||||
// remove
|
||||
for ( int i = 0; i < keys.length; ++i ) {
|
||||
t.set( keys[i], LuaValue.NIL );
|
||||
assertEquals( 0, t.length() );
|
||||
assertEquals( keys.length-i-1, t.keyCount() );
|
||||
if ( i<keys.length-1 )
|
||||
assertEquals( capacities[keys.length], t.getHashLength() );
|
||||
else
|
||||
assertTrue( 0<=t.getHashLength() );
|
||||
}
|
||||
for ( int i = 0; i < keys.length; ++i ) {
|
||||
assertEquals( LuaValue.NIL, t.get( keys[i] ) );
|
||||
}
|
||||
}
|
||||
|
||||
public void testIndexMetatag() {
|
||||
LuaTable t = new_Table();
|
||||
LuaTable mt = new_Table();
|
||||
LuaTable fb = new_Table();
|
||||
|
||||
// set basic values
|
||||
t.set( "ppp", "abc" );
|
||||
t.set( 123, "def" );
|
||||
mt.set(LuaValue.INDEX, fb);
|
||||
fb.set( "qqq", "ghi" );
|
||||
fb.set( 456, "jkl" );
|
||||
|
||||
// check before setting metatable
|
||||
assertEquals( "abc", t.get("ppp").tojstring() );
|
||||
assertEquals( "def", t.get(123).tojstring() );
|
||||
assertEquals( "nil", t.get("qqq").tojstring() );
|
||||
assertEquals( "nil", t.get(456).tojstring() );
|
||||
assertEquals( "nil", fb.get("ppp").tojstring() );
|
||||
assertEquals( "nil", fb.get(123).tojstring() );
|
||||
assertEquals( "ghi", fb.get("qqq").tojstring() );
|
||||
assertEquals( "jkl", fb.get(456).tojstring() );
|
||||
assertEquals( "nil", mt.get("ppp").tojstring() );
|
||||
assertEquals( "nil", mt.get(123).tojstring() );
|
||||
assertEquals( "nil", mt.get("qqq").tojstring() );
|
||||
assertEquals( "nil", mt.get(456).tojstring() );
|
||||
|
||||
// check before setting metatable
|
||||
t.setmetatable(mt);
|
||||
assertEquals( mt, t.getmetatable() );
|
||||
assertEquals( "abc", t.get("ppp").tojstring() );
|
||||
assertEquals( "def", t.get(123).tojstring() );
|
||||
assertEquals( "ghi", t.get("qqq").tojstring() );
|
||||
assertEquals( "jkl", t.get(456).tojstring() );
|
||||
assertEquals( "nil", fb.get("ppp").tojstring() );
|
||||
assertEquals( "nil", fb.get(123).tojstring() );
|
||||
assertEquals( "ghi", fb.get("qqq").tojstring() );
|
||||
assertEquals( "jkl", fb.get(456).tojstring() );
|
||||
assertEquals( "nil", mt.get("ppp").tojstring() );
|
||||
assertEquals( "nil", mt.get(123).tojstring() );
|
||||
assertEquals( "nil", mt.get("qqq").tojstring() );
|
||||
assertEquals( "nil", mt.get(456).tojstring() );
|
||||
|
||||
// set metatable to metatable without values
|
||||
t.setmetatable(fb);
|
||||
assertEquals( "abc", t.get("ppp").tojstring() );
|
||||
assertEquals( "def", t.get(123).tojstring() );
|
||||
assertEquals( "nil", t.get("qqq").tojstring() );
|
||||
assertEquals( "nil", t.get(456).tojstring() );
|
||||
|
||||
// set metatable to null
|
||||
t.setmetatable(null);
|
||||
assertEquals( "abc", t.get("ppp").tojstring() );
|
||||
assertEquals( "def", t.get(123).tojstring() );
|
||||
assertEquals( "nil", t.get("qqq").tojstring() );
|
||||
assertEquals( "nil", t.get(456).tojstring() );
|
||||
}
|
||||
|
||||
public void testIndexFunction() {
|
||||
final LuaTable t = new_Table();
|
||||
final LuaTable mt = new_Table();
|
||||
|
||||
final TwoArgFunction fb = new TwoArgFunction() {
|
||||
public LuaValue call(LuaValue tbl, LuaValue key) {
|
||||
assertEquals(tbl, t);
|
||||
return valueOf("from mt: "+key);
|
||||
}
|
||||
};
|
||||
|
||||
// set basic values
|
||||
t.set( "ppp", "abc" );
|
||||
t.set( 123, "def" );
|
||||
mt.set(LuaValue.INDEX, fb);
|
||||
|
||||
// check before setting metatable
|
||||
assertEquals( "abc", t.get("ppp").tojstring() );
|
||||
assertEquals( "def", t.get(123).tojstring() );
|
||||
assertEquals( "nil", t.get("qqq").tojstring() );
|
||||
assertEquals( "nil", t.get(456).tojstring() );
|
||||
|
||||
|
||||
// check before setting metatable
|
||||
t.setmetatable(mt);
|
||||
assertEquals( mt, t.getmetatable() );
|
||||
assertEquals( "abc", t.get("ppp").tojstring() );
|
||||
assertEquals( "def", t.get(123).tojstring() );
|
||||
assertEquals( "from mt: qqq", t.get("qqq").tojstring() );
|
||||
assertEquals( "from mt: 456", t.get(456).tojstring() );
|
||||
|
||||
// use raw set
|
||||
t.rawset("qqq", "alt-qqq");
|
||||
t.rawset(456, "alt-456");
|
||||
assertEquals( "abc", t.get("ppp").tojstring() );
|
||||
assertEquals( "def", t.get(123).tojstring() );
|
||||
assertEquals( "alt-qqq", t.get("qqq").tojstring() );
|
||||
assertEquals( "alt-456", t.get(456).tojstring() );
|
||||
|
||||
// remove using raw set
|
||||
t.rawset("qqq", LuaValue.NIL);
|
||||
t.rawset(456, LuaValue.NIL);
|
||||
assertEquals( "abc", t.get("ppp").tojstring() );
|
||||
assertEquals( "def", t.get(123).tojstring() );
|
||||
assertEquals( "from mt: qqq", t.get("qqq").tojstring() );
|
||||
assertEquals( "from mt: 456", t.get(456).tojstring() );
|
||||
|
||||
// set metatable to null
|
||||
t.setmetatable(null);
|
||||
assertEquals( "abc", t.get("ppp").tojstring() );
|
||||
assertEquals( "def", t.get(123).tojstring() );
|
||||
assertEquals( "nil", t.get("qqq").tojstring() );
|
||||
assertEquals( "nil", t.get(456).tojstring() );
|
||||
}
|
||||
|
||||
public void testNext() {
|
||||
final LuaTable t = new_Table();
|
||||
assertEquals( LuaValue.NIL, t.next(LuaValue.NIL) );
|
||||
|
||||
// insert array elements
|
||||
t.set( 1, "one" );
|
||||
assertEquals( LuaValue.valueOf(1), t.next(LuaValue.NIL).arg(1) );
|
||||
assertEquals( LuaValue.valueOf("one"), t.next(LuaValue.NIL).arg(2) );
|
||||
assertEquals( LuaValue.NIL, t.next(LuaValue.ONE) );
|
||||
t.set( 2, "two" );
|
||||
assertEquals( LuaValue.valueOf(1), t.next(LuaValue.NIL).arg(1) );
|
||||
assertEquals( LuaValue.valueOf("one"), t.next(LuaValue.NIL).arg(2) );
|
||||
assertEquals( LuaValue.valueOf(2), t.next(LuaValue.ONE).arg(1) );
|
||||
assertEquals( LuaValue.valueOf("two"), t.next(LuaValue.ONE).arg(2) );
|
||||
assertEquals( LuaValue.NIL, t.next(LuaValue.valueOf(2)) );
|
||||
|
||||
// insert hash elements
|
||||
t.set( "aa", "aaa" );
|
||||
assertEquals( LuaValue.valueOf(1), t.next(LuaValue.NIL).arg(1) );
|
||||
assertEquals( LuaValue.valueOf("one"), t.next(LuaValue.NIL).arg(2) );
|
||||
assertEquals( LuaValue.valueOf(2), t.next(LuaValue.ONE).arg(1) );
|
||||
assertEquals( LuaValue.valueOf("two"), t.next(LuaValue.ONE).arg(2) );
|
||||
assertEquals( LuaValue.valueOf("aa"), t.next(LuaValue.valueOf(2)).arg(1) );
|
||||
assertEquals( LuaValue.valueOf("aaa"), t.next(LuaValue.valueOf(2)).arg(2) );
|
||||
assertEquals( LuaValue.NIL, t.next(LuaValue.valueOf("aa")) );
|
||||
t.set( "bb", "bbb" );
|
||||
assertEquals( LuaValue.valueOf(1), t.next(LuaValue.NIL).arg(1) );
|
||||
assertEquals( LuaValue.valueOf("one"), t.next(LuaValue.NIL).arg(2) );
|
||||
assertEquals( LuaValue.valueOf(2), t.next(LuaValue.ONE).arg(1) );
|
||||
assertEquals( LuaValue.valueOf("two"), t.next(LuaValue.ONE).arg(2) );
|
||||
assertEquals( LuaValue.valueOf("aa"), t.next(LuaValue.valueOf(2)).arg(1) );
|
||||
assertEquals( LuaValue.valueOf("aaa"), t.next(LuaValue.valueOf(2)).arg(2) );
|
||||
assertEquals( LuaValue.valueOf("bb"), t.next(LuaValue.valueOf("aa")).arg(1) );
|
||||
assertEquals( LuaValue.valueOf("bbb"), t.next(LuaValue.valueOf("aa")).arg(2) );
|
||||
assertEquals( LuaValue.NIL, t.next(LuaValue.valueOf("bb")) );
|
||||
}
|
||||
|
||||
public void testLoopWithRemoval() {
|
||||
final LuaTable t = new_Table();
|
||||
|
||||
t.set( LuaValue.valueOf(1), LuaValue.valueOf("1") );
|
||||
t.set( LuaValue.valueOf(3), LuaValue.valueOf("3") );
|
||||
t.set( LuaValue.valueOf(8), LuaValue.valueOf("4") );
|
||||
t.set( LuaValue.valueOf(17), LuaValue.valueOf("5") );
|
||||
t.set( LuaValue.valueOf(26), LuaValue.valueOf("6") );
|
||||
t.set( LuaValue.valueOf(35), LuaValue.valueOf("7") );
|
||||
t.set( LuaValue.valueOf(42), LuaValue.valueOf("8") );
|
||||
t.set( LuaValue.valueOf(60), LuaValue.valueOf("10") );
|
||||
t.set( LuaValue.valueOf(63), LuaValue.valueOf("11") );
|
||||
|
||||
Varargs entry = t.next(LuaValue.NIL);
|
||||
while ( !entry.isnil(1) ) {
|
||||
LuaValue k = entry.arg1();
|
||||
LuaValue v = entry.arg(2);
|
||||
if ( ( k.toint() & 1 ) == 0 ) {
|
||||
t.set( k, LuaValue.NIL );
|
||||
}
|
||||
entry = t.next(k);
|
||||
}
|
||||
|
||||
int numEntries = 0;
|
||||
entry = t.next(LuaValue.NIL);
|
||||
while ( !entry.isnil(1) ) {
|
||||
LuaValue k = entry.arg1();
|
||||
// Only odd keys should remain
|
||||
assertTrue( ( k.toint() & 1 ) == 1 );
|
||||
numEntries++;
|
||||
entry = t.next(k);
|
||||
}
|
||||
assertEquals( 5, numEntries );
|
||||
}
|
||||
|
||||
public void testLoopWithRemovalAndSet() {
|
||||
final LuaTable t = new_Table();
|
||||
|
||||
t.set( LuaValue.valueOf(1), LuaValue.valueOf("1") );
|
||||
t.set( LuaValue.valueOf(3), LuaValue.valueOf("3") );
|
||||
t.set( LuaValue.valueOf(8), LuaValue.valueOf("4") );
|
||||
t.set( LuaValue.valueOf(17), LuaValue.valueOf("5") );
|
||||
t.set( LuaValue.valueOf(26), LuaValue.valueOf("6") );
|
||||
t.set( LuaValue.valueOf(35), LuaValue.valueOf("7") );
|
||||
t.set( LuaValue.valueOf(42), LuaValue.valueOf("8") );
|
||||
t.set( LuaValue.valueOf(60), LuaValue.valueOf("10") );
|
||||
t.set( LuaValue.valueOf(63), LuaValue.valueOf("11") );
|
||||
|
||||
Varargs entry = t.next(LuaValue.NIL);
|
||||
Varargs entry2 = entry;
|
||||
while ( !entry.isnil(1) ) {
|
||||
LuaValue k = entry.arg1();
|
||||
LuaValue v = entry.arg(2);
|
||||
if ( ( k.toint() & 1 ) == 0 ) {
|
||||
t.set( k, LuaValue.NIL );
|
||||
} else {
|
||||
t.set( k, v.tonumber() );
|
||||
entry2 = t.next(entry2.arg1());
|
||||
}
|
||||
entry = t.next(k);
|
||||
}
|
||||
|
||||
int numEntries = 0;
|
||||
entry = t.next(LuaValue.NIL);
|
||||
while ( !entry.isnil(1) ) {
|
||||
LuaValue k = entry.arg1();
|
||||
// Only odd keys should remain
|
||||
assertTrue( ( k.toint() & 1 ) == 1 );
|
||||
assertTrue( entry.arg(2).type() == LuaValue.TNUMBER );
|
||||
numEntries++;
|
||||
entry = t.next(k);
|
||||
}
|
||||
assertEquals( 5, numEntries );
|
||||
}
|
||||
}
|
||||
419
luaj-test/src/test/java/org/luaj/vm2/TableTest.java
Normal file
419
luaj-test/src/test/java/org/luaj/vm2/TableTest.java
Normal file
@@ -0,0 +1,419 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Vector;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class TableTest extends TestCase {
|
||||
|
||||
protected LuaTable new_Table() {
|
||||
return new LuaTable();
|
||||
}
|
||||
|
||||
protected LuaTable new_Table(int n,int m) {
|
||||
return new LuaTable(n,m);
|
||||
}
|
||||
|
||||
private int keyCount(LuaTable t) {
|
||||
return keys(t).length;
|
||||
}
|
||||
|
||||
private LuaValue[] keys(LuaTable t) {
|
||||
ArrayList<LuaValue> l = new ArrayList<LuaValue>();
|
||||
LuaValue k = LuaValue.NIL;
|
||||
while ( true ) {
|
||||
Varargs n = t.next(k);
|
||||
if ( (k = n.arg1()).isnil() )
|
||||
break;
|
||||
l.add( k );
|
||||
}
|
||||
return l.toArray(new LuaValue[t.length()]);
|
||||
}
|
||||
|
||||
|
||||
public void testInOrderIntegerKeyInsertion() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
t.set( i, LuaValue.valueOf( "Test Value! "+i ) );
|
||||
}
|
||||
|
||||
// Ensure all keys are still there.
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
assertEquals( "Test Value! " + i, t.get( i ).tojstring() );
|
||||
}
|
||||
|
||||
// Ensure capacities make sense
|
||||
assertEquals( 0, t.getHashLength() );
|
||||
|
||||
assertTrue( t.getArrayLength() >= 32 );
|
||||
assertTrue( t.getArrayLength() <= 64 );
|
||||
|
||||
}
|
||||
|
||||
public void testRekeyCount() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
// NOTE: This order of insertion is important.
|
||||
t.set(3, LuaInteger.valueOf(3));
|
||||
t.set(1, LuaInteger.valueOf(1));
|
||||
t.set(5, LuaInteger.valueOf(5));
|
||||
t.set(4, LuaInteger.valueOf(4));
|
||||
t.set(6, LuaInteger.valueOf(6));
|
||||
t.set(2, LuaInteger.valueOf(2));
|
||||
|
||||
for ( int i = 1; i < 6; ++i ) {
|
||||
assertEquals(LuaInteger.valueOf(i), t.get(i));
|
||||
}
|
||||
|
||||
assertTrue( t.getArrayLength() >= 3 );
|
||||
assertTrue( t.getArrayLength() <= 12 );
|
||||
assertTrue( t.getHashLength() <= 3 );
|
||||
}
|
||||
|
||||
public void testOutOfOrderIntegerKeyInsertion() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 32; i > 0; --i ) {
|
||||
t.set( i, LuaValue.valueOf( "Test Value! "+i ) );
|
||||
}
|
||||
|
||||
// Ensure all keys are still there.
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
assertEquals( "Test Value! "+i, t.get( i ).tojstring() );
|
||||
}
|
||||
|
||||
// Ensure capacities make sense
|
||||
assertEquals( 32, t.getArrayLength() );
|
||||
assertEquals( 0, t.getHashLength() );
|
||||
}
|
||||
|
||||
public void testStringAndIntegerKeys() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 0; i < 10; ++i ) {
|
||||
LuaString str = LuaValue.valueOf( String.valueOf( i ) );
|
||||
t.set( i, str );
|
||||
t.set( str, LuaInteger.valueOf( i ) );
|
||||
}
|
||||
|
||||
assertTrue( t.getArrayLength() >= 8 ); // 1, 2, ..., 9
|
||||
assertTrue( t.getArrayLength() <= 16 );
|
||||
assertTrue( t.getHashLength() >= 11 ); // 0, "0", "1", ..., "9"
|
||||
assertTrue( t.getHashLength() <= 33 );
|
||||
|
||||
LuaValue[] keys = keys(t);
|
||||
|
||||
int intKeys = 0;
|
||||
int stringKeys = 0;
|
||||
|
||||
assertEquals( 20, keys.length );
|
||||
for ( int i = 0; i < keys.length; ++i ) {
|
||||
LuaValue k = keys[i];
|
||||
|
||||
if ( k instanceof LuaInteger ) {
|
||||
final int ik = k.toint();
|
||||
assertTrue( ik >= 0 && ik < 10 );
|
||||
final int mask = 1 << ik;
|
||||
assertTrue( ( intKeys & mask ) == 0 );
|
||||
intKeys |= mask;
|
||||
} else if ( k instanceof LuaString ) {
|
||||
final int ik = Integer.parseInt( k.strvalue().tojstring() );
|
||||
assertEquals( String.valueOf( ik ), k.strvalue().tojstring() );
|
||||
assertTrue( ik >= 0 && ik < 10 );
|
||||
final int mask = 1 << ik;
|
||||
assertTrue( "Key \""+ik+"\" found more than once", ( stringKeys & mask ) == 0 );
|
||||
stringKeys |= mask;
|
||||
} else {
|
||||
fail( "Unexpected type of key found" );
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals( 0x03FF, intKeys );
|
||||
assertEquals( 0x03FF, stringKeys );
|
||||
}
|
||||
|
||||
public void testBadInitialCapacity() {
|
||||
LuaTable t = new_Table(0, 1);
|
||||
|
||||
t.set( "test", LuaValue.valueOf("foo") );
|
||||
t.set( "explode", LuaValue.valueOf("explode") );
|
||||
assertEquals( 2, keyCount(t) );
|
||||
}
|
||||
|
||||
public void testRemove0() {
|
||||
LuaTable t = new_Table(2, 0);
|
||||
|
||||
t.set( 1, LuaValue.valueOf("foo") );
|
||||
t.set( 2, LuaValue.valueOf("bah") );
|
||||
assertNotSame(LuaValue.NIL, t.get(1));
|
||||
assertNotSame(LuaValue.NIL, t.get(2));
|
||||
assertEquals(LuaValue.NIL, t.get(3));
|
||||
|
||||
t.set( 1, LuaValue.NIL );
|
||||
t.set( 2, LuaValue.NIL );
|
||||
t.set( 3, LuaValue.NIL );
|
||||
assertEquals(LuaValue.NIL, t.get(1));
|
||||
assertEquals(LuaValue.NIL, t.get(2));
|
||||
assertEquals(LuaValue.NIL, t.get(3));
|
||||
}
|
||||
|
||||
public void testRemove1() {
|
||||
LuaTable t = new_Table(0, 1);
|
||||
|
||||
t.set( "test", LuaValue.valueOf("foo") );
|
||||
t.set( "explode", LuaValue.NIL );
|
||||
t.set( 42, LuaValue.NIL );
|
||||
t.set( new_Table(), LuaValue.NIL );
|
||||
t.set( "test", LuaValue.NIL );
|
||||
assertEquals( 0, keyCount(t) );
|
||||
|
||||
t.set( 10, LuaInteger.valueOf( 5 ) );
|
||||
t.set( 10, LuaValue.NIL );
|
||||
assertEquals( 0, keyCount(t) );
|
||||
}
|
||||
|
||||
public void testRemove2() {
|
||||
LuaTable t = new_Table(0, 1);
|
||||
|
||||
t.set( "test", LuaValue.valueOf("foo") );
|
||||
t.set( "string", LuaInteger.valueOf( 10 ) );
|
||||
assertEquals( 2, keyCount(t) );
|
||||
|
||||
t.set( "string", LuaValue.NIL );
|
||||
t.set( "three", LuaValue.valueOf( 3.14 ) );
|
||||
assertEquals( 2, keyCount(t) );
|
||||
|
||||
t.set( "test", LuaValue.NIL );
|
||||
assertEquals( 1, keyCount(t) );
|
||||
|
||||
t.set( 10, LuaInteger.valueOf( 5 ) );
|
||||
assertEquals( 2, keyCount(t) );
|
||||
|
||||
t.set( 10, LuaValue.NIL );
|
||||
assertEquals( 1, keyCount(t) );
|
||||
|
||||
t.set( "three", LuaValue.NIL );
|
||||
assertEquals( 0, keyCount(t) );
|
||||
}
|
||||
|
||||
public void testShrinkNonPowerOfTwoArray() {
|
||||
LuaTable t = new_Table(6, 2);
|
||||
|
||||
t.set(1, "one");
|
||||
t.set(2, "two");
|
||||
t.set(3, "three");
|
||||
t.set(4, "four");
|
||||
t.set(5, "five");
|
||||
t.set(6, "six");
|
||||
|
||||
t.set("aa", "aaa");
|
||||
t.set("bb", "bbb");
|
||||
|
||||
t.set(3, LuaValue.NIL);
|
||||
t.set(4, LuaValue.NIL);
|
||||
t.set(6, LuaValue.NIL);
|
||||
|
||||
t.set("cc", "ccc");
|
||||
t.set("dd", "ddd");
|
||||
|
||||
assertEquals(4, t.getArrayLength());
|
||||
assertTrue(t.getHashLength() < 10);
|
||||
assertEquals(5, t.hashEntries);
|
||||
assertEquals("one", t.get(1).tojstring());
|
||||
assertEquals("two", t.get(2).tojstring());
|
||||
assertEquals(LuaValue.NIL, t.get(3));
|
||||
assertEquals(LuaValue.NIL, t.get(4));
|
||||
assertEquals("five", t.get(5).tojstring());
|
||||
assertEquals(LuaValue.NIL, t.get(6));
|
||||
assertEquals("aaa", t.get("aa").tojstring());
|
||||
assertEquals("bbb", t.get("bb").tojstring());
|
||||
assertEquals("ccc", t.get("cc").tojstring());
|
||||
assertEquals("ddd", t.get("dd").tojstring());
|
||||
}
|
||||
|
||||
public void testInOrderLuaLength() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
t.set( i, LuaValue.valueOf( "Test Value! "+i ) );
|
||||
assertEquals( i, t.length() );
|
||||
}
|
||||
}
|
||||
|
||||
public void testOutOfOrderLuaLength() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int j=8; j<32; j+=8 ) {
|
||||
for ( int i = j; i > 0; --i ) {
|
||||
t.set( i, LuaValue.valueOf( "Test Value! "+i ) );
|
||||
}
|
||||
assertEquals( j, t.length() );
|
||||
}
|
||||
}
|
||||
|
||||
public void testStringKeysLuaLength() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
t.set( "str-"+i, LuaValue.valueOf( "String Key Test Value! "+i ) );
|
||||
assertEquals( 0, t.length() );
|
||||
}
|
||||
}
|
||||
|
||||
public void testMixedKeysLuaLength() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
t.set( "str-"+i, LuaValue.valueOf( "String Key Test Value! "+i ) );
|
||||
t.set( i, LuaValue.valueOf( "Int Key Test Value! "+i ) );
|
||||
assertEquals( i, t.length() );
|
||||
}
|
||||
}
|
||||
|
||||
private static final void compareLists(LuaTable t,Vector v) {
|
||||
int n = v.size();
|
||||
assertEquals(v.size(),t.length());
|
||||
for ( int j=0; j<n; j++ ) {
|
||||
Object vj = v.elementAt(j);
|
||||
Object tj = t.get(j+1).tojstring();
|
||||
vj = ((LuaString)vj).tojstring();
|
||||
assertEquals(vj,tj);
|
||||
}
|
||||
}
|
||||
|
||||
public void testInsertBeginningOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector v = new Vector();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
LuaString test = LuaValue.valueOf("Test Value! "+i);
|
||||
t.insert(1, test);
|
||||
v.insertElementAt(test, 0);
|
||||
compareLists(t,v);
|
||||
}
|
||||
}
|
||||
|
||||
public void testInsertEndOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector v = new Vector();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
LuaString test = LuaValue.valueOf("Test Value! "+i);
|
||||
t.insert(0, test);
|
||||
v.insertElementAt(test, v.size());
|
||||
compareLists(t,v);
|
||||
}
|
||||
}
|
||||
|
||||
public void testInsertMiddleOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector v = new Vector();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
LuaString test = LuaValue.valueOf("Test Value! "+i);
|
||||
int m = i / 2;
|
||||
t.insert(m+1, test);
|
||||
v.insertElementAt(test, m);
|
||||
compareLists(t,v);
|
||||
}
|
||||
}
|
||||
|
||||
private static final void prefillLists(LuaTable t,Vector v) {
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
LuaString test = LuaValue.valueOf("Test Value! "+i);
|
||||
t.insert(0, test);
|
||||
v.insertElementAt(test, v.size());
|
||||
}
|
||||
}
|
||||
|
||||
public void testRemoveBeginningOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector v = new Vector();
|
||||
prefillLists(t,v);
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
t.remove(1);
|
||||
v.removeElementAt(0);
|
||||
compareLists(t,v);
|
||||
}
|
||||
}
|
||||
|
||||
public void testRemoveEndOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector v = new Vector();
|
||||
prefillLists(t,v);
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
t.remove(0);
|
||||
v.removeElementAt(v.size()-1);
|
||||
compareLists(t,v);
|
||||
}
|
||||
}
|
||||
|
||||
public void testRemoveMiddleOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector v = new Vector();
|
||||
prefillLists(t,v);
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
int m = v.size() / 2;
|
||||
t.remove(m+1);
|
||||
v.removeElementAt(m);
|
||||
compareLists(t,v);
|
||||
}
|
||||
}
|
||||
public void testRemoveWhileIterating() {
|
||||
LuaTable t = LuaValue.tableOf(new LuaValue[] {
|
||||
LuaValue.valueOf("a"), LuaValue.valueOf("aa"),
|
||||
LuaValue.valueOf("b"), LuaValue.valueOf("bb"),
|
||||
LuaValue.valueOf("c"), LuaValue.valueOf("cc"),
|
||||
LuaValue.valueOf("d"), LuaValue.valueOf("dd"),
|
||||
LuaValue.valueOf("e"), LuaValue.valueOf("ee"),
|
||||
}, new LuaValue[] {
|
||||
LuaValue.valueOf("11"),
|
||||
LuaValue.valueOf("22"),
|
||||
LuaValue.valueOf("33"),
|
||||
LuaValue.valueOf("44"),
|
||||
LuaValue.valueOf("55"),
|
||||
});
|
||||
// Find expected order after removal.
|
||||
java.util.List<String> expected = new java.util.ArrayList<String>();
|
||||
Varargs n;
|
||||
int i;
|
||||
for (n = t.next(LuaValue.NIL), i = 0; !n.arg1().isnil(); n = t.next(n.arg1()), ++i) {
|
||||
if (i % 2 == 0)
|
||||
expected.add(n.arg1() + "=" + n.arg(2));
|
||||
}
|
||||
// Remove every other key while iterating over the table.
|
||||
for (n = t.next(LuaValue.NIL), i = 0; !n.arg1().isnil(); n = t.next(n.arg1()), ++i) {
|
||||
if (i % 2 != 0)
|
||||
t.set(n.arg1(), LuaValue.NIL);
|
||||
}
|
||||
// Iterate over remaining table, and form list of entries still in table.
|
||||
java.util.List<String> actual = new java.util.ArrayList<String>();
|
||||
for (n = t.next(LuaValue.NIL); !n.arg1().isnil(); n = t.next(n.arg1())) {
|
||||
actual.add(n.arg1() + "=" + n.arg(2));
|
||||
}
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
}
|
||||
1246
luaj-test/src/test/java/org/luaj/vm2/TypeTest.java
Normal file
1246
luaj-test/src/test/java/org/luaj/vm2/TypeTest.java
Normal file
File diff suppressed because it is too large
Load Diff
41
luaj-test/src/test/java/org/luaj/vm2/UTF8StreamTest.java
Normal file
41
luaj-test/src/test/java/org/luaj/vm2/UTF8StreamTest.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014 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;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
|
||||
public class UTF8StreamTest extends TestCase {
|
||||
|
||||
public void testUtf8CharsInStream() {
|
||||
String script = "x = \"98\u00b0: today's temp!\"\n"
|
||||
+ "print('x = ', x)\n"
|
||||
+ "return x";
|
||||
Globals globals = JsePlatform.standardGlobals();
|
||||
LuaValue chunk = globals.load(script);
|
||||
LuaValue result = chunk.call();
|
||||
String str = result.tojstring();
|
||||
assertEquals("98\u00b0: today's temp!", str);
|
||||
}
|
||||
|
||||
}
|
||||
1149
luaj-test/src/test/java/org/luaj/vm2/UnaryBinaryOperatorsTest.java
Normal file
1149
luaj-test/src/test/java/org/luaj/vm2/UnaryBinaryOperatorsTest.java
Normal file
File diff suppressed because it is too large
Load Diff
230
luaj-test/src/test/java/org/luaj/vm2/VarargsTest.java
Normal file
230
luaj-test/src/test/java/org/luaj/vm2/VarargsTest.java
Normal file
@@ -0,0 +1,230 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2012 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;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests of basic unary and binary operators on main value types.
|
||||
*/
|
||||
public class VarargsTest extends TestCase {
|
||||
|
||||
static LuaValue A = LuaValue.valueOf("a");
|
||||
static LuaValue B = LuaValue.valueOf("b");
|
||||
static LuaValue C = LuaValue.valueOf("c");
|
||||
static LuaValue D = LuaValue.valueOf("d");
|
||||
static LuaValue E = LuaValue.valueOf("e");
|
||||
static LuaValue F = LuaValue.valueOf("f");
|
||||
static LuaValue G = LuaValue.valueOf("g");
|
||||
static LuaValue H = LuaValue.valueOf("h");
|
||||
static LuaValue Z = LuaValue.valueOf("z");
|
||||
static LuaValue NIL = LuaValue.NIL;
|
||||
static Varargs A_G = LuaValue.varargsOf(new LuaValue[] { A, B, C, D, E, F, G });
|
||||
static Varargs B_E = LuaValue.varargsOf(new LuaValue[] { B, C, D, E });
|
||||
static Varargs C_G = LuaValue.varargsOf(new LuaValue[] { C, D, E, F, G });
|
||||
static Varargs C_E = LuaValue.varargsOf(new LuaValue[] { C, D, E });
|
||||
static Varargs DE = LuaValue.varargsOf(new LuaValue[] { D, E });
|
||||
static Varargs E_G = LuaValue.varargsOf(new LuaValue[] { E, F, G });
|
||||
static Varargs FG = LuaValue.varargsOf(new LuaValue[] { F, G });
|
||||
static LuaValue[] Z_H_array = {Z, A, B, C, D, E, F, G, H };
|
||||
static Varargs A_G_alt = new Varargs.ArrayPartVarargs(Z_H_array, 1, 7);
|
||||
static Varargs B_E_alt = new Varargs.ArrayPartVarargs(Z_H_array, 2, 4);
|
||||
static Varargs C_G_alt = new Varargs.ArrayPartVarargs(Z_H_array, 3, 5);
|
||||
static Varargs C_E_alt = new Varargs.ArrayPartVarargs(Z_H_array, 3, 3);
|
||||
static Varargs C_E_alt2 = LuaValue.varargsOf(C, D, E);
|
||||
static Varargs DE_alt = new Varargs.PairVarargs(D,E);
|
||||
static Varargs DE_alt2 = LuaValue.varargsOf(D,E);
|
||||
static Varargs E_G_alt = new Varargs.ArrayPartVarargs(Z_H_array, 5, 3);
|
||||
static Varargs FG_alt = new Varargs.PairVarargs(F, G);
|
||||
static Varargs NONE = LuaValue.NONE;
|
||||
|
||||
static void expectEquals(Varargs x, Varargs y) {
|
||||
assertEquals(x.narg(), y.narg());
|
||||
assertEquals(x.arg1(), y.arg1());
|
||||
assertEquals(x.arg(0), y.arg(0));
|
||||
assertEquals(x.arg(-1), y.arg(-1));
|
||||
assertEquals(x.arg(2), y.arg(2));
|
||||
assertEquals(x.arg(3), y.arg(3));
|
||||
for (int i = 4; i < x.narg() + 2; ++i)
|
||||
assertEquals(x.arg(i), y.arg(i));
|
||||
}
|
||||
|
||||
public void testSanity() {
|
||||
expectEquals(A_G, A_G);
|
||||
expectEquals(A_G_alt, A_G_alt);
|
||||
expectEquals(A_G, A_G_alt);
|
||||
expectEquals(B_E, B_E_alt);
|
||||
expectEquals(C_G, C_G_alt);
|
||||
expectEquals(C_E, C_E_alt);
|
||||
expectEquals(C_E, C_E_alt2);
|
||||
expectEquals(DE, DE_alt);
|
||||
expectEquals(DE, DE_alt2);
|
||||
expectEquals(E_G, E_G_alt);
|
||||
expectEquals(FG, FG_alt);
|
||||
expectEquals(FG_alt, FG_alt);
|
||||
expectEquals(A, A);
|
||||
expectEquals(NONE, NONE);
|
||||
expectEquals(NIL, NIL);
|
||||
}
|
||||
|
||||
public void testNegativeIndices() {
|
||||
expectNegSubargsError(A_G);
|
||||
expectNegSubargsError(A_G_alt);
|
||||
expectNegSubargsError(B_E);
|
||||
expectNegSubargsError(B_E_alt);
|
||||
expectNegSubargsError(C_G);
|
||||
expectNegSubargsError(C_G_alt);
|
||||
expectNegSubargsError(C_E);
|
||||
expectNegSubargsError(C_E_alt);
|
||||
expectNegSubargsError(C_E_alt2);
|
||||
expectNegSubargsError(DE);
|
||||
expectNegSubargsError(DE_alt);
|
||||
expectNegSubargsError(DE_alt2);
|
||||
expectNegSubargsError(E_G);
|
||||
expectNegSubargsError(FG);
|
||||
expectNegSubargsError(A);
|
||||
expectNegSubargsError(NONE);
|
||||
expectNegSubargsError(NIL);
|
||||
}
|
||||
|
||||
static void standardTestsA_G(Varargs a_g) {
|
||||
expectEquals(A_G, a_g);
|
||||
expectEquals(A_G, a_g.subargs(1));
|
||||
expectEquals(C_G, a_g.subargs(3).subargs(1));
|
||||
expectEquals(E_G, a_g.subargs(5));
|
||||
expectEquals(E_G, a_g.subargs(5).subargs(1));
|
||||
expectEquals(FG, a_g.subargs(6));
|
||||
expectEquals(FG, a_g.subargs(6).subargs(1));
|
||||
expectEquals(G, a_g.subargs(7));
|
||||
expectEquals(G, a_g.subargs(7).subargs(1));
|
||||
expectEquals(NONE, a_g.subargs(8));
|
||||
expectEquals(NONE, a_g.subargs(8).subargs(1));
|
||||
standardTestsC_G(A_G.subargs(3));
|
||||
}
|
||||
|
||||
static void standardTestsC_G(Varargs c_g) {
|
||||
expectEquals(C_G, c_g.subargs(1));
|
||||
expectEquals(E_G, c_g.subargs(3));
|
||||
expectEquals(E_G, c_g.subargs(3).subargs(1));
|
||||
expectEquals(FG, c_g.subargs(4));
|
||||
expectEquals(FG, c_g.subargs(4).subargs(1));
|
||||
expectEquals(G, c_g.subargs(5));
|
||||
expectEquals(G, c_g.subargs(5).subargs(1));
|
||||
expectEquals(NONE, c_g.subargs(6));
|
||||
expectEquals(NONE, c_g.subargs(6).subargs(1));
|
||||
standardTestsE_G(c_g.subargs(3));
|
||||
}
|
||||
|
||||
static void standardTestsE_G(Varargs e_g) {
|
||||
expectEquals(E_G, e_g.subargs(1));
|
||||
expectEquals(FG, e_g.subargs(2));
|
||||
expectEquals(FG, e_g.subargs(2).subargs(1));
|
||||
expectEquals(G, e_g.subargs(3));
|
||||
expectEquals(G, e_g.subargs(3).subargs(1));
|
||||
expectEquals(NONE, e_g.subargs(4));
|
||||
expectEquals(NONE, e_g.subargs(4).subargs(1));
|
||||
standardTestsFG(e_g.subargs(2));
|
||||
}
|
||||
|
||||
static void standardTestsFG(Varargs fg) {
|
||||
expectEquals(FG, fg.subargs(1));
|
||||
expectEquals(G, fg.subargs(2));
|
||||
expectEquals(G, fg.subargs(2).subargs(1));
|
||||
expectEquals(NONE, fg.subargs(3));
|
||||
expectEquals(NONE, fg.subargs(3).subargs(1));
|
||||
}
|
||||
|
||||
static void standardTestsNone(Varargs none) {
|
||||
expectEquals(NONE, none.subargs(1));
|
||||
expectEquals(NONE, none.subargs(2));
|
||||
}
|
||||
|
||||
public void testVarargsSubargs() {
|
||||
standardTestsA_G(A_G);
|
||||
standardTestsA_G(A_G_alt);
|
||||
standardTestsC_G(C_G);
|
||||
standardTestsC_G(C_G_alt);
|
||||
standardTestsE_G(E_G);
|
||||
standardTestsE_G(E_G_alt);
|
||||
standardTestsFG(FG);
|
||||
standardTestsFG(FG_alt);
|
||||
standardTestsNone(NONE);
|
||||
}
|
||||
|
||||
public void testVarargsMore() {
|
||||
Varargs a_g;
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, }, LuaValue.varargsOf( new LuaValue[] { B, C, D, E, F, G }));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, B, }, LuaValue.varargsOf( new LuaValue[] { C, D, E, F, G }));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, B, C, }, LuaValue.varargsOf( new LuaValue[] { D, E, F, G }));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, B, C, D, }, LuaValue.varargsOf(E, F, G));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, B, C, D, E }, LuaValue.varargsOf( F, G ));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, B, C, D, E, F, }, G );
|
||||
standardTestsA_G(a_g);
|
||||
}
|
||||
|
||||
public void testPairVarargsMore() {
|
||||
Varargs a_g = new Varargs.PairVarargs(A,
|
||||
new Varargs.PairVarargs(B,
|
||||
new Varargs.PairVarargs(C,
|
||||
new Varargs.PairVarargs(D,
|
||||
new Varargs.PairVarargs(E,
|
||||
new Varargs.PairVarargs(F, G))))));
|
||||
standardTestsA_G(a_g);
|
||||
}
|
||||
|
||||
public void testArrayPartMore() {
|
||||
Varargs a_g;
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 1, new Varargs.ArrayPartVarargs(Z_H_array, 2, 6));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 2, new Varargs.ArrayPartVarargs(Z_H_array, 3, 5));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 3, new Varargs.ArrayPartVarargs(Z_H_array, 4, 4));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 4, new Varargs.ArrayPartVarargs(Z_H_array, 5, 3));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 5, new Varargs.ArrayPartVarargs(Z_H_array, 6, 2));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 6, new Varargs.ArrayPartVarargs(Z_H_array, 7, 1));
|
||||
standardTestsA_G(a_g);
|
||||
}
|
||||
|
||||
static void expectNegSubargsError(Varargs v) {
|
||||
String expected_msg = "bad argument #1: start must be > 0";
|
||||
try {
|
||||
v.subargs(0);
|
||||
fail("Failed to throw exception for index 0");
|
||||
} catch ( LuaError e ) {
|
||||
assertEquals(expected_msg, e.getMessage());
|
||||
}
|
||||
try {
|
||||
v.subargs(-1);
|
||||
fail("Failed to throw exception for index -1");
|
||||
} catch ( LuaError e ) {
|
||||
assertEquals(expected_msg, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
261
luaj-test/src/test/java/org/luaj/vm2/WeakTableTest.java
Normal file
261
luaj-test/src/test/java/org/luaj/vm2/WeakTableTest.java
Normal file
@@ -0,0 +1,261 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2009 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;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
abstract public class WeakTableTest extends TableTest {
|
||||
|
||||
public static class MyData {
|
||||
public final int value;
|
||||
public MyData( int value ) {
|
||||
this.value = value;
|
||||
}
|
||||
public int hashCode() {
|
||||
return value;
|
||||
}
|
||||
public boolean equals( Object o ) {
|
||||
return (o instanceof MyData) && ((MyData)o).value == value;
|
||||
}
|
||||
public String toString() {
|
||||
return "mydata-"+value;
|
||||
}
|
||||
}
|
||||
|
||||
static void collectGarbage() {
|
||||
Runtime rt = Runtime.getRuntime();
|
||||
rt.gc();
|
||||
try {
|
||||
Thread.sleep(20);
|
||||
rt.gc();
|
||||
Thread.sleep(20);
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
rt.gc();
|
||||
}
|
||||
|
||||
public static class WeakValueTableTest extends WeakTableTest {
|
||||
protected LuaTable new_Table() { return WeakTable.make(false, true); }
|
||||
protected LuaTable new_Table(int n,int m) { return WeakTable.make(false, true); }
|
||||
|
||||
public void testWeakValuesTable() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
Object obj = new Object();
|
||||
LuaTable tableValue = new LuaTable();
|
||||
LuaString stringValue = LuaString.valueOf("this is a test");
|
||||
LuaTable tableValue2 = new LuaTable();
|
||||
|
||||
t.set("table", tableValue);
|
||||
t.set("userdata", LuaValue.userdataOf(obj, null));
|
||||
t.set("string", stringValue);
|
||||
t.set("string2", LuaValue.valueOf("another string"));
|
||||
t.set(1, tableValue2);
|
||||
assertTrue("table must have at least 4 elements", t.getHashLength() >= 4);
|
||||
assertTrue("array part must have 1 element", t.getArrayLength() >= 1);
|
||||
|
||||
// check that table can be used to get elements
|
||||
assertEquals(tableValue, t.get("table"));
|
||||
assertEquals(stringValue, t.get("string"));
|
||||
assertEquals(obj, t.get("userdata").checkuserdata());
|
||||
assertEquals(tableValue2, t.get(1));
|
||||
|
||||
// nothing should be collected, since we have strong references here
|
||||
collectGarbage();
|
||||
|
||||
// check that elements are still there
|
||||
assertEquals(tableValue, t.get("table"));
|
||||
assertEquals(stringValue, t.get("string"));
|
||||
assertEquals(obj, t.get("userdata").checkuserdata());
|
||||
assertEquals(tableValue2, t.get(1));
|
||||
|
||||
// drop our strong references
|
||||
obj = null;
|
||||
tableValue = null;
|
||||
tableValue2 = null;
|
||||
stringValue = null;
|
||||
|
||||
// Garbage collection should cause weak entries to be dropped.
|
||||
collectGarbage();
|
||||
|
||||
// check that they are dropped
|
||||
assertEquals(LuaValue.NIL, t.get("table"));
|
||||
assertEquals(LuaValue.NIL, t.get("userdata"));
|
||||
assertEquals(LuaValue.NIL, t.get(1));
|
||||
assertFalse("strings should not be in weak references", t.get("string").isnil());
|
||||
}
|
||||
}
|
||||
|
||||
public static class WeakKeyTableTest extends WeakTableTest {
|
||||
protected LuaTable new_Table() { return WeakTable.make(true, false); }
|
||||
protected LuaTable new_Table(int n,int m) { return WeakTable.make(true, false); }
|
||||
|
||||
public void testWeakKeysTable() {
|
||||
LuaTable t = WeakTable.make(true, false);
|
||||
|
||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
||||
|
||||
// set up the table
|
||||
t.set( key, val );
|
||||
assertEquals( val, t.get(key) );
|
||||
System.gc();
|
||||
assertEquals( val, t.get(key) );
|
||||
|
||||
// drop key and value references, replace them with new ones
|
||||
WeakReference origkey = new WeakReference(key);
|
||||
WeakReference origval = new WeakReference(val);
|
||||
key = LuaValue.userdataOf(new MyData(111));
|
||||
val = LuaValue.userdataOf(new MyData(222));
|
||||
|
||||
// new key and value should be interchangeable (feature of this test class)
|
||||
assertEquals( key, origkey.get() );
|
||||
assertEquals( val, origval.get() );
|
||||
assertEquals( val, t.get(key) );
|
||||
assertEquals( val, t.get((LuaValue) origkey.get()) );
|
||||
assertEquals( origval.get(), t.get(key) );
|
||||
|
||||
// value should not be reachable after gc
|
||||
collectGarbage();
|
||||
assertEquals( null, origkey.get() );
|
||||
assertEquals( LuaValue.NIL, t.get(key) );
|
||||
collectGarbage();
|
||||
assertEquals( null, origval.get() );
|
||||
}
|
||||
|
||||
public void testNext() {
|
||||
LuaTable t = WeakTable.make(true, true);
|
||||
|
||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
||||
LuaValue key2 = LuaValue.userdataOf(new MyData(333));
|
||||
LuaValue val2 = LuaValue.userdataOf(new MyData(444));
|
||||
LuaValue key3 = LuaValue.userdataOf(new MyData(555));
|
||||
LuaValue val3 = LuaValue.userdataOf(new MyData(666));
|
||||
|
||||
// set up the table
|
||||
t.set( key, val );
|
||||
t.set( key2, val2 );
|
||||
t.set( key3, val3 );
|
||||
|
||||
// forget one of the keys
|
||||
key2 = null;
|
||||
val2 = null;
|
||||
collectGarbage();
|
||||
|
||||
// table should have 2 entries
|
||||
int size = 0;
|
||||
for ( LuaValue k = t.next(LuaValue.NIL).arg1(); !k.isnil();
|
||||
k = t.next(k).arg1() ) {
|
||||
size++;
|
||||
}
|
||||
assertEquals(2, size);
|
||||
}
|
||||
}
|
||||
|
||||
public static class WeakKeyValueTableTest extends WeakTableTest {
|
||||
protected LuaTable new_Table() { return WeakTable.make(true, true); }
|
||||
protected LuaTable new_Table(int n,int m) { return WeakTable.make(true, true); }
|
||||
|
||||
public void testWeakKeysValuesTable() {
|
||||
LuaTable t = WeakTable.make(true, true);
|
||||
|
||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
||||
LuaValue key2 = LuaValue.userdataOf(new MyData(333));
|
||||
LuaValue val2 = LuaValue.userdataOf(new MyData(444));
|
||||
LuaValue key3 = LuaValue.userdataOf(new MyData(555));
|
||||
LuaValue val3 = LuaValue.userdataOf(new MyData(666));
|
||||
|
||||
// set up the table
|
||||
t.set( key, val );
|
||||
t.set( key2, val2 );
|
||||
t.set( key3, val3 );
|
||||
assertEquals( val, t.get(key) );
|
||||
assertEquals( val2, t.get(key2) );
|
||||
assertEquals( val3, t.get(key3) );
|
||||
System.gc();
|
||||
assertEquals( val, t.get(key) );
|
||||
assertEquals( val2, t.get(key2) );
|
||||
assertEquals( val3, t.get(key3) );
|
||||
|
||||
// drop key and value references, replace them with new ones
|
||||
WeakReference origkey = new WeakReference(key);
|
||||
WeakReference origval = new WeakReference(val);
|
||||
WeakReference origkey2 = new WeakReference(key2);
|
||||
WeakReference origval2 = new WeakReference(val2);
|
||||
WeakReference origkey3 = new WeakReference(key3);
|
||||
WeakReference origval3 = new WeakReference(val3);
|
||||
key = LuaValue.userdataOf(new MyData(111));
|
||||
val = LuaValue.userdataOf(new MyData(222));
|
||||
key2 = LuaValue.userdataOf(new MyData(333));
|
||||
// don't drop val2, or key3
|
||||
val3 = LuaValue.userdataOf(new MyData(666));
|
||||
|
||||
// no values should be reachable after gc
|
||||
collectGarbage();
|
||||
assertEquals( null, origkey.get() );
|
||||
assertEquals( null, origval.get() );
|
||||
assertEquals( null, origkey2.get() );
|
||||
assertEquals( null, origval3.get() );
|
||||
assertEquals( LuaValue.NIL, t.get(key) );
|
||||
assertEquals( LuaValue.NIL, t.get(key2) );
|
||||
assertEquals( LuaValue.NIL, t.get(key3) );
|
||||
|
||||
// all originals should be gone after gc, then access
|
||||
val2 = null;
|
||||
key3 = null;
|
||||
collectGarbage();
|
||||
assertEquals( null, origval2.get() );
|
||||
assertEquals( null, origkey3.get() );
|
||||
}
|
||||
|
||||
public void testReplace() {
|
||||
LuaTable t = WeakTable.make(true, true);
|
||||
|
||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
||||
LuaValue key2 = LuaValue.userdataOf(new MyData(333));
|
||||
LuaValue val2 = LuaValue.userdataOf(new MyData(444));
|
||||
LuaValue key3 = LuaValue.userdataOf(new MyData(555));
|
||||
LuaValue val3 = LuaValue.userdataOf(new MyData(666));
|
||||
|
||||
// set up the table
|
||||
t.set( key, val );
|
||||
t.set( key2, val2 );
|
||||
t.set( key3, val3 );
|
||||
|
||||
LuaValue val4 = LuaValue.userdataOf(new MyData(777));
|
||||
t.set( key2, val4 );
|
||||
|
||||
// table should have 3 entries
|
||||
int size = 0;
|
||||
for ( LuaValue k = t.next(LuaValue.NIL).arg1();
|
||||
!k.isnil() && size < 1000;
|
||||
k = t.next(k).arg1() ) {
|
||||
size++;
|
||||
}
|
||||
assertEquals(3, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package org.luaj.vm2.compiler;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LoadState;
|
||||
import org.luaj.vm2.Print;
|
||||
import org.luaj.vm2.Prototype;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
|
||||
abstract public class AbstractUnitTests extends TestCase {
|
||||
|
||||
private final String dir;
|
||||
private final String jar;
|
||||
private Globals globals;
|
||||
|
||||
public AbstractUnitTests(String zipdir, String zipfile, String dir) {
|
||||
URL zip = null;
|
||||
zip = getClass().getResource(zipfile);
|
||||
if ( zip == null ) {
|
||||
File file = new File(zipdir+"/"+zipfile);
|
||||
try {
|
||||
if ( file.exists() )
|
||||
zip = file.toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if ( zip == null )
|
||||
throw new RuntimeException("not found: "+zipfile);
|
||||
this.jar = "jar:" + zip.toExternalForm()+ "!/";
|
||||
this.dir = dir;
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
globals = JsePlatform.standardGlobals();
|
||||
}
|
||||
|
||||
protected String pathOfFile(String file) {
|
||||
return jar + dir + "/" + file;
|
||||
}
|
||||
|
||||
protected InputStream inputStreamOfPath(String path) throws IOException {
|
||||
URL url = new URL(path);
|
||||
return url.openStream();
|
||||
}
|
||||
|
||||
protected InputStream inputStreamOfFile(String file) throws IOException {
|
||||
return inputStreamOfPath(pathOfFile(file));
|
||||
}
|
||||
|
||||
protected void doTest(String file) {
|
||||
try {
|
||||
// load source from jar
|
||||
String path = pathOfFile(file);
|
||||
byte[] lua = bytesFromJar(path);
|
||||
|
||||
// compile in memory
|
||||
InputStream is = new ByteArrayInputStream(lua);
|
||||
Prototype p = globals.loadPrototype(is, "@" + file, "bt");
|
||||
String actual = protoToString(p);
|
||||
|
||||
// load expected value from jar
|
||||
byte[] luac = bytesFromJar(path.substring(0, path.length()-4)+".lc");
|
||||
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 {
|
||||
InputStream is = inputStreamOfPath(path);
|
||||
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 globals.loadPrototype(is, script, "b");
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.luaj.vm2.compiler;
|
||||
|
||||
|
||||
|
||||
public class CompilerUnitTests extends AbstractUnitTests {
|
||||
|
||||
public CompilerUnitTests() {
|
||||
super("test/lua", "luaj3.0-tests.zip", "lua5.2.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 testBitwise() { doTest("bitwise.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 testCoroutine() { doTest("coroutine.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 testGoto() { doTest("goto.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"); }
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
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 java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LoadState;
|
||||
import org.luaj.vm2.LuaClosure;
|
||||
import org.luaj.vm2.LuaFunction;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Prototype;
|
||||
import org.luaj.vm2.lib.jse.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 Globals globals;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
globals = JsePlatform.standardGlobals();
|
||||
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
|
||||
Reader reader = new StringReader(script);
|
||||
Prototype p = globals.compilePrototype(reader, "script");
|
||||
|
||||
// double check script result before dumping
|
||||
LuaFunction f = new LuaClosure(p, globals);
|
||||
LuaValue r = f.call();
|
||||
String actual = r.tojstring();
|
||||
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
|
||||
InputStream is = new ByteArrayInputStream(dumped);
|
||||
f = globals.load(is, "dumped", "b", globals).checkfunction();
|
||||
r = f.call();
|
||||
actual = r.tojstring();
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.luaj.vm2.compiler;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.parser.LuaParser;
|
||||
|
||||
public class LuaParserTests extends CompilerUnitTests {
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
LuaValue.valueOf(true);
|
||||
}
|
||||
|
||||
protected void doTest(String file) {
|
||||
try {
|
||||
InputStream is = inputStreamOfFile(file);
|
||||
Reader r = new InputStreamReader(is, "ISO-8859-1");
|
||||
LuaParser parser = new LuaParser(r);
|
||||
parser.Chunk();
|
||||
} catch (Exception e) {
|
||||
fail(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
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( "test/lua", "luaj3.0-tests.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"); }
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package org.luaj.vm2.compiler;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LuaDouble;
|
||||
import org.luaj.vm2.LuaInteger;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.jse.JsePlatform;
|
||||
|
||||
public class SimpleTests extends TestCase {
|
||||
|
||||
private Globals globals;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
globals = JsePlatform.standardGlobals();
|
||||
}
|
||||
|
||||
private void doTest( String script ) {
|
||||
try {
|
||||
LuaValue c = globals.load(script, "script");
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.luaj.vm2.lib.jse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Varargs;
|
||||
|
||||
|
||||
public class JsePlatformTest extends TestCase {
|
||||
public void testLuaMainPassesArguments() {
|
||||
Globals globals = JsePlatform.standardGlobals();
|
||||
LuaValue chunk = globals.load("return #arg, arg.n, arg[2], arg[1]");
|
||||
Varargs results = JsePlatform.luaMain(chunk, new String[] { "aaa", "bbb" });
|
||||
assertEquals(results.narg(), 4);
|
||||
assertEquals(results.arg(1), LuaValue.valueOf(2));
|
||||
assertEquals(results.arg(2), LuaValue.valueOf(2));
|
||||
assertEquals(results.arg(3), LuaValue.valueOf("bbb"));
|
||||
assertEquals(results.arg(4), LuaValue.valueOf("aaa"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,446 @@
|
||||
package org.luaj.vm2.lib.jse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.LuaError;
|
||||
import org.luaj.vm2.LuaInteger;
|
||||
import org.luaj.vm2.LuaString;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.Varargs;
|
||||
import org.luaj.vm2.lib.MathLib;
|
||||
|
||||
public class LuaJavaCoercionTest extends TestCase {
|
||||
|
||||
private static LuaValue globals;
|
||||
private static LuaValue ZERO = LuaValue.ZERO;
|
||||
private static LuaValue ONE = LuaValue.ONE;
|
||||
private static LuaValue TWO = LuaValue.valueOf(2);
|
||||
private static LuaValue THREE = LuaValue.valueOf(3);
|
||||
private static LuaString LENGTH = LuaString.valueOf("length");
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
globals = JsePlatform.standardGlobals();
|
||||
}
|
||||
|
||||
public void testJavaIntToLuaInt() {
|
||||
Integer i = Integer.valueOf(777);
|
||||
LuaValue v = CoerceJavaToLua.coerce(i);
|
||||
assertEquals( LuaInteger.class, v.getClass() );
|
||||
assertEquals( 777, v.toint() );
|
||||
}
|
||||
|
||||
public void testLuaIntToJavaInt() {
|
||||
LuaInteger i = LuaInteger.valueOf(777);
|
||||
Object o = CoerceLuaToJava.coerce(i, int.class);
|
||||
assertEquals( Integer.class, o.getClass() );
|
||||
assertEquals( 777, ((Number)o).intValue() );
|
||||
o = CoerceLuaToJava.coerce(i, Integer.class);
|
||||
assertEquals( Integer.class, o.getClass() );
|
||||
assertEquals( new Integer(777), o );
|
||||
}
|
||||
|
||||
public void testJavaStringToLuaString() {
|
||||
String s = new String("777");
|
||||
LuaValue v = CoerceJavaToLua.coerce(s);
|
||||
assertEquals( LuaString.class, v.getClass() );
|
||||
assertEquals( "777", v.toString() );
|
||||
}
|
||||
|
||||
public void testLuaStringToJavaString() {
|
||||
LuaString s = LuaValue.valueOf("777");
|
||||
Object o = CoerceLuaToJava.coerce(s, String.class);
|
||||
assertEquals( String.class, o.getClass() );
|
||||
assertEquals( "777", o );
|
||||
}
|
||||
|
||||
public void testJavaClassToLuaUserdata() {
|
||||
LuaValue va = CoerceJavaToLua.coerce(ClassA.class);
|
||||
LuaValue va1 = CoerceJavaToLua.coerce(ClassA.class);
|
||||
LuaValue vb = CoerceJavaToLua.coerce(ClassB.class);
|
||||
assertSame(va, va1);
|
||||
assertNotSame(va, vb);
|
||||
LuaValue vi = CoerceJavaToLua.coerce(new ClassA());
|
||||
assertNotSame(va, vi);
|
||||
assertTrue(vi.isuserdata());
|
||||
assertTrue(vi.isuserdata(ClassA.class));
|
||||
assertFalse(vi.isuserdata(ClassB.class));
|
||||
LuaValue vj = CoerceJavaToLua.coerce(new ClassB());
|
||||
assertNotSame(vb, vj);
|
||||
assertTrue(vj.isuserdata());
|
||||
assertFalse(vj.isuserdata(ClassA.class));
|
||||
assertTrue(vj.isuserdata(ClassB.class));
|
||||
}
|
||||
|
||||
static class ClassA {
|
||||
}
|
||||
|
||||
static class ClassB {
|
||||
}
|
||||
|
||||
public void testJavaIntArrayToLuaTable() {
|
||||
int[] i = { 222, 333 };
|
||||
LuaValue v = CoerceJavaToLua.coerce(i);
|
||||
assertEquals( JavaArray.class, v.getClass() );
|
||||
assertEquals( LuaInteger.valueOf(222), v.get(ONE) );
|
||||
assertEquals( LuaInteger.valueOf(333), v.get(TWO) );
|
||||
assertEquals( TWO, v.get(LENGTH));
|
||||
assertEquals( LuaValue.NIL, v.get(THREE) );
|
||||
assertEquals( LuaValue.NIL, v.get(ZERO) );
|
||||
v.set(ONE, LuaInteger.valueOf(444));
|
||||
v.set(TWO, LuaInteger.valueOf(555));
|
||||
assertEquals( 444, i[0] );
|
||||
assertEquals( 555, i[1] );
|
||||
assertEquals( LuaInteger.valueOf(444), v.get(ONE) );
|
||||
assertEquals( LuaInteger.valueOf(555), v.get(TWO) );
|
||||
try {
|
||||
v.set(ZERO, LuaInteger.valueOf(777));
|
||||
fail( "array bound exception not thrown" );
|
||||
} catch ( LuaError lee ) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
v.set(THREE, LuaInteger.valueOf(777));
|
||||
fail( "array bound exception not thrown" );
|
||||
} catch ( LuaError lee ) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void testLuaTableToJavaIntArray() {
|
||||
LuaTable t = new LuaTable();
|
||||
t.set(1, LuaInteger.valueOf(222) );
|
||||
t.set(2, LuaInteger.valueOf(333) );
|
||||
int[] i = null;
|
||||
Object o = CoerceLuaToJava.coerce(t, int[].class);
|
||||
assertEquals( int[].class, o.getClass() );
|
||||
i = (int[]) o;
|
||||
assertEquals( 2, i.length );
|
||||
assertEquals( 222, i[0] );
|
||||
assertEquals( 333, i[1] );
|
||||
}
|
||||
|
||||
public void testIntArrayScoringTables() {
|
||||
int a = 5;
|
||||
LuaValue la = LuaInteger.valueOf(a);
|
||||
LuaTable tb = new LuaTable();
|
||||
tb.set( 1, la );
|
||||
LuaTable tc = new LuaTable();
|
||||
tc.set( 1, tb );
|
||||
|
||||
int saa = CoerceLuaToJava.getCoercion(int.class).score(la);
|
||||
int sab = CoerceLuaToJava.getCoercion(int[].class).score(la);
|
||||
int sac = CoerceLuaToJava.getCoercion(int[][].class).score(la);
|
||||
assertTrue( saa < sab );
|
||||
assertTrue( saa < sac );
|
||||
int sba = CoerceLuaToJava.getCoercion(int.class).score(tb);
|
||||
int sbb = CoerceLuaToJava.getCoercion(int[].class).score(tb);
|
||||
int sbc = CoerceLuaToJava.getCoercion(int[][].class).score(tb);
|
||||
assertTrue( sbb < sba );
|
||||
assertTrue( sbb < sbc );
|
||||
int sca = CoerceLuaToJava.getCoercion(int.class).score(tc);
|
||||
int scb = CoerceLuaToJava.getCoercion(int[].class).score(tc);
|
||||
int scc = CoerceLuaToJava.getCoercion(int[][].class).score(tc);
|
||||
assertTrue( scc < sca );
|
||||
assertTrue( scc < scb );
|
||||
}
|
||||
|
||||
public void testIntArrayScoringUserdata() {
|
||||
int a = 5;
|
||||
int[] b = { 44, 66 };
|
||||
int[][] c = { { 11, 22 }, { 33, 44 } };
|
||||
LuaValue va = CoerceJavaToLua.coerce(a);
|
||||
LuaValue vb = CoerceJavaToLua.coerce(b);
|
||||
LuaValue vc = CoerceJavaToLua.coerce(c);
|
||||
|
||||
int vaa = CoerceLuaToJava.getCoercion(int.class).score(va);
|
||||
int vab = CoerceLuaToJava.getCoercion(int[].class).score(va);
|
||||
int vac = CoerceLuaToJava.getCoercion(int[][].class).score(va);
|
||||
assertTrue( vaa < vab );
|
||||
assertTrue( vaa < vac );
|
||||
int vba = CoerceLuaToJava.getCoercion(int.class).score(vb);
|
||||
int vbb = CoerceLuaToJava.getCoercion(int[].class).score(vb);
|
||||
int vbc = CoerceLuaToJava.getCoercion(int[][].class).score(vb);
|
||||
assertTrue( vbb < vba );
|
||||
assertTrue( vbb < vbc );
|
||||
int vca = CoerceLuaToJava.getCoercion(int.class).score(vc);
|
||||
int vcb = CoerceLuaToJava.getCoercion(int[].class).score(vc);
|
||||
int vcc = CoerceLuaToJava.getCoercion(int[][].class).score(vc);
|
||||
assertTrue( vcc < vca );
|
||||
assertTrue( vcc < vcb );
|
||||
}
|
||||
|
||||
public static class SampleClass {
|
||||
public String sample() { return "void-args"; }
|
||||
public String sample(int a) { return "int-args "+a; }
|
||||
public String sample(int[] a) { return "int-array-args "+a[0]+","+a[1]; }
|
||||
public String sample(int[][] a) { return "int-array-array-args "+a[0][0]+","+a[0][1]+","+a[1][0]+","+a[1][1]; }
|
||||
}
|
||||
|
||||
public void testMatchVoidArgs() {
|
||||
LuaValue v = CoerceJavaToLua.coerce(new SampleClass());
|
||||
LuaValue result = v.method("sample");
|
||||
assertEquals( "void-args", result.toString() );
|
||||
}
|
||||
|
||||
public void testMatchIntArgs() {
|
||||
LuaValue v = CoerceJavaToLua.coerce(new SampleClass());
|
||||
LuaValue arg = CoerceJavaToLua.coerce(new Integer(123));
|
||||
LuaValue result = v.method("sample",arg);
|
||||
assertEquals( "int-args 123", result.toString() );
|
||||
}
|
||||
|
||||
public void testMatchIntArrayArgs() {
|
||||
LuaValue v = CoerceJavaToLua.coerce(new SampleClass());
|
||||
LuaValue arg = CoerceJavaToLua.coerce(new int[]{345,678});
|
||||
LuaValue result = v.method("sample",arg);
|
||||
assertEquals( "int-array-args 345,678", result.toString() );
|
||||
}
|
||||
|
||||
public void testMatchIntArrayArrayArgs() {
|
||||
LuaValue v = CoerceJavaToLua.coerce(new SampleClass());
|
||||
LuaValue arg = CoerceJavaToLua.coerce(new int[][]{{22,33},{44,55}});
|
||||
LuaValue result = v.method("sample",arg);
|
||||
assertEquals( "int-array-array-args 22,33,44,55", result.toString() );
|
||||
}
|
||||
|
||||
public static final class SomeException extends RuntimeException {
|
||||
public SomeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class SomeClass {
|
||||
public static void someMethod() {
|
||||
throw new SomeException( "this is some message" );
|
||||
}
|
||||
}
|
||||
|
||||
public void testExceptionMessage() {
|
||||
String script = "local c = luajava.bindClass( \""+SomeClass.class.getName()+"\" )\n" +
|
||||
"return pcall( c.someMethod, c )";
|
||||
Varargs vresult = globals.get("load").call(LuaValue.valueOf(script)).invoke(LuaValue.NONE);
|
||||
LuaValue status = vresult.arg1();
|
||||
LuaValue message = vresult.arg(2);
|
||||
assertEquals( LuaValue.FALSE, status );
|
||||
int index = message.toString().indexOf( "this is some message" );
|
||||
assertTrue( "bad message: "+message, index>=0 );
|
||||
}
|
||||
|
||||
public void testLuaErrorCause() {
|
||||
String script = "luajava.bindClass( \""+SomeClass.class.getName()+"\"):someMethod()";
|
||||
LuaValue chunk = globals.get("load").call(LuaValue.valueOf(script));
|
||||
try {
|
||||
chunk.invoke(LuaValue.NONE);
|
||||
fail( "call should not have succeeded" );
|
||||
} catch ( LuaError lee ) {
|
||||
Throwable c = lee.getCause();
|
||||
assertEquals( SomeException.class, c.getClass() );
|
||||
}
|
||||
}
|
||||
|
||||
public interface VarArgsInterface {
|
||||
public String varargsMethod( String a, String ... v );
|
||||
public String arrayargsMethod( String a, String[] v );
|
||||
}
|
||||
|
||||
public void testVarArgsProxy() {
|
||||
String script = "return luajava.createProxy( \""+VarArgsInterface.class.getName()+"\", \n"+
|
||||
"{\n" +
|
||||
" varargsMethod = function(a,...)\n" +
|
||||
" return table.concat({a,...},'-')\n" +
|
||||
" end,\n" +
|
||||
" arrayargsMethod = function(a,array)\n" +
|
||||
" return tostring(a)..(array and \n" +
|
||||
" ('-'..tostring(array.length)\n" +
|
||||
" ..'-'..tostring(array[1])\n" +
|
||||
" ..'-'..tostring(array[2])\n" +
|
||||
" ) or '-nil')\n" +
|
||||
" end,\n" +
|
||||
"} )\n";
|
||||
Varargs chunk = globals.get("load").call(LuaValue.valueOf(script));
|
||||
if ( ! chunk.arg1().toboolean() )
|
||||
fail( chunk.arg(2).toString() );
|
||||
LuaValue result = chunk.arg1().call();
|
||||
Object u = result.touserdata();
|
||||
VarArgsInterface v = (VarArgsInterface) u;
|
||||
assertEquals( "foo", v.varargsMethod("foo") );
|
||||
assertEquals( "foo-bar", v.varargsMethod("foo", "bar") );
|
||||
assertEquals( "foo-bar-etc", v.varargsMethod("foo", "bar", "etc") );
|
||||
assertEquals( "foo-0-nil-nil", v.arrayargsMethod("foo", new String[0]) );
|
||||
assertEquals( "foo-1-bar-nil", v.arrayargsMethod("foo", new String[] {"bar"}) );
|
||||
assertEquals( "foo-2-bar-etc", v.arrayargsMethod("foo", new String[] {"bar","etc"}) );
|
||||
assertEquals( "foo-3-bar-etc", v.arrayargsMethod("foo", new String[] {"bar","etc","etc"}) );
|
||||
assertEquals( "foo-nil", v.arrayargsMethod("foo", null) );
|
||||
}
|
||||
|
||||
public void testBigNum() {
|
||||
String script =
|
||||
"bigNumA = luajava.newInstance('java.math.BigDecimal','12345678901234567890');\n" +
|
||||
"bigNumB = luajava.newInstance('java.math.BigDecimal','12345678901234567890');\n" +
|
||||
"bigNumC = bigNumA:multiply(bigNumB);\n" +
|
||||
//"print(bigNumA:toString())\n" +
|
||||
//"print(bigNumB:toString())\n" +
|
||||
//"print(bigNumC:toString())\n" +
|
||||
"return bigNumA:toString(), bigNumB:toString(), bigNumC:toString()";
|
||||
Varargs chunk = globals.get("load").call(LuaValue.valueOf(script));
|
||||
if ( ! chunk.arg1().toboolean() )
|
||||
fail( chunk.arg(2).toString() );
|
||||
Varargs results = chunk.arg1().invoke();
|
||||
int nresults = results.narg();
|
||||
String sa = results.tojstring(1);
|
||||
String sb = results.tojstring(2);
|
||||
String sc = results.tojstring(3);
|
||||
assertEquals( 3, nresults );
|
||||
assertEquals( "12345678901234567890", sa );
|
||||
assertEquals( "12345678901234567890", sb );
|
||||
assertEquals( "152415787532388367501905199875019052100", sc );
|
||||
}
|
||||
|
||||
public interface IA {}
|
||||
public interface IB extends IA {}
|
||||
public interface IC extends IB {}
|
||||
|
||||
public static class A implements IA {
|
||||
}
|
||||
public static class B extends A implements IB {
|
||||
public String set( Object x ) { return "set(Object) "; }
|
||||
public String set( String x ) { return "set(String) "+x; }
|
||||
public String set( A x ) { return "set(A) "; }
|
||||
public String set( B x ) { return "set(B) "; }
|
||||
public String set( C x ) { return "set(C) "; }
|
||||
public String set( byte x ) { return "set(byte) "+x; }
|
||||
public String set( char x ) { return "set(char) "+(int)x; }
|
||||
public String set( short x ) { return "set(short) "+x; }
|
||||
public String set( int x ) { return "set(int) "+x; }
|
||||
public String set( long x ) { return "set(long) "+x; }
|
||||
public String set( float x ) { return "set(float) "+x; }
|
||||
public String set( double x ) { return "set(double) "+x; }
|
||||
|
||||
public String setr( double x ) { return "setr(double) "+x; }
|
||||
public String setr( float x ) { return "setr(float) "+x; }
|
||||
public String setr( long x ) { return "setr(long) "+x; }
|
||||
public String setr( int x ) { return "setr(int) "+x; }
|
||||
public String setr( short x ) { return "setr(short) "+x; }
|
||||
public String setr( char x ) { return "setr(char) "+(int)x; }
|
||||
public String setr( byte x ) { return "setr(byte) "+x; }
|
||||
public String setr( C x ) { return "setr(C) "; }
|
||||
public String setr( B x ) { return "setr(B) "; }
|
||||
public String setr( A x ) { return "setr(A) "; }
|
||||
public String setr( String x ) { return "setr(String) "+x; }
|
||||
public String setr( Object x ) { return "setr(Object) "; }
|
||||
|
||||
public Object getObject() { return new Object(); }
|
||||
public String getString() { return "abc"; }
|
||||
public byte[] getbytearray() { return new byte[] { 1, 2, 3 }; }
|
||||
public A getA() { return new A(); }
|
||||
public B getB() { return new B(); }
|
||||
public C getC() { return new C(); }
|
||||
public byte getbyte() { return 1; }
|
||||
public char getchar() { return 65000; }
|
||||
public short getshort() { return -32000; }
|
||||
public int getint() { return 100000; }
|
||||
public long getlong() { return 50000000000L; }
|
||||
public float getfloat() { return 6.5f; }
|
||||
public double getdouble() { return Math.PI; }
|
||||
}
|
||||
public static class C extends B implements IC {
|
||||
}
|
||||
public static class D extends C implements IA {
|
||||
}
|
||||
|
||||
public void testOverloadedJavaMethodObject() { doOverloadedMethodTest( "Object", "" ); }
|
||||
public void testOverloadedJavaMethodString() { doOverloadedMethodTest( "String", "abc" ); }
|
||||
public void testOverloadedJavaMethodA() { doOverloadedMethodTest( "A", "" ); }
|
||||
public void testOverloadedJavaMethodB() { doOverloadedMethodTest( "B", "" ); }
|
||||
public void testOverloadedJavaMethodC() { doOverloadedMethodTest( "C", "" ); }
|
||||
public void testOverloadedJavaMethodByte() { doOverloadedMethodTest( "byte", "1" ); }
|
||||
public void testOverloadedJavaMethodChar() { doOverloadedMethodTest( "char", "65000" ); }
|
||||
public void testOverloadedJavaMethodShort() { doOverloadedMethodTest( "short", "-32000" ); }
|
||||
public void testOverloadedJavaMethodInt() { doOverloadedMethodTest( "int", "100000" ); }
|
||||
public void testOverloadedJavaMethodLong() { doOverloadedMethodTest( "long", "50000000000" ); }
|
||||
public void testOverloadedJavaMethodFloat() { doOverloadedMethodTest( "float", "6.5" ); }
|
||||
public void testOverloadedJavaMethodDouble() { doOverloadedMethodTest( "double", "3.141592653589793" ); }
|
||||
|
||||
private void doOverloadedMethodTest( String typename, String value ) {
|
||||
String script =
|
||||
"local a = luajava.newInstance('"+B.class.getName()+"');\n" +
|
||||
"local b = a:set(a:get"+typename+"())\n" +
|
||||
"local c = a:setr(a:get"+typename+"())\n" +
|
||||
"return b,c";
|
||||
Varargs chunk = globals.get("load").call(LuaValue.valueOf(script));
|
||||
if ( ! chunk.arg1().toboolean() )
|
||||
fail( chunk.arg(2).toString() );
|
||||
Varargs results = chunk.arg1().invoke();
|
||||
int nresults = results.narg();
|
||||
assertEquals( 2, nresults );
|
||||
LuaValue b = results.arg(1);
|
||||
LuaValue c = results.arg(2);
|
||||
String sb = b.tojstring();
|
||||
String sc = c.tojstring();
|
||||
assertEquals( "set("+typename+") "+value, sb );
|
||||
assertEquals( "setr("+typename+") "+value, sc );
|
||||
}
|
||||
|
||||
public void testClassInheritanceLevels() {
|
||||
assertEquals( 0, CoerceLuaToJava.inheritanceLevels(Object.class, Object.class) );
|
||||
assertEquals( 1, CoerceLuaToJava.inheritanceLevels(Object.class, String.class) );
|
||||
assertEquals( 1, CoerceLuaToJava.inheritanceLevels(Object.class, A.class) );
|
||||
assertEquals( 2, CoerceLuaToJava.inheritanceLevels(Object.class, B.class) );
|
||||
assertEquals( 3, CoerceLuaToJava.inheritanceLevels(Object.class, C.class) );
|
||||
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(A.class, Object.class) );
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(A.class, String.class) );
|
||||
assertEquals( 0, CoerceLuaToJava.inheritanceLevels(A.class, A.class) );
|
||||
assertEquals( 1, CoerceLuaToJava.inheritanceLevels(A.class, B.class) );
|
||||
assertEquals( 2, CoerceLuaToJava.inheritanceLevels(A.class, C.class) );
|
||||
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(B.class, Object.class) );
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(B.class, String.class) );
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(B.class, A.class) );
|
||||
assertEquals( 0, CoerceLuaToJava.inheritanceLevels(B.class, B.class) );
|
||||
assertEquals( 1, CoerceLuaToJava.inheritanceLevels(B.class, C.class) );
|
||||
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, Object.class) );
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, String.class) );
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, A.class) );
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(C.class, B.class) );
|
||||
assertEquals( 0, CoerceLuaToJava.inheritanceLevels(C.class, C.class) );
|
||||
}
|
||||
|
||||
public void testInterfaceInheritanceLevels() {
|
||||
assertEquals( 1, CoerceLuaToJava.inheritanceLevels(IA.class, A.class) );
|
||||
assertEquals( 1, CoerceLuaToJava.inheritanceLevels(IB.class, B.class) );
|
||||
assertEquals( 2, CoerceLuaToJava.inheritanceLevels(IA.class, B.class) );
|
||||
assertEquals( 1, CoerceLuaToJava.inheritanceLevels(IC.class, C.class) );
|
||||
assertEquals( 2, CoerceLuaToJava.inheritanceLevels(IB.class, C.class) );
|
||||
assertEquals( 3, CoerceLuaToJava.inheritanceLevels(IA.class, C.class) );
|
||||
assertEquals( 1, CoerceLuaToJava.inheritanceLevels(IA.class, D.class) );
|
||||
assertEquals( 2, CoerceLuaToJava.inheritanceLevels(IC.class, D.class) );
|
||||
assertEquals( 3, CoerceLuaToJava.inheritanceLevels(IB.class, D.class) );
|
||||
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IB.class, A.class) );
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IC.class, A.class) );
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IC.class, B.class) );
|
||||
assertEquals( CoerceLuaToJava.SCORE_UNCOERCIBLE, CoerceLuaToJava.inheritanceLevels(IB.class, IA.class) );
|
||||
assertEquals( 1, CoerceLuaToJava.inheritanceLevels(IA.class, IB.class) );
|
||||
}
|
||||
|
||||
public void testCoerceJavaToLuaLuaValue() {
|
||||
assertSame(LuaValue.NIL, CoerceJavaToLua.coerce(LuaValue.NIL));
|
||||
assertSame(LuaValue.ZERO, CoerceJavaToLua.coerce(LuaValue.ZERO));
|
||||
assertSame(LuaValue.ONE, CoerceJavaToLua.coerce(LuaValue.ONE));
|
||||
assertSame(LuaValue.INDEX, CoerceJavaToLua.coerce(LuaValue.INDEX));
|
||||
LuaTable table = LuaValue.tableOf();
|
||||
assertSame(table, CoerceJavaToLua.coerce(table));
|
||||
}
|
||||
|
||||
public void testCoerceJavaToLuaByeArray() {
|
||||
byte[] bytes = "abcd".getBytes();
|
||||
LuaValue value = CoerceJavaToLua.coerce(bytes);
|
||||
assertEquals(LuaString.class, value.getClass());
|
||||
assertEquals(LuaValue.valueOf("abcd"), value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package org.luaj.vm2.lib.jse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.Globals;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
public class LuajavaAccessibleMembersTest extends TestCase {
|
||||
|
||||
private Globals globals;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
globals = JsePlatform.standardGlobals();
|
||||
}
|
||||
|
||||
private String invokeScript(String script) {
|
||||
try {
|
||||
LuaValue c = globals.load(script, "script");
|
||||
return c.call().tojstring();
|
||||
} catch ( Exception e ) {
|
||||
fail("exception: "+e );
|
||||
return "failed";
|
||||
}
|
||||
}
|
||||
|
||||
public void testAccessFromPrivateClassImplementedMethod() {
|
||||
assertEquals("privateImpl-aaa-interface_method(bar)", invokeScript(
|
||||
"b = luajava.newInstance('"+TestClass.class.getName()+"');" +
|
||||
"a = b:create_PrivateImpl('aaa');" +
|
||||
"return a:interface_method('bar');"));
|
||||
}
|
||||
|
||||
public void testAccessFromPrivateClassPublicMethod() {
|
||||
assertEquals("privateImpl-aaa-public_method", invokeScript(
|
||||
"b = luajava.newInstance('"+TestClass.class.getName()+"');" +
|
||||
"a = b:create_PrivateImpl('aaa');" +
|
||||
"return a:public_method();"));
|
||||
}
|
||||
|
||||
public void testAccessFromPrivateClassGetPublicField() {
|
||||
assertEquals("aaa", invokeScript(
|
||||
"b = luajava.newInstance('"+TestClass.class.getName()+"');" +
|
||||
"a = b:create_PrivateImpl('aaa');" +
|
||||
"return a.public_field;"));
|
||||
}
|
||||
|
||||
public void testAccessFromPrivateClassSetPublicField() {
|
||||
assertEquals("foo", invokeScript(
|
||||
"b = luajava.newInstance('"+TestClass.class.getName()+"');" +
|
||||
"a = b:create_PrivateImpl('aaa');" +
|
||||
"a.public_field = 'foo';" +
|
||||
"return a.public_field;"));
|
||||
}
|
||||
|
||||
public void testAccessFromPrivateClassPublicConstructor() {
|
||||
assertEquals("privateImpl-constructor", invokeScript(
|
||||
"b = luajava.newInstance('"+TestClass.class.getName()+"');" +
|
||||
"c = b:get_PrivateImplClass();" +
|
||||
"return luajava.new(c);"));
|
||||
}
|
||||
|
||||
public void testAccessPublicEnum() {
|
||||
assertEquals("class org.luaj.vm2.lib.jse.TestClass$SomeEnum", invokeScript(
|
||||
"b = luajava.newInstance('"+TestClass.class.getName()+"');" +
|
||||
"return b.SomeEnum"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
package org.luaj.vm2.lib.jse;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.LuaError;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
public class LuajavaClassMembersTest extends TestCase {
|
||||
public static class A {
|
||||
protected A() {}
|
||||
}
|
||||
public static class B extends A {
|
||||
public byte m_byte_field;
|
||||
public int m_int_field;
|
||||
public double m_double_field;
|
||||
public String m_string_field;
|
||||
|
||||
protected B() {}
|
||||
public B(int i) { m_int_field = i; }
|
||||
|
||||
public String setString( String x ) { return "setString(String) "+x; }
|
||||
public String getString() { return "abc"; }
|
||||
public int getint() { return 100000; }
|
||||
|
||||
public String uniq() { return "uniq()"; }
|
||||
public String uniqs(String s) { return "uniqs(string:"+s+")"; }
|
||||
public String uniqi(int i) { return "uniqi(int:"+i+")"; }
|
||||
public String uniqsi(String s, int i) { return "uniqsi(string:"+s+",int:"+i+")"; }
|
||||
public String uniqis(int i, String s) { return "uniqis(int:"+i+",string:"+s+")"; }
|
||||
|
||||
public String pick() { return "pick()"; }
|
||||
public String pick(String s) { return "pick(string:"+s+")"; }
|
||||
public String pick(int i) { return "pick(int:"+i+")"; }
|
||||
public String pick(String s, int i) { return "pick(string:"+s+",int:"+i+")"; }
|
||||
public String pick(int i, String s) { return "pick(int:"+i+",string:"+s+")"; }
|
||||
|
||||
public static String staticpick() { return "static-pick()"; }
|
||||
public static String staticpick(String s) { return "static-pick(string:"+s+")"; }
|
||||
public static String staticpick(int i) { return "static-pick(int:"+i+")"; }
|
||||
public static String staticpick(String s, int i) { return "static-pick(string:"+s+",int:"+i+")"; }
|
||||
public static String staticpick(int i, String s) { return "static-pick(int:"+i+",string:"+s+")"; }
|
||||
}
|
||||
public static class C extends B {
|
||||
public C() {}
|
||||
public C(String s) { m_string_field = s; }
|
||||
public C(int i) { m_int_field = i; }
|
||||
public C(String s, int i) { m_string_field = s; m_int_field = i; }
|
||||
public int getint() { return 200000; }
|
||||
|
||||
public String pick(String s) { return "class-c-pick(string:"+s+")"; }
|
||||
public String pick(int i) { return "class-c-pick(int:"+i+")"; }
|
||||
public static class D {
|
||||
public static String name() { return "name-of-D"; }
|
||||
}
|
||||
}
|
||||
|
||||
static LuaValue ZERO = LuaValue.ZERO;
|
||||
static LuaValue ONE = LuaValue.ONE;
|
||||
static LuaValue PI = LuaValue.valueOf(Math.PI);
|
||||
static LuaValue THREE = LuaValue.valueOf(3);
|
||||
static LuaValue NUMS = LuaValue.valueOf(123);
|
||||
static LuaValue ABC = LuaValue.valueOf("abc");
|
||||
static LuaValue SOMEA = CoerceJavaToLua.coerce(new A());
|
||||
static LuaValue SOMEB = CoerceJavaToLua.coerce(new B());
|
||||
static LuaValue SOMEC = CoerceJavaToLua.coerce(new C());
|
||||
|
||||
public void testSetByteField() {
|
||||
B b = new B();
|
||||
JavaInstance i = new JavaInstance(b);
|
||||
i.set("m_byte_field", ONE ); assertEquals( 1, b.m_byte_field ); assertEquals( ONE, i.get("m_byte_field") );
|
||||
i.set("m_byte_field", PI ); assertEquals( 3, b.m_byte_field ); assertEquals( THREE, i.get("m_byte_field") );
|
||||
i.set("m_byte_field", ABC ); assertEquals( 0, b.m_byte_field ); assertEquals( ZERO, i.get("m_byte_field") );
|
||||
}
|
||||
public void testSetDoubleField() {
|
||||
B b = new B();
|
||||
JavaInstance i = new JavaInstance(b);
|
||||
i.set("m_double_field", ONE ); assertEquals( 1., b.m_double_field ); assertEquals( ONE, i.get("m_double_field") );
|
||||
i.set("m_double_field", PI ); assertEquals( Math.PI, b.m_double_field ); assertEquals( PI, i.get("m_double_field") );
|
||||
i.set("m_double_field", ABC ); assertEquals( 0., b.m_double_field ); assertEquals( ZERO, i.get("m_double_field") );
|
||||
}
|
||||
public void testNoFactory() {
|
||||
JavaClass c = JavaClass.forClass(A.class);
|
||||
try {
|
||||
c.call();
|
||||
fail( "did not throw lua error as expected" );
|
||||
} catch ( LuaError e ) {
|
||||
}
|
||||
}
|
||||
public void testUniqueFactoryCoercible() {
|
||||
JavaClass c = JavaClass.forClass(B.class);
|
||||
assertEquals( JavaClass.class, c.getClass() );
|
||||
LuaValue constr = c.get("new");
|
||||
assertEquals( JavaConstructor.class, constr.getClass() );
|
||||
LuaValue v = constr.call(NUMS);
|
||||
Object b = v.touserdata();
|
||||
assertEquals( B.class, b.getClass() );
|
||||
assertEquals( 123, ((B)b).m_int_field );
|
||||
Object b0 = constr.call().touserdata();
|
||||
assertEquals( B.class, b0.getClass() );
|
||||
assertEquals( 0, ((B)b0).m_int_field );
|
||||
}
|
||||
public void testUniqueFactoryUncoercible() {
|
||||
JavaClass f = JavaClass.forClass(B.class);
|
||||
LuaValue constr = f.get("new");
|
||||
assertEquals( JavaConstructor.class, constr.getClass() );
|
||||
try {
|
||||
LuaValue v = constr.call(LuaValue.userdataOf(new Object()));
|
||||
Object b = v.touserdata();
|
||||
// fail( "did not throw lua error as expected" );
|
||||
assertEquals( 0, ((B)b).m_int_field );
|
||||
} catch ( LuaError e ) {
|
||||
}
|
||||
}
|
||||
public void testOverloadedFactoryCoercible() {
|
||||
JavaClass f = JavaClass.forClass(C.class);
|
||||
LuaValue constr = f.get("new");
|
||||
assertEquals( JavaConstructor.Overload.class, constr.getClass() );
|
||||
Object c = constr.call().touserdata();
|
||||
Object ci = constr.call(LuaValue.valueOf(123)).touserdata();
|
||||
Object cs = constr.call(LuaValue.valueOf("abc")).touserdata();
|
||||
Object csi = constr.call( LuaValue.valueOf("def"), LuaValue.valueOf(456) ).touserdata();
|
||||
assertEquals( C.class, c.getClass() );
|
||||
assertEquals( C.class, ci.getClass() );
|
||||
assertEquals( C.class, cs.getClass() );
|
||||
assertEquals( C.class, csi.getClass() );
|
||||
assertEquals( null, ((C)c).m_string_field );
|
||||
assertEquals( 0, ((C)c).m_int_field );
|
||||
assertEquals( "abc", ((C)cs).m_string_field );
|
||||
assertEquals( 0, ((C)cs).m_int_field );
|
||||
assertEquals( null, ((C)ci).m_string_field );
|
||||
assertEquals( 123, ((C)ci).m_int_field );
|
||||
assertEquals( "def", ((C)csi).m_string_field );
|
||||
assertEquals( 456, ((C)csi).m_int_field );
|
||||
}
|
||||
public void testOverloadedFactoryUncoercible() {
|
||||
JavaClass f = JavaClass.forClass(C.class);
|
||||
try {
|
||||
Object c = f.call(LuaValue.userdataOf(new Object()));
|
||||
// fail( "did not throw lua error as expected" );
|
||||
assertEquals( 0, ((C)c).m_int_field );
|
||||
assertEquals( null, ((C)c).m_string_field );
|
||||
} catch ( LuaError e ) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testNoAttribute() {
|
||||
JavaClass f = JavaClass.forClass(A.class);
|
||||
LuaValue v = f.get("bogus");
|
||||
assertEquals( v, LuaValue.NIL );
|
||||
try {
|
||||
f.set("bogus",ONE);
|
||||
fail( "did not throw lua error as expected" );
|
||||
} catch ( LuaError e ) {}
|
||||
}
|
||||
public void testFieldAttributeCoercible() {
|
||||
JavaInstance i = new JavaInstance(new B());
|
||||
i.set("m_int_field", ONE ); assertEquals( 1, i.get("m_int_field").toint() );
|
||||
i.set("m_int_field", THREE ); assertEquals( 3, i.get("m_int_field").toint() );
|
||||
i = new JavaInstance(new C());
|
||||
i.set("m_int_field", ONE ); assertEquals( 1, i.get("m_int_field").toint() );
|
||||
i.set("m_int_field", THREE ); assertEquals( 3, i.get("m_int_field").toint() );
|
||||
}
|
||||
public void testUniqueMethodAttributeCoercible() {
|
||||
B b = new B();
|
||||
JavaInstance ib = new JavaInstance(b);
|
||||
LuaValue b_getString = ib.get("getString");
|
||||
LuaValue b_getint = ib.get("getint");
|
||||
assertEquals( JavaMethod.class, b_getString.getClass() );
|
||||
assertEquals( JavaMethod.class, b_getint.getClass() );
|
||||
assertEquals( "abc", b_getString.call(SOMEB).tojstring() );
|
||||
assertEquals( 100000, b_getint.call(SOMEB).toint());
|
||||
assertEquals( "abc", b_getString.call(SOMEC).tojstring() );
|
||||
assertEquals( 200000, b_getint.call(SOMEC).toint());
|
||||
}
|
||||
public void testUniqueMethodAttributeArgsCoercible() {
|
||||
B b = new B();
|
||||
JavaInstance ib = new JavaInstance(b);
|
||||
LuaValue uniq = ib.get("uniq");
|
||||
LuaValue uniqs = ib.get("uniqs");
|
||||
LuaValue uniqi = ib.get("uniqi");
|
||||
LuaValue uniqsi = ib.get("uniqsi");
|
||||
LuaValue uniqis = ib.get("uniqis");
|
||||
assertEquals( JavaMethod.class, uniq.getClass() );
|
||||
assertEquals( JavaMethod.class, uniqs.getClass() );
|
||||
assertEquals( JavaMethod.class, uniqi.getClass() );
|
||||
assertEquals( JavaMethod.class, uniqsi.getClass() );
|
||||
assertEquals( JavaMethod.class, uniqis.getClass() );
|
||||
assertEquals( "uniq()", uniq.call(SOMEB).tojstring() );
|
||||
assertEquals( "uniqs(string:abc)", uniqs.call(SOMEB,ABC).tojstring() );
|
||||
assertEquals( "uniqi(int:1)", uniqi.call(SOMEB,ONE).tojstring() );
|
||||
assertEquals( "uniqsi(string:abc,int:1)", uniqsi.call(SOMEB,ABC,ONE).tojstring() );
|
||||
assertEquals( "uniqis(int:1,string:abc)", uniqis.call(SOMEB,ONE,ABC).tojstring() );
|
||||
assertEquals( "uniqis(int:1,string:abc)", uniqis.invoke(LuaValue.varargsOf(new LuaValue[] {SOMEB,ONE,ABC,ONE})).arg1().tojstring() );
|
||||
}
|
||||
public void testOverloadedMethodAttributeCoercible() {
|
||||
B b = new B();
|
||||
JavaInstance ib = new JavaInstance(b);
|
||||
LuaValue p = ib.get("pick");
|
||||
assertEquals( "pick()", p.call(SOMEB).tojstring() );
|
||||
assertEquals( "pick(string:abc)", p.call(SOMEB,ABC).tojstring() );
|
||||
assertEquals( "pick(int:1)", p.call(SOMEB,ONE).tojstring() );
|
||||
assertEquals( "pick(string:abc,int:1)", p.call(SOMEB,ABC,ONE).tojstring() );
|
||||
assertEquals( "pick(int:1,string:abc)", p.call(SOMEB,ONE,ABC).tojstring() );
|
||||
assertEquals( "pick(int:1,string:abc)", p.invoke(LuaValue.varargsOf(new LuaValue[] {SOMEB,ONE,ABC,ONE})).arg1().tojstring() );
|
||||
}
|
||||
public void testUnboundOverloadedMethodAttributeCoercible() {
|
||||
B b = new B();
|
||||
JavaInstance ib = new JavaInstance(b);
|
||||
LuaValue p = ib.get("pick");
|
||||
assertEquals( JavaMethod.Overload.class, p.getClass() );
|
||||
assertEquals( "pick()", p.call(SOMEC).tojstring() );
|
||||
assertEquals( "class-c-pick(string:abc)", p.call(SOMEC,ABC).tojstring() );
|
||||
assertEquals( "class-c-pick(int:1)", p.call(SOMEC,ONE).tojstring() );
|
||||
assertEquals( "pick(string:abc,int:1)", p.call(SOMEC,ABC,ONE).tojstring() );
|
||||
assertEquals( "pick(int:1,string:abc)", p.call(SOMEC,ONE,ABC).tojstring() );
|
||||
assertEquals( "pick(int:1,string:abc)", p.invoke(LuaValue.varargsOf(new LuaValue[] {SOMEC,ONE,ABC,ONE})).arg1().tojstring() );
|
||||
}
|
||||
public void testOverloadedStaticMethodAttributeCoercible() {
|
||||
B b = new B();
|
||||
JavaInstance ib = new JavaInstance(b);
|
||||
LuaValue p = ib.get("staticpick");
|
||||
assertEquals( "static-pick()", p.call(SOMEB).tojstring() );
|
||||
assertEquals( "static-pick(string:abc)", p.call(SOMEB,ABC).tojstring() );
|
||||
assertEquals( "static-pick(int:1)", p.call(SOMEB,ONE).tojstring() );
|
||||
assertEquals( "static-pick(string:abc,int:1)", p.call(SOMEB,ABC,ONE).tojstring() );
|
||||
assertEquals( "static-pick(int:1,string:abc)", p.call(SOMEB,ONE,ABC).tojstring() );
|
||||
assertEquals( "static-pick(int:1,string:abc)", p.invoke(LuaValue.varargsOf(new LuaValue[] {SOMEB,ONE,ABC,ONE})).arg1().tojstring() );
|
||||
}
|
||||
public void testGetInnerClass() {
|
||||
C c = new C();
|
||||
JavaInstance ic = new JavaInstance(c);
|
||||
LuaValue d = ic.get("D");
|
||||
assertFalse(d.isnil());
|
||||
assertSame(d, JavaClass.forClass(C.D.class));
|
||||
LuaValue e = ic.get("E");
|
||||
assertTrue(e.isnil());
|
||||
}
|
||||
}
|
||||
78
luaj-test/src/test/java/org/luaj/vm2/lib/jse/OsLibTest.java
Normal file
78
luaj-test/src/test/java/org/luaj/vm2/lib/jse/OsLibTest.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package org.luaj.vm2.lib.jse;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.OsLib;
|
||||
import org.luaj.vm2.lib.jme.JmePlatform;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class OsLibTest extends TestCase {
|
||||
|
||||
LuaValue jme_lib;
|
||||
LuaValue jse_lib;
|
||||
double time;
|
||||
|
||||
public void setUp() {
|
||||
jse_lib = JsePlatform.standardGlobals().get("os");;
|
||||
jme_lib = JmePlatform.standardGlobals().get("os");;
|
||||
time = new java.util.Date(2001-1900, 7, 23, 14, 55, 02).getTime() / 1000.0;
|
||||
}
|
||||
|
||||
void t(String format, String expected) {
|
||||
String actual = jme_lib.get("date").call(LuaValue.valueOf(format), LuaValue.valueOf(time)).tojstring();
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
public void testStringDateChars() { t("foo", "foo"); }
|
||||
public void testStringDate_a() { t("%a", "Thu"); }
|
||||
public void testStringDate_A() { t("%A", "Thursday"); }
|
||||
public void testStringDate_b() { t("%b", "Aug"); }
|
||||
public void testStringDate_B() { t("%B", "August"); }
|
||||
public void testStringDate_c() { t("%c", "Thu Aug 23 14:55:02 2001"); }
|
||||
public void testStringDate_d() { t("%d", "23"); }
|
||||
public void testStringDate_H() { t("%H", "14"); }
|
||||
public void testStringDate_I() { t("%I", "02"); }
|
||||
public void testStringDate_j() { t("%j", "235"); }
|
||||
public void testStringDate_m() { t("%m", "08"); }
|
||||
public void testStringDate_M() { t("%M", "55"); }
|
||||
public void testStringDate_p() { t("%p", "PM"); }
|
||||
public void testStringDate_S() { t("%S", "02"); }
|
||||
public void testStringDate_U() { t("%U", "33"); }
|
||||
public void testStringDate_w() { t("%w", "4"); }
|
||||
public void testStringDate_W() { t("%W", "34"); }
|
||||
public void testStringDate_x() { t("%x", "08/23/01"); }
|
||||
public void testStringDate_X() { t("%X", "14:55:02"); }
|
||||
public void testStringDate_y() { t("%y", "01"); }
|
||||
public void testStringDate_Y() { t("%Y", "2001"); }
|
||||
public void testStringDate_Pct() { t("%%", "%"); }
|
||||
|
||||
static final double DAY = 24. * 3600.;
|
||||
public void testStringDate_UW_neg4() { time-=4*DAY; t("%c %U %W", "Sun Aug 19 14:55:02 2001 33 33"); }
|
||||
public void testStringDate_UW_neg3() { time-=3*DAY; t("%c %U %W", "Mon Aug 20 14:55:02 2001 33 34"); }
|
||||
public void testStringDate_UW_neg2() { time-=2*DAY; t("%c %U %W", "Tue Aug 21 14:55:02 2001 33 34"); }
|
||||
public void testStringDate_UW_neg1() { time-=DAY; t("%c %U %W", "Wed Aug 22 14:55:02 2001 33 34"); }
|
||||
public void testStringDate_UW_pos0() { time+=0; t("%c %U %W", "Thu Aug 23 14:55:02 2001 33 34"); }
|
||||
public void testStringDate_UW_pos1() { time+=DAY; t("%c %U %W", "Fri Aug 24 14:55:02 2001 33 34"); }
|
||||
public void testStringDate_UW_pos2() { time+=2*DAY; t("%c %U %W", "Sat Aug 25 14:55:02 2001 33 34"); }
|
||||
public void testStringDate_UW_pos3() { time+=3*DAY; t("%c %U %W", "Sun Aug 26 14:55:02 2001 34 34"); }
|
||||
public void testStringDate_UW_pos4() { time+=4*DAY; t("%c %U %W", "Mon Aug 27 14:55:02 2001 34 35"); }
|
||||
|
||||
public void testJseOsGetenvForEnvVariables() {
|
||||
LuaValue USER = LuaValue.valueOf("USER");
|
||||
LuaValue jse_user = jse_lib.get("getenv").call(USER);
|
||||
LuaValue jme_user = jme_lib.get("getenv").call(USER);
|
||||
assertFalse(jse_user.isnil());
|
||||
assertTrue(jme_user.isnil());
|
||||
System.out.println("User: " + jse_user);
|
||||
}
|
||||
|
||||
public void testJseOsGetenvForSystemProperties() {
|
||||
System.setProperty("test.key.foo", "test.value.bar");
|
||||
LuaValue key = LuaValue.valueOf("test.key.foo");
|
||||
LuaValue value = LuaValue.valueOf("test.value.bar");
|
||||
LuaValue jse_value = jse_lib.get("getenv").call(key);
|
||||
LuaValue jme_value = jme_lib.get("getenv").call(key);
|
||||
assertEquals(value, jse_value);
|
||||
assertEquals(value, jme_value);
|
||||
}
|
||||
}
|
||||
22
luaj-test/src/test/java/org/luaj/vm2/lib/jse/TestClass.java
Normal file
22
luaj-test/src/test/java/org/luaj/vm2/lib/jse/TestClass.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package org.luaj.vm2.lib.jse;
|
||||
|
||||
public class TestClass {
|
||||
private static class PrivateImpl implements TestInterface {
|
||||
public String public_field;
|
||||
public PrivateImpl() {
|
||||
this.public_field = "privateImpl-constructor";
|
||||
}
|
||||
PrivateImpl(String f) {
|
||||
this.public_field = f;
|
||||
}
|
||||
public String public_method() { return "privateImpl-"+public_field+"-public_method"; }
|
||||
public String interface_method(String x) { return "privateImpl-"+public_field+"-interface_method("+x+")"; }
|
||||
public String toString() { return public_field; }
|
||||
}
|
||||
public TestInterface create_PrivateImpl(String f) { return new PrivateImpl(f); }
|
||||
public Class get_PrivateImplClass() { return PrivateImpl.class; }
|
||||
public enum SomeEnum {
|
||||
ValueOne,
|
||||
ValueTwo,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package org.luaj.vm2.lib.jse;
|
||||
|
||||
public interface TestInterface {
|
||||
String interface_method(String x);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.luaj.vm2.require;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
/**
|
||||
* This should fail while trying to load via "require() because it is not a LibFunction"
|
||||
*
|
||||
*/
|
||||
public class RequireSampleClassCastExcep {
|
||||
|
||||
public RequireSampleClassCastExcep() {
|
||||
}
|
||||
|
||||
public LuaValue call() {
|
||||
return LuaValue.valueOf("require-sample-class-cast-excep");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.luaj.vm2.require;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
||||
|
||||
/**
|
||||
* This should fail while trying to load via
|
||||
* "require()" because it throws a LuaError
|
||||
*
|
||||
*/
|
||||
public class RequireSampleLoadLuaError extends ZeroArgFunction {
|
||||
|
||||
public RequireSampleLoadLuaError() {
|
||||
}
|
||||
|
||||
public LuaValue call() {
|
||||
error("sample-load-lua-error");
|
||||
return LuaValue.valueOf("require-sample-load-lua-error");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.luaj.vm2.require;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
||||
|
||||
/**
|
||||
* This should fail while trying to load via "require()" because it throws a RuntimeException
|
||||
*
|
||||
*/
|
||||
public class RequireSampleLoadRuntimeExcep extends ZeroArgFunction {
|
||||
|
||||
public RequireSampleLoadRuntimeExcep() {
|
||||
}
|
||||
|
||||
public LuaValue call() {
|
||||
throw new RuntimeException("sample-load-runtime-exception");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.luaj.vm2.require;
|
||||
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.TwoArgFunction;
|
||||
|
||||
/**
|
||||
* This should succeed as a library that can be loaded dynamically via "require()"
|
||||
*/
|
||||
public class RequireSampleSuccess extends TwoArgFunction {
|
||||
|
||||
public RequireSampleSuccess() {
|
||||
}
|
||||
|
||||
public LuaValue call(LuaValue modname, LuaValue env) {
|
||||
env.checkglobals();
|
||||
return LuaValue.valueOf("require-sample-success-"+modname.tojstring());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2013 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.script;
|
||||
|
||||
import java.io.CharArrayReader;
|
||||
import java.io.CharArrayWriter;
|
||||
import java.io.Reader;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.Compilable;
|
||||
import javax.script.CompiledScript;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import javax.script.SimpleBindings;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.luaj.vm2.LuaFunction;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
import org.luaj.vm2.lib.OneArgFunction;
|
||||
|
||||
public class ScriptEngineTests extends TestSuite {
|
||||
|
||||
public static TestSuite suite() {
|
||||
TestSuite suite = new TestSuite("Script Engine Tests");
|
||||
suite.addTest( new TestSuite( LookupEngineTestCase.class, "Lookup Engine" ) );
|
||||
suite.addTest( new TestSuite( DefaultBindingsTest.class, "Default Bindings" ) );
|
||||
suite.addTest( new TestSuite( SimpleBindingsTest.class, "Simple Bindings" ) );
|
||||
suite.addTest( new TestSuite( CompileClosureTest.class, "Compile Closure" ) );
|
||||
suite.addTest( new TestSuite( CompileNonClosureTest.class, "Compile NonClosure" ) );
|
||||
suite.addTest( new TestSuite( UserContextTest.class, "User Context" ) );
|
||||
suite.addTest( new TestSuite( WriterTest.class, "Writer" ) );
|
||||
return suite;
|
||||
}
|
||||
|
||||
public static class LookupEngineTestCase extends TestCase {
|
||||
public void testGetEngineByExtension() {
|
||||
ScriptEngine e = new ScriptEngineManager().getEngineByExtension(".lua");
|
||||
assertNotNull(e);
|
||||
assertEquals(LuaScriptEngine.class, e.getClass());
|
||||
}
|
||||
public void testGetEngineByName() {
|
||||
ScriptEngine e = new ScriptEngineManager().getEngineByName("luaj");
|
||||
assertNotNull(e);
|
||||
assertEquals(LuaScriptEngine.class, e.getClass());
|
||||
}
|
||||
public void testGetEngineByMimeType() {
|
||||
ScriptEngine e = new ScriptEngineManager().getEngineByMimeType("text/lua");
|
||||
assertNotNull(e);
|
||||
assertEquals(LuaScriptEngine.class, e.getClass());
|
||||
}
|
||||
public void testFactoryMetadata() {
|
||||
ScriptEngine e = new ScriptEngineManager().getEngineByName("luaj");
|
||||
ScriptEngineFactory f = e.getFactory();
|
||||
assertEquals("Luaj", f.getEngineName());
|
||||
assertEquals("Luaj 0.0", f.getEngineVersion());
|
||||
assertEquals("lua", f.getLanguageName());
|
||||
assertEquals("5.2", f.getLanguageVersion());
|
||||
}
|
||||
}
|
||||
|
||||
public static class DefaultBindingsTest extends EngineTestCase {
|
||||
protected Bindings createBindings() {
|
||||
return e.createBindings();
|
||||
}
|
||||
}
|
||||
|
||||
public static class SimpleBindingsTest extends EngineTestCase {
|
||||
protected Bindings createBindings() {
|
||||
return new SimpleBindings();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompileClosureTest extends DefaultBindingsTest {
|
||||
protected void setUp() throws Exception {
|
||||
System.setProperty("org.luaj.luajc", "false");
|
||||
super.setUp();
|
||||
}
|
||||
public void testCompiledFunctionIsClosure() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("return 'foo'");
|
||||
LuaValue value = ((LuaScriptEngine.LuajCompiledScript)cs).function;
|
||||
assertTrue(value.isclosure());
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompileNonClosureTest extends DefaultBindingsTest {
|
||||
protected void setUp() throws Exception {
|
||||
System.setProperty("org.luaj.luajc", "true");
|
||||
super.setUp();
|
||||
}
|
||||
public void testCompiledFunctionIsNotClosure() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("return 'foo'");
|
||||
LuaValue value = ((LuaScriptEngine.LuajCompiledScript)cs).function;
|
||||
assertFalse(value.isclosure());
|
||||
}
|
||||
}
|
||||
|
||||
abstract public static class EngineTestCase extends TestCase {
|
||||
protected ScriptEngine e;
|
||||
protected Bindings b;
|
||||
abstract protected Bindings createBindings();
|
||||
protected void setUp() throws Exception {
|
||||
this.e = new ScriptEngineManager().getEngineByName("luaj");
|
||||
this.b = createBindings();
|
||||
}
|
||||
public void testSqrtIntResult() throws ScriptException {
|
||||
e.put("x", 25);
|
||||
e.eval("y = math.sqrt(x)");
|
||||
Object y = e.get("y");
|
||||
assertEquals(5, y);
|
||||
}
|
||||
public void testOneArgFunction() throws ScriptException {
|
||||
e.put("x", 25);
|
||||
e.eval("y = math.sqrt(x)");
|
||||
Object y = e.get("y");
|
||||
assertEquals(5, y);
|
||||
e.put("f", new OneArgFunction() {
|
||||
public LuaValue call(LuaValue arg) {
|
||||
return LuaValue.valueOf(arg.toString()+"123");
|
||||
}
|
||||
});
|
||||
Object r = e.eval("return f('abc')");
|
||||
assertEquals("abc123", r);
|
||||
}
|
||||
public void testCompiledScript() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("y = math.sqrt(x); return y");
|
||||
b.put("x", 144);
|
||||
assertEquals(12, cs.eval(b));
|
||||
}
|
||||
public void testBuggyLuaScript() {
|
||||
try {
|
||||
e.eval("\n\nbuggy lua code\n\n");
|
||||
} catch ( ScriptException se ) {
|
||||
assertEquals("eval threw javax.script.ScriptException: [string \"script\"]:3: syntax error", se.getMessage());
|
||||
return;
|
||||
}
|
||||
fail("buggy script did not throw ScriptException as expected.");
|
||||
}
|
||||
public void testScriptRedirection() throws ScriptException {
|
||||
Reader input = new CharArrayReader("abcdefg\nhijk".toCharArray());
|
||||
CharArrayWriter output = new CharArrayWriter();
|
||||
CharArrayWriter errors = new CharArrayWriter();
|
||||
String script =
|
||||
"print(\"string written using 'print'\")\n" +
|
||||
"io.write(\"string written using 'io.write()'\\n\")\n" +
|
||||
"io.stdout:write(\"string written using 'io.stdout:write()'\\n\")\n" +
|
||||
"io.stderr:write(\"string written using 'io.stderr:write()'\\n\")\n" +
|
||||
"io.write([[string read using 'io.stdin:read(\"*l\")':]]..io.stdin:read(\"*l\")..\"\\n\")\n";
|
||||
|
||||
// Evaluate script with redirection set
|
||||
e.getContext().setReader(input);
|
||||
e.getContext().setWriter(output);
|
||||
e.getContext().setErrorWriter(errors);
|
||||
e.eval(script);
|
||||
final String expectedOutput = "string written using 'print'\n"+
|
||||
"string written using 'io.write()'\n"+
|
||||
"string written using 'io.stdout:write()'\n"+
|
||||
"string read using 'io.stdin:read(\"*l\")':abcdefg\n";
|
||||
assertEquals(expectedOutput, output.toString());
|
||||
final String expectedErrors = "string written using 'io.stderr:write()'\n";
|
||||
assertEquals(expectedErrors, errors.toString());
|
||||
|
||||
// Evaluate script with redirection reset
|
||||
output.reset();
|
||||
errors.reset();
|
||||
// e.getContext().setReader(null); // This will block if using actual STDIN
|
||||
e.getContext().setWriter(null);
|
||||
e.getContext().setErrorWriter(null);
|
||||
e.eval(script);
|
||||
assertEquals("", output.toString());
|
||||
assertEquals("", errors.toString());
|
||||
}
|
||||
public void testBindingJavaInt() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("y = x; return 'x '..type(x)..' '..tostring(x)\n");
|
||||
b.put("x", 111);
|
||||
assertEquals("x number 111", cs.eval(b));
|
||||
assertEquals(111, b.get("y"));
|
||||
}
|
||||
public void testBindingJavaDouble() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("y = x; return 'x '..type(x)..' '..tostring(x)\n");
|
||||
b.put("x", 125.125);
|
||||
assertEquals("x number 125.125", cs.eval(b));
|
||||
assertEquals(125.125, b.get("y"));
|
||||
}
|
||||
public void testBindingJavaString() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("y = x; return 'x '..type(x)..' '..tostring(x)\n");
|
||||
b.put("x", "foo");
|
||||
assertEquals("x string foo", cs.eval(b));
|
||||
assertEquals("foo", b.get("y"));
|
||||
}
|
||||
public void testBindingJavaObject() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("y = x; return 'x '..type(x)..' '..tostring(x)\n");
|
||||
b.put("x", new SomeUserClass());
|
||||
assertEquals("x userdata some-user-value", cs.eval(b));
|
||||
assertEquals(SomeUserClass.class, b.get("y").getClass());
|
||||
}
|
||||
public void testBindingJavaArray() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("y = x; return 'x '..type(x)..' '..#x..' '..x[1]..' '..x[2]\n");
|
||||
b.put("x", new int[] { 777, 888 });
|
||||
assertEquals("x userdata 2 777 888", cs.eval(b));
|
||||
assertEquals(int[].class, b.get("y").getClass());
|
||||
}
|
||||
public void testBindingLuaFunction() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("y = function(x) return 678 + x end; return 'foo'");
|
||||
assertEquals("foo", cs.eval(b).toString());
|
||||
assertTrue(b.get("y") instanceof LuaFunction);
|
||||
assertEquals(LuaValue.valueOf(801), ((LuaFunction) b.get("y")).call(LuaValue.valueOf(123)));
|
||||
}
|
||||
public void testUserClasses() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile(
|
||||
"x = x or luajava.newInstance('java.lang.String', 'test')\n" +
|
||||
"return 'x ' .. type(x) .. ' ' .. tostring(x)\n");
|
||||
assertEquals("x string test", cs.eval(b));
|
||||
b.put("x", new SomeUserClass());
|
||||
assertEquals("x userdata some-user-value", cs.eval(b));
|
||||
}
|
||||
public void testReturnMultipleValues() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("return 'foo', 'bar'\n");
|
||||
Object o = cs.eval();
|
||||
assertEquals(Object[].class, o.getClass());
|
||||
Object[] array = (Object[]) o;
|
||||
assertEquals(2, array.length);
|
||||
assertEquals("foo", array[0]);
|
||||
assertEquals("bar", array[1]);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SomeUserClass {
|
||||
public String toString() {
|
||||
return "some-user-value";
|
||||
}
|
||||
}
|
||||
|
||||
public static class UserContextTest extends TestCase {
|
||||
protected ScriptEngine e;
|
||||
protected Bindings b;
|
||||
protected ScriptContext c;
|
||||
public void setUp() {
|
||||
this.e = new ScriptEngineManager().getEngineByName("luaj");
|
||||
this.c = new LuajContext();
|
||||
this.b = c.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
}
|
||||
public void testUncompiledScript() throws ScriptException {
|
||||
b.put("x", 144);
|
||||
assertEquals(12, e.eval("z = math.sqrt(x); return z", b));
|
||||
assertEquals(12, b.get("z"));
|
||||
assertEquals(null, e.getBindings(ScriptContext.ENGINE_SCOPE).get("z"));
|
||||
assertEquals(null, e.getBindings(ScriptContext.GLOBAL_SCOPE).get("z"));
|
||||
|
||||
b.put("x", 25);
|
||||
assertEquals(5, e.eval("z = math.sqrt(x); return z", c));
|
||||
assertEquals(5, b.get("z"));
|
||||
assertEquals(null, e.getBindings(ScriptContext.ENGINE_SCOPE).get("z"));
|
||||
assertEquals(null, e.getBindings(ScriptContext.GLOBAL_SCOPE).get("z"));
|
||||
}
|
||||
public void testCompiledScript() throws ScriptException {
|
||||
CompiledScript cs = ((Compilable)e).compile("z = math.sqrt(x); return z");
|
||||
|
||||
b.put("x", 144);
|
||||
assertEquals(12, cs.eval(b));
|
||||
assertEquals(12, b.get("z"));
|
||||
|
||||
b.put("x", 25);
|
||||
assertEquals(5, cs.eval(c));
|
||||
assertEquals(5, b.get("z"));
|
||||
}
|
||||
}
|
||||
|
||||
public static class WriterTest extends TestCase {
|
||||
protected ScriptEngine e;
|
||||
protected Bindings b;
|
||||
public void setUp() {
|
||||
this.e = new ScriptEngineManager().getEngineByName("luaj");
|
||||
this.b = e.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
}
|
||||
public void testWriter() throws ScriptException {
|
||||
CharArrayWriter output = new CharArrayWriter();
|
||||
CharArrayWriter errors = new CharArrayWriter();
|
||||
e.getContext().setWriter(output);
|
||||
e.getContext().setErrorWriter(errors);
|
||||
e.eval("io.write( [[line]] )");
|
||||
assertEquals("line", output.toString());
|
||||
e.eval("io.write( [[ one\nline two\n]] )");
|
||||
assertEquals("line one\nline two\n", output.toString());
|
||||
output.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
277
luaj-test/src/test/resources/baselib.lua
Normal file
277
luaj-test/src/test/resources/baselib.lua
Normal file
@@ -0,0 +1,277 @@
|
||||
|
||||
-- tostring replacement that assigns ids
|
||||
local ts,id,nid,types = tostring,{},0,{table='tbl',thread='thr',userdata='uda',['function']='func'}
|
||||
tostring = function(x)
|
||||
if not x or not types[type(x)] then return ts(x) end
|
||||
if not id[x] then nid=nid+1; id[x]=types[type(x)]..'.'..nid end
|
||||
return id[x]
|
||||
end
|
||||
|
||||
-- wrap pcall to return one result
|
||||
-- error message are tested elsewhere
|
||||
local pc = pcall
|
||||
local pcall = function(...)
|
||||
local s,e = pc(...)
|
||||
if s then return e end
|
||||
return false, type(e)
|
||||
end
|
||||
|
||||
-- print
|
||||
print()
|
||||
print(11)
|
||||
print("abc",123,nil,"pqr")
|
||||
print( nil and 'T' or 'F' )
|
||||
print( false and 'T' or 'F' )
|
||||
print( 0 and 'T' or 'F' )
|
||||
|
||||
-- assert
|
||||
print( 'assert(true)', assert(true) )
|
||||
print( 'pcall(assert,true)', pcall(assert,true) )
|
||||
print( 'pcall(assert,false)', pcall(assert,false) )
|
||||
print( 'pcall(assert,nil)', pcall(assert,nil) )
|
||||
print( 'pcall(assert,true,"msg")', pcall(assert,true,"msg") )
|
||||
print( 'pcall(assert,false,"msg")', pcall(assert,false,"msg") )
|
||||
print( 'pcall(assert,nil,"msg")', pcall(assert,nil,"msg") )
|
||||
print( 'pcall(assert,false,"msg","msg2")', pcall(assert,false,"msg","msg2") )
|
||||
|
||||
-- collectgarbage (not supported)
|
||||
print( 'collectgarbage("count")', type(collectgarbage("count")))
|
||||
print( 'collectgarbage("collect")', type(collectgarbage("collect")))
|
||||
print( 'collectgarbage("count")', type(collectgarbage("count")))
|
||||
|
||||
-- dofile (not supported)
|
||||
-- ipairs
|
||||
print( 'pcall(ipairs)', pcall(ipairs) )
|
||||
print( 'pcall(ipairs,nil)', pcall(ipairs,nil) )
|
||||
print( 'pcall(ipairs,"a")', pcall(ipairs,"a") )
|
||||
print( 'pcall(ipairs,1)', pcall(ipairs,1) )
|
||||
for k,v in ipairs({}) do print('ipairs1',k,v)end
|
||||
for k,v in ipairs({'one','two'}) do print('ipairs2',k,v)end
|
||||
for k,v in ipairs({aa='aaa',bb='bbb'}) do print('ipairs3',k,v)end
|
||||
for k,v in ipairs({aa='aaa',bb='bbb','one','two'}) do print('ipairs4',k,v)end
|
||||
for k,v in ipairs({[30]='30',[20]='20'}) do print('ipairs5',k,v)end
|
||||
|
||||
-- load
|
||||
t = { "print ", "'table ", "loaded'", "", " print'after empty string'" }
|
||||
i = 0
|
||||
f = function() i = i + 1; return t[i]; end
|
||||
c,e = load(f)
|
||||
if c then print('load: ', pcall(c)) else print('load failed:', e) end
|
||||
|
||||
-- loadfile
|
||||
-- load
|
||||
local lst = "print(3+4); return 8"
|
||||
local chunk, err = load( lst )
|
||||
print( 'load("'..lst..'")', chunk, err )
|
||||
print( 'load("'..lst..'")()', chunk() )
|
||||
|
||||
-- pairs
|
||||
print( 'pcall(pairs)', pcall(pairs) )
|
||||
print( 'pcall(pairs,nil)', pcall(pairs,nil) )
|
||||
print( 'pcall(pairs,"a")', pcall(pairs,"a") )
|
||||
print( 'pcall(pairs,1)', pcall(pairs,1) )
|
||||
for k,v in pairs({}) do print('pairs1',k,v)end
|
||||
for k,v in pairs({'one','two'}) do print('pairs2',k,v)end
|
||||
for k,v in pairs({aa='aaa'}) do print('pairs3',k,v)end
|
||||
for k,v in pairs({aa='aaa','one','two'}) do print('pairs4',k,v)end
|
||||
for k,v in pairs({[20]='30',[30]='20'}) do print('pairs5',k,v)end
|
||||
|
||||
-- _G
|
||||
print( '_G["abc"] (before)', _G["abc"] )
|
||||
abc='def'
|
||||
print( '_G["abc"] (after)', _G["abc"] )
|
||||
|
||||
-- type
|
||||
print( 'type(nil)', type(nil) )
|
||||
print( 'type("a")', type("a") )
|
||||
print( 'type(1)', type(1) )
|
||||
print( 'type(1.5)', type(1.5) )
|
||||
print( 'type(function() end)', type(function() end) )
|
||||
print( 'type({})', type({}) )
|
||||
print( 'type(true)', type(true) )
|
||||
print( 'type(false)', type(false) )
|
||||
print( 'pcall(type,type)', pcall(type,type) )
|
||||
print( 'pcall(type)', pcall(type) )
|
||||
print( '(function() return pcall(type) end)()', (function() return pcall(type) end)() )
|
||||
local function la() return pcall(type) end
|
||||
print( 'la()', la() )
|
||||
function ga() return pcall(type) end
|
||||
print( 'ga()', ga() )
|
||||
|
||||
-- getmetatable, setmetatable
|
||||
ta = { aa1="aaa1", aa2="aaa2" }
|
||||
tb = { bb1="bbb1", bb2="bbb2" }
|
||||
print( 'getmetatable(ta)', getmetatable(ta) )
|
||||
print( 'getmetatable(tb)', getmetatable(tb) )
|
||||
print( 'setmetatable(ta),{cc1="ccc1"}', type( setmetatable(ta,{cc1="ccc1"}) ) )
|
||||
print( 'setmetatable(tb),{dd1="ddd1"}', type( setmetatable(tb,{dd1="ddd1"}) ) )
|
||||
print( 'getmetatable(ta)["cc1"]', getmetatable(ta)["cc1"] )
|
||||
print( 'getmetatable(tb)["dd1"]', getmetatable(tb)["dd1"] )
|
||||
print( 'getmetatable(1)', getmetatable(1) )
|
||||
print( 'pcall(setmetatable,1)', pcall(setmetatable,1) )
|
||||
print( 'pcall(setmetatable,nil)', pcall(setmetatable,nil) )
|
||||
print( 'pcall(setmetatable,"ABC")', pcall(setmetatable,"ABC") )
|
||||
print( 'pcall(setmetatable,function() end)', pcall(setmetatable,function() end) )
|
||||
|
||||
-- rawget,rawset
|
||||
local mt = {aa="aaa", bb="bbb"}
|
||||
mt.__index = mt
|
||||
mt.__newindex = mt
|
||||
local s = {cc="ccc", dd="ddd", }
|
||||
local t = {cc="ccc", dd="ddd"}
|
||||
setmetatable(t,mt)
|
||||
print( 'pcall(rawget)', pcall(rawget))
|
||||
print( 'pcall(rawget,"a")', pcall(rawget,"a"))
|
||||
print( 'pcall(rawget,s)', pcall(rawget,s))
|
||||
print( 'pcall(rawget,t)', pcall(rawget,t))
|
||||
|
||||
function printtables()
|
||||
function printtable(name,t)
|
||||
print( ' '..name, t["aa"], t["bb"], t["cc"], t["dd"], t["ee"], t["ff"], t["gg"] )
|
||||
print( ' '..name,
|
||||
rawget(t,"aa"),
|
||||
rawget(t,"bb"),
|
||||
rawget(t,"cc"),
|
||||
rawget(t,"dd"),
|
||||
rawget(t,"ee"),
|
||||
rawget(t,"ff"),
|
||||
rawget(t,"gg") )
|
||||
end
|
||||
printtable( 's', s )
|
||||
printtable( 't', t )
|
||||
printtable( 'mt', mt )
|
||||
end
|
||||
printtables()
|
||||
print( 'pcall(rawset,s,"aa","www")', rawset(s,"aa","www"))
|
||||
printtables()
|
||||
print( 'pcall(rawset,s,"cc","xxx")', rawset(s,"cc","xxx"))
|
||||
printtables()
|
||||
print( 'pcall(rawset,t,"aa","yyy")', rawset(t,"aa","yyy"))
|
||||
printtables()
|
||||
print( 'pcall(rawset,t,"dd","zzz")', rawset(t,"dd","zzz"))
|
||||
printtables()
|
||||
|
||||
-- rawlen
|
||||
print( 'pcall(rawlen, {})', pcall(rawlen, {}))
|
||||
print( 'pcall(rawlen, {"a"})', pcall(rawlen, {'a'}))
|
||||
print( 'pcall(rawlen, {"a","b"})', pcall(rawlen, {'a','b'}))
|
||||
print( 'pcall(rawlen, "")', pcall(rawlen, ""))
|
||||
print( 'pcall(rawlen, "a")', pcall(rawlen, 'a'))
|
||||
print( 'pcall(rawlen, "ab")', pcall(rawlen, 'ab'))
|
||||
print( 'pcall(rawlen, 1)', pcall(rawlen, 1))
|
||||
print( 'pcall(rawlen, nil)', pcall(rawlen, nil))
|
||||
print( 'pcall(rawlen)', pcall(rawlen))
|
||||
|
||||
printtables()
|
||||
print( 's["ee"]="ppp"' ); s["ee"]="ppp"
|
||||
printtables()
|
||||
print( 's["cc"]="qqq"' ); s["cc"]="qqq"
|
||||
printtables()
|
||||
print( 't["ff"]="rrr"' ); t["ff"]="rrr"
|
||||
printtables()
|
||||
print( 't["dd"]="sss"' ); t["dd"]="sss"
|
||||
printtables()
|
||||
print( 'mt["gg"]="ttt"' ); mt["gg"]="ttt"
|
||||
printtables()
|
||||
|
||||
|
||||
-- select
|
||||
print( 'pcall(select)', pcall(select) )
|
||||
print( 'select(1,11,22,33,44,55)', select(1,11,22,33,44,55) )
|
||||
print( 'select(2,11,22,33,44,55)', select(2,11,22,33,44,55) )
|
||||
print( 'select(3,11,22,33,44,55)', select(3,11,22,33,44,55) )
|
||||
print( 'select(4,11,22,33,44,55)', select(4,11,22,33,44,55) )
|
||||
print( 'pcall(select,5,11,22,33,44,55)', pcall(select,5,11,22,33,44,55) )
|
||||
print( 'pcall(select,6,11,22,33,44,55)', pcall(select,6,11,22,33,44,55) )
|
||||
print( 'pcall(select,7,11,22,33,44,55)', pcall(select,7,11,22,33,44,55) )
|
||||
print( 'pcall(select,0,11,22,33,44,55)', pcall(select,0,11,22,33,44,55) )
|
||||
print( 'pcall(select,-1,11,22,33,44,55)', pcall(select,-1,11,22,33,44,55) )
|
||||
print( 'pcall(select,-2,11,22,33,44,55)', pcall(select,-2,11,22,33,44,55) )
|
||||
print( 'pcall(select,-4,11,22,33,44,55)', pcall(select,-4,11,22,33,44,55) )
|
||||
print( 'pcall(select,-5,11,22,33,44,55)', pcall(select,-5,11,22,33,44,55) )
|
||||
print( 'pcall(select,-6,11,22,33,44,55)', pcall(select,-6,11,22,33,44,55) )
|
||||
print( 'pcall(select,1)', pcall(select,1) )
|
||||
print( 'pcall(select,select)', pcall(select,select) )
|
||||
print( 'pcall(select,{})', pcall(select,{}) )
|
||||
print( 'pcall(select,"2",11,22,33)', pcall(select,"2",11,22,33) )
|
||||
print( 'pcall(select,"abc",11,22,33)', pcall(select,"abc",11,22,33) )
|
||||
|
||||
|
||||
-- tonumber
|
||||
print( 'pcall(tonumber)', pcall(tostring) )
|
||||
print( 'pcall(tonumber,nil)', pcall(tonumber,nil) )
|
||||
print( 'pcall(tonumber,"abc")', pcall(tonumber,"abc") )
|
||||
print( 'pcall(tonumber,"123")', pcall(tonumber,"123") )
|
||||
print( 'pcall(tonumber,"123",10)', pcall(tonumber,"123", 10) )
|
||||
print( 'pcall(tonumber,"123",8)', pcall(tonumber,"123", 8) )
|
||||
print( 'pcall(tonumber,"123",6)', pcall(tonumber,"123", 6) )
|
||||
print( 'pcall(tonumber,"10101",4)', pcall(tonumber,"10101", 4) )
|
||||
print( 'pcall(tonumber,"10101",3)', pcall(tonumber,"10101", 3) )
|
||||
print( 'pcall(tonumber,"10101",2)', pcall(tonumber,"10101", 2) )
|
||||
print( 'pcall(tonumber,"1a1",16)', pcall(tonumber,"1a1", 16) )
|
||||
print( 'pcall(tonumber,"1a1",32)', pcall(tonumber,"1a1", 32) )
|
||||
print( 'pcall(tonumber,"1a1",54)', pcall(tonumber,"1a1", 54) )
|
||||
print( 'pcall(tonumber,"1a1",1)', pcall(tonumber,"1a1", 1) )
|
||||
print( 'pcall(tonumber,"1a1",0)', pcall(tonumber,"1a1", 0) )
|
||||
print( 'pcall(tonumber,"1a1",-1)', pcall(tonumber,"1a1", -1) )
|
||||
print( 'pcall(tonumber,"1a1","32")', pcall(tonumber,"1a1", "32") )
|
||||
print( 'pcall(tonumber,"123","456")', pcall(tonumber,"123","456") )
|
||||
print( 'pcall(tonumber,"1a1",10)', pcall(tonumber,"1a1", 10) )
|
||||
print( 'pcall(tonumber,"151",4)', pcall(tonumber,"151", 4) )
|
||||
print( 'pcall(tonumber,"151",3)', pcall(tonumber,"151", 3) )
|
||||
print( 'pcall(tonumber,"151",2)', pcall(tonumber,"151", 2) )
|
||||
print( 'pcall(tonumber,"123",8,8)', pcall(tonumber,"123", 8, 8) )
|
||||
print( 'pcall(tonumber,123)', pcall(tonumber,123) )
|
||||
print( 'pcall(tonumber,true)', pcall(tonumber,true) )
|
||||
print( 'pcall(tonumber,false)', pcall(tonumber,false) )
|
||||
print( 'pcall(tonumber,tonumber)', pcall(tonumber,tonumber) )
|
||||
print( 'pcall(tonumber,function() end)', pcall(tonumber,function() end) )
|
||||
print( 'pcall(tonumber,{"one","two",a="aa",b="bb"})', pcall(tonumber,{"one","two",a="aa",b="bb"}) )
|
||||
print( 'pcall(tonumber,"123.456")', pcall(tonumber,"123.456") )
|
||||
print( 'pcall(tonumber," 123.456")', pcall(tonumber," 123.456") )
|
||||
print( 'pcall(tonumber," 234qwer")', pcall(tonumber," 234qwer") )
|
||||
print( 'pcall(tonumber,"0x20")', pcall(tonumber,"0x20") )
|
||||
print( 'pcall(tonumber," 0x20")', pcall(tonumber," 0x20") )
|
||||
print( 'pcall(tonumber,"0x20 ")', pcall(tonumber,"0x20 ") )
|
||||
print( 'pcall(tonumber," 0x20 ")', pcall(tonumber," 0x20 ") )
|
||||
print( 'pcall(tonumber,"0X20")', pcall(tonumber,"0X20") )
|
||||
print( 'pcall(tonumber," 0X20")', pcall(tonumber," 0X20") )
|
||||
print( 'pcall(tonumber,"0X20 ")', pcall(tonumber,"0X20 ") )
|
||||
print( 'pcall(tonumber," 0X20 ")', pcall(tonumber," 0X20 ") )
|
||||
print( 'pcall(tonumber,"0x20",10)', pcall(tonumber,"0x20",10) )
|
||||
print( 'pcall(tonumber,"0x20",16)', pcall(tonumber,"0x20",16) )
|
||||
print( 'pcall(tonumber,"0x20",8)', pcall(tonumber,"0x20",8) )
|
||||
|
||||
-- tostring
|
||||
print( 'pcall(tostring)', pcall(tostring) )
|
||||
print( 'pcall(tostring,nil)', pcall(tostring,nil) )
|
||||
print( 'pcall(tostring,"abc")', pcall(tostring,"abc") )
|
||||
print( 'pcall(tostring,"abc","def")', pcall(tostring,"abc","def") )
|
||||
print( 'pcall(tostring,123)', pcall(tostring,123) )
|
||||
print( 'pcall(tostring,true)', pcall(tostring,true) )
|
||||
print( 'pcall(tostring,false)', pcall(tostring,false) )
|
||||
print( 'tostring(tostring)', type(tostring(tostring)) )
|
||||
print( 'tostring(function() end)', type(tostring(function() end)) )
|
||||
print( 'tostring({"one","two",a="aa",b="bb"})', type(tostring({"one","two",a="aa",b="bb"})) )
|
||||
|
||||
-- _VERSION
|
||||
print( '_VERSION', type(_VERSION) )
|
||||
|
||||
-- xpcall
|
||||
local errfunc = function( detail )
|
||||
print( ' in errfunc', type(detail) )
|
||||
return 'response-from-xpcall'
|
||||
end
|
||||
local badfunc = function() error( 'error-from-badfunc' ) end
|
||||
local wrappedbad = function() pcall( badfunc ) end
|
||||
print( 'pcall(badfunc)', pcall(badfunc) )
|
||||
print( 'pcall(badfunc,errfunc)', pcall(badfunc,errfunc) )
|
||||
print( 'pcall(badfunc,badfunc)', pcall(badfunc,badfunc) )
|
||||
print( 'pcall(wrappedbad)', pcall(wrappedbad) )
|
||||
print( 'pcall(wrappedbad,errfunc)', pcall(wrappedbad,errfunc) )
|
||||
print( 'pcall(xpcall(badfunc))', pcall(xpcall,badfunc) )
|
||||
print( 'pcall(xpcall(badfunc,errfunc))', pcall(xpcall,badfunc,errfunc) )
|
||||
print( 'pcall(xpcall(badfunc,badfunc))', pcall(xpcall,badfunc,badfunc) )
|
||||
print( 'pcall(xpcall(wrappedbad))', pcall(xpcall,wrappedbad) )
|
||||
print( 'xpcall(wrappedbad,errfunc)', xpcall(wrappedbad,errfunc) )
|
||||
|
||||
126
luaj-test/src/test/resources/coroutinelib.lua
Normal file
126
luaj-test/src/test/resources/coroutinelib.lua
Normal file
@@ -0,0 +1,126 @@
|
||||
function printrunning()
|
||||
if coroutine.running() == nil then
|
||||
print("running is nil");
|
||||
else
|
||||
print("running is not nil")
|
||||
end
|
||||
end
|
||||
|
||||
function foo (a)
|
||||
print("foo", a)
|
||||
return coroutine.yield(2*a)
|
||||
end
|
||||
|
||||
co = coroutine.create(function (a,b)
|
||||
print("co-body", a, b)
|
||||
local r = foo(a+1)
|
||||
print("co-body", r)
|
||||
local r, s = coroutine.yield(a+b, a-b)
|
||||
print("co-body", r, s)
|
||||
|
||||
printrunning()
|
||||
print("co.status.inside",coroutine.status(co));
|
||||
local co2 = coroutine.create(function()
|
||||
print("co.status.inside2",coroutine.status(co));
|
||||
end)
|
||||
print("co.status.inside",coroutine.status(co));
|
||||
coroutine.resume(co2);
|
||||
|
||||
return b, "end"
|
||||
end)
|
||||
|
||||
function exercise()
|
||||
printrunning()
|
||||
print("co.status",coroutine.status(co));
|
||||
print("main", coroutine.resume(co, 1, 10))
|
||||
print("co.status",coroutine.status(co));
|
||||
print("main", coroutine.resume(co, "r"))
|
||||
print("co.status",coroutine.status(co));
|
||||
print("main", coroutine.resume(co, "x", "y"))
|
||||
print("co.status",coroutine.status(co));
|
||||
print("main", coroutine.resume(co, "x", "y"))
|
||||
print("co.status",coroutine.status(co));
|
||||
end
|
||||
|
||||
exercise();
|
||||
|
||||
co = coroutine.create(function (a,b)
|
||||
print("co-body", a, b)
|
||||
-- TODO: make java and C behave the same for yielding in pcalls
|
||||
-- local status,r = pcall( foo, a+1 )
|
||||
foo(a+1)
|
||||
print("co-body", status,r)
|
||||
local r, s = coroutine.yield(a+b, a-b)
|
||||
print("co-body", r, s)
|
||||
return b, "end"
|
||||
end)
|
||||
|
||||
exercise();
|
||||
|
||||
|
||||
-- wrap test
|
||||
local g = coroutine.wrap(function (a,b)
|
||||
print("co-body", a, b)
|
||||
local r = foo(a+1)
|
||||
print("co-body", r)
|
||||
local r, s = coroutine.yield(a+b, a-b)
|
||||
print("co-body", r, s)
|
||||
return b, "end"
|
||||
end )
|
||||
|
||||
print("g", g(1, 10))
|
||||
print("g", g("r"))
|
||||
print("g", g("x", "y"))
|
||||
local s,e = pcall( g, "x", "y" )
|
||||
print("g", string.match(e,'cannot resume dead coroutine') or 'badmessage: '..tostring(e))
|
||||
|
||||
-- varargs passing
|
||||
local echo = function(msg,...)
|
||||
print( msg, ...)
|
||||
return ...
|
||||
end
|
||||
local echocr = function(...)
|
||||
local arg = table.pack(...)
|
||||
echo('(echocr) first args', table.unpack(arg,1,arg.n))
|
||||
local a = arg
|
||||
while true do
|
||||
a = { echo( '(echoch) yield returns', coroutine.yield( table.unpack(a) ) ) }
|
||||
end
|
||||
end
|
||||
local c = coroutine.create( echocr )
|
||||
local step = function(...)
|
||||
echo( '(main) resume returns',
|
||||
coroutine.resume(c, echo('(main) sending args', ...)) )
|
||||
end
|
||||
step(111,222,333)
|
||||
step()
|
||||
step(111)
|
||||
step(111,222,333)
|
||||
|
||||
-- test loops in resume calls
|
||||
b = coroutine.create( function( arg )
|
||||
while ( true ) do
|
||||
print( ' b-resumed', arg, b == coroutine.running() )
|
||||
print( ' b-b', coroutine.status(b) )
|
||||
print( ' b-c', coroutine.status(c) )
|
||||
print( ' b-resume-b',coroutine.resume( b, 'b-arg-for-b' ) )
|
||||
print( ' b-resume-c',coroutine.resume( c, 'b-arg-for-c' ) )
|
||||
arg = coroutine.yield( 'b-rslt' )
|
||||
end
|
||||
end )
|
||||
c = coroutine.create( function( arg )
|
||||
for i=1,3 do
|
||||
print( ' c-resumed', arg, c == coroutine.running() )
|
||||
print( ' c-b', coroutine.status(b) )
|
||||
print( ' c-c', coroutine.status(c) )
|
||||
print( ' c-resume-b',coroutine.resume( b, 'b-arg-for-b' ) )
|
||||
print( ' c-resume-c',coroutine.resume( c, 'b-arg-for-c' ) )
|
||||
arg = coroutine.yield( 'c-rslt' )
|
||||
end
|
||||
end )
|
||||
for i=1,3 do
|
||||
print( 'main-b', coroutine.status(b) )
|
||||
print( 'main-c', coroutine.status(c) )
|
||||
print( 'main-resume-b',coroutine.resume( b, 'main-arg-for-b' ) )
|
||||
print( 'main-resume-c',coroutine.resume( c, 'main-arg-for-c' ) )
|
||||
end
|
||||
280
luaj-test/src/test/resources/debuglib.lua
Normal file
280
luaj-test/src/test/resources/debuglib.lua
Normal file
@@ -0,0 +1,280 @@
|
||||
|
||||
local print,tostring,_G,pcall,ipairs,isnumber = print,tostring,_G,pcall,ipairs,isnumber
|
||||
local e,f,g,h,s
|
||||
print( 'has debug', debug~=nil )
|
||||
if not debug then error( 'no debug' ) end
|
||||
|
||||
|
||||
print( '----- debug.getlocal, debug.setlocal' )
|
||||
h = function(v,i,n)
|
||||
s = 'h-'..v..'-'..i
|
||||
local x1,y1 = debug.getlocal(v,i)
|
||||
local x2,y2 = debug.setlocal(v,i,n)
|
||||
local x3,y3 = debug.getlocal(v,i)
|
||||
return s..' -> '..v..'-'..i..' '..
|
||||
'get='..tostring(x1)..','..tostring(y1)..' '..
|
||||
'set='..tostring(x2)..','..tostring(y2)..' '..
|
||||
'get='..tostring(x3)..','..tostring(y3)..' '
|
||||
end
|
||||
g = function(...)
|
||||
local p,q,r=7,8,9
|
||||
local t = h(...)
|
||||
local b = table.concat({...},',')
|
||||
return t..'\tg locals='..p..','..q..','..r..' tbl={'..b..'}'
|
||||
end
|
||||
f = function(a,b,c)
|
||||
local d,e,f = 4,5,6
|
||||
local t = g(a,b,c)
|
||||
return t..'\tf locals='..','..a..','..b..','..c..','..d..','..e..','..f
|
||||
end
|
||||
for lvl=3,2,-1 do
|
||||
for lcl=0,7 do
|
||||
print( pcall( f, lvl, lcl, '#' ) )
|
||||
end
|
||||
end
|
||||
for lvl=1,1 do
|
||||
for lcl=3,7 do
|
||||
print( pcall( f, lvl, lcl, '#' ) )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
print( '----- debug.getupvalue, debug.setupvalue' )
|
||||
local m,n,o = 101,102,103
|
||||
f = function(p,q,r)
|
||||
local p,q,r = 104,105,106
|
||||
local g = function(s,t,u)
|
||||
local v,w,x = 107,108,109
|
||||
return function()
|
||||
return m,n,o,p,q,r,v,w,x
|
||||
end
|
||||
end
|
||||
return g
|
||||
end
|
||||
g = f()
|
||||
h = g()
|
||||
local callh = function()
|
||||
local t = {}
|
||||
for i,v in ipairs( { pcall(h) } ) do
|
||||
t[i] = tostring(v)
|
||||
end
|
||||
return table.concat(t,',')
|
||||
end
|
||||
print( 'h', h() )
|
||||
local funs = { f, g, h }
|
||||
local names = { 'f', 'g', 'h' }
|
||||
for i=1,3 do
|
||||
local fun,name = funs[i],names[i]
|
||||
for index=0,10 do
|
||||
local s1,x1,y1 = pcall( debug.getupvalue, fun, index )
|
||||
local s2,x2,y2 = pcall( debug.setupvalue, fun, index, 666000+i*111000+index )
|
||||
local s3,x3,y3 = pcall( debug.getupvalue, fun, index )
|
||||
print( name..' -> '..i..'-'..index..' '..
|
||||
'get='..tostring(s1)..','..tostring(x1)..','..tostring(y1)..' '..
|
||||
'set='..tostring(s2)..','..tostring(x2)..','..tostring(y2)..' '..
|
||||
'get='..tostring(s3)..','..tostring(x3)..','..tostring(y3)..' '..
|
||||
'tbl='..callh() )
|
||||
end
|
||||
end
|
||||
|
||||
print( '----- debug.setmetatable, debug.getmetatable' )
|
||||
local a = {a='bbb'}
|
||||
local b = {}
|
||||
local mt = {__index={b='ccc'}}
|
||||
print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b))
|
||||
local s1,x1,y1 = pcall( debug.getmetatable, a )
|
||||
local s2,x2,y2 = pcall( debug.setmetatable, a, mt )
|
||||
print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b))
|
||||
local s3,x3,y3 = pcall( debug.getmetatable, a ) print(type(s3), type(x3), type(y3), type(getmetatable(a)))
|
||||
local s4,x4,y4 = pcall( debug.getmetatable, b ) print(type(s4), type(x4), type(y4), type(getmetatable(b)))
|
||||
local s5,x5,y5 = pcall( debug.setmetatable, a, nil ) print(type(s5), type(x5), type(y5), type(getmetatable(a)))
|
||||
print( 'a.a='..tostring(a.a)..' a.b='..tostring(a.b)..' b.a='..tostring(b.a)..' b.b='..tostring(b.b))
|
||||
local s6,x6,y6 = pcall( debug.getmetatable, a ) print(type(s6), type(x6), type(y6), type(getmetatable(a)))
|
||||
if not s1 then print( 's1 error', x1 ) end
|
||||
if not s2 then print( 's2 error', x2 ) end
|
||||
if not s3 then print( 's3 error', x3 ) end
|
||||
if not s4 then print( 's4 error', x4 ) end
|
||||
if not s5 then print( 's5 error', x5 ) end
|
||||
if not s6 then print( 's6 error', x6 ) end
|
||||
print( 'get='..tostring(s1)..','..tostring(x1==nil)..','..tostring(y1) )
|
||||
print( 'set='..tostring(s2)..','..tostring(x2==a)..','..tostring(y2) )
|
||||
print( 'get='..tostring(s3)..','..tostring(x3==mt)..','..tostring(y3) )
|
||||
print( 'get='..tostring(s4)..','..tostring(x4==nil)..','..tostring(y4) )
|
||||
print( 'set='..tostring(s5)..','..tostring(x5==a)..','..tostring(y5) )
|
||||
print( 'get='..tostring(s6)..','..tostring(x6==nil)..','..tostring(y6) )
|
||||
print( pcall( debug.getmetatable, 1 ) )
|
||||
print( pcall( debug.setmetatable, 1, {} ) )
|
||||
print( pcall( debug.setmetatable, 1, nil ) )
|
||||
|
||||
print( '----- debug.getinfo' )
|
||||
local printfield = function(tbl, field)
|
||||
local x = tbl[field]
|
||||
if x == nil then return end
|
||||
local typ = type(x)
|
||||
if typ=='table' then
|
||||
x = '{'..table.concat(x,',')..'}'
|
||||
elseif typ=='function' then
|
||||
x = typ
|
||||
end
|
||||
print( ' '..field..': '..tostring(x) )
|
||||
end
|
||||
local fields = { 'source', 'short_src', 'what',
|
||||
'currentline', 'linedefined', 'lastlinedefined',
|
||||
'nups', 'func', 'activelines' }
|
||||
local printinfo = function(...)
|
||||
for i,a in ipairs({...}) do
|
||||
if type(a) == 'table' then
|
||||
for j,field in ipairs(fields) do
|
||||
printfield( a, field)
|
||||
end
|
||||
else
|
||||
print( tostring(a) )
|
||||
end
|
||||
end
|
||||
end
|
||||
function test()
|
||||
local x = 5
|
||||
function f()
|
||||
x = x + 1
|
||||
return x
|
||||
end
|
||||
function g()
|
||||
x = x - 1
|
||||
print( '---' )
|
||||
printinfo( 'debug.getinfo(1)', debug.getinfo(1) )
|
||||
printinfo( 'debug.getinfo(1,"")', debug.getinfo(1, "") )
|
||||
printinfo( 'debug.getinfo(1,"l")', debug.getinfo(1, "l") )
|
||||
printinfo( 'debug.getinfo(1,"fL")', debug.getinfo(1, "fL") )
|
||||
printinfo( 'debug.getinfo(2)', debug.getinfo(2) )
|
||||
printinfo( 'debug.getinfo(2,"l")', debug.getinfo(2, "l") )
|
||||
printinfo( 'debug.getinfo(2,"fL")', debug.getinfo(2, "fL") )
|
||||
printinfo( 'debug.getinfo(10,"")', pcall( debug.getinfo, 10, "" ) )
|
||||
printinfo( 'debug.getinfo(-10,"")', pcall( debug.getinfo, -10, "" ) )
|
||||
print( '---' )
|
||||
return x
|
||||
end
|
||||
print(f())
|
||||
print(g())
|
||||
return f, g
|
||||
end
|
||||
|
||||
local options = "nSlufL"
|
||||
local e,f,g = pcall( test )
|
||||
print( 'e,f,g', e, type(f), type(g) )
|
||||
printinfo( 'debug.getinfo(f)', pcall(debug.getinfo, f) )
|
||||
printinfo( 'debug.getinfo(f,"'..options..'")', pcall(debug.getinfo, f, options) )
|
||||
for j=1,6 do
|
||||
local opts = options:sub(j,j)
|
||||
printinfo( 'debug.getinfo(f,"'..opts..'")', pcall(debug.getinfo, f, opts) )
|
||||
end
|
||||
printinfo( 'debug.getinfo(g)', pcall(debug.getinfo, g) )
|
||||
printinfo( 'debug.getinfo(test)', pcall(debug.getinfo, test) )
|
||||
|
||||
print( '----- debug.sethook, debug.gethook' )
|
||||
f = function(x)
|
||||
g = function(y)
|
||||
return math.min(x,h)
|
||||
end
|
||||
local a = g(x)
|
||||
return a + a
|
||||
end
|
||||
local hook = function(...)
|
||||
print( ' ... in hook', ... )
|
||||
local info = debug.getinfo(2,"Sl")
|
||||
if info then
|
||||
print( ' info[2]='..tostring(info.short_src)..','..tostring(info.currentline) )
|
||||
end
|
||||
end
|
||||
local tryfunc = function(hook,mask,func,arg)
|
||||
local x,f,h,m
|
||||
pcall( function()
|
||||
debug.sethook(hook,mask)
|
||||
x = func(arg)
|
||||
f,h,m = debug.gethook()
|
||||
end )
|
||||
debug.sethook()
|
||||
return x,f,h,m
|
||||
end
|
||||
|
||||
local tryhooks = function(mask)
|
||||
local s1,a1,b1,c1,d1 = pcall( tryfunc, hook, mask, f, 333 )
|
||||
print( 'hook = '..mask..' -> '..
|
||||
'result='..tostring(s1)..','..tostring(a1)..','..
|
||||
type(b1)..','..type(c1)..','..
|
||||
tostring(b1==f)..','..tostring(c1==hook)..','..
|
||||
tostring(d1)..' ' )
|
||||
end
|
||||
|
||||
tryhooks("c")
|
||||
tryhooks("r")
|
||||
tryhooks("l")
|
||||
tryhooks("crl")
|
||||
|
||||
print( '----- debug.traceback' )
|
||||
function test()
|
||||
function a(msg)
|
||||
print((string.gsub(debug.traceback(msg), "%[Java]", "[C]")))
|
||||
end
|
||||
local function b(msg)
|
||||
pcall(a,msg)
|
||||
end
|
||||
c = function(i)
|
||||
if i <= 0 then b('hi') return end
|
||||
return c(i-1)
|
||||
end
|
||||
d = setmetatable({},{__index=function(t,k) v = c(k) return v end})
|
||||
local e = function()
|
||||
return d[0]
|
||||
end
|
||||
local f = {
|
||||
g = function()
|
||||
e()
|
||||
end
|
||||
}
|
||||
h = function()
|
||||
f.g()
|
||||
end
|
||||
local i = h
|
||||
i()
|
||||
end
|
||||
pcall(test)
|
||||
|
||||
|
||||
print( '----- debug.upvalueid' )
|
||||
local x,y = 100,200
|
||||
function a(b,c)
|
||||
local z,w = b,c
|
||||
return function()
|
||||
x,y,z,w = x+1,y+1,z+1,w+1
|
||||
return x,y,z,w
|
||||
end
|
||||
end
|
||||
a1 = a(300,400)
|
||||
a2 = a(500,600)
|
||||
print('debug.getupvalue(a1,1)', debug.getupvalue(a1,1))
|
||||
print('debug.getupvalue(a1,2)', debug.getupvalue(a1,2))
|
||||
print('debug.getupvalue(a2,1)', debug.getupvalue(a2,1))
|
||||
print('debug.getupvalue(a2,2)', debug.getupvalue(a2,2))
|
||||
print('debug.upvalueid(a1,1) == debug.upvalueid(a1,1)', debug.upvalueid(a1,1) == debug.upvalueid(a1,1))
|
||||
print('debug.upvalueid(a1,1) == debug.upvalueid(a2,1)', debug.upvalueid(a1,1) == debug.upvalueid(a2,1))
|
||||
print('debug.upvalueid(a1,1) == debug.upvalueid(a1,2)', debug.upvalueid(a1,1) == debug.upvalueid(a1,2))
|
||||
|
||||
print( '----- debug.upvaluejoin' )
|
||||
print('a1',a1())
|
||||
print('a2',a2())
|
||||
print('debug.upvaluejoin(a1,1,a2,2)', debug.upvaluejoin(a1,1,a2,2))
|
||||
print('debug.upvaluejoin(a1,3,a2,4)', debug.upvaluejoin(a1,3,a2,4))
|
||||
print('a1',a1())
|
||||
print('a2',a2())
|
||||
print('a1',a1())
|
||||
print('a2',a2())
|
||||
for i = 1,4 do
|
||||
print('debug.getupvalue(a1,'..i..')', debug.getupvalue(a1,i))
|
||||
print('debug.getupvalue(a2,'..i..')', debug.getupvalue(a2,i))
|
||||
for j = 1,4 do
|
||||
print('debug.upvalueid(a1,'..i..') == debug.upvalueid(a1,'..j..')', debug.upvalueid(a1,i) == debug.upvalueid(a1,j))
|
||||
print('debug.upvalueid(a1,'..i..') == debug.upvalueid(a2,'..j..')', debug.upvalueid(a1,i) == debug.upvalueid(a2,j))
|
||||
print('debug.upvalueid(a2,'..i..') == debug.upvalueid(a1,'..j..')', debug.upvalueid(a2,i) == debug.upvalueid(a1,j))
|
||||
print('debug.upvalueid(a2,'..i..') == debug.upvalueid(a2,'..j..')', debug.upvalueid(a2,i) == debug.upvalueid(a2,j))
|
||||
end
|
||||
end
|
||||
137
luaj-test/src/test/resources/errors.lua
Normal file
137
luaj-test/src/test/resources/errors.lua
Normal file
@@ -0,0 +1,137 @@
|
||||
-- tostring replacement that assigns ids
|
||||
local ts,id,nid,types = tostring,{},0,{table='tbl',thread='thr',userdata='uda',['function']='func'}
|
||||
tostring = function(x)
|
||||
if not x or not types[type(x)] then return ts(x) end
|
||||
if not id[x] then nid=nid+1; id[x]=types[type(x)]..'.'..nid end
|
||||
return id[x]
|
||||
end
|
||||
|
||||
-- test of common types of errors
|
||||
-- local function c(f,...) return f(...) end
|
||||
-- local function b(...) return c(...) end
|
||||
--local function a(...) return (pcall(b,...)) end
|
||||
local function a(...) local s,e=pcall(...) if s then return s,e else return false,type(e) end end
|
||||
s = 'some string'
|
||||
local t = {}
|
||||
-- error message tests
|
||||
print( 'a(error)', a(error) )
|
||||
print( 'a(error,"msg")', a(error,"msg") )
|
||||
print( 'a(error,"msg",0)', a(error,"msg",0) )
|
||||
print( 'a(error,"msg",1)', a(error,"msg",1) )
|
||||
print( 'a(error,"msg",2)', a(error,"msg",2) )
|
||||
print( 'a(error,"msg",3)', a(error,"msg",3) )
|
||||
print( 'a(error,"msg",4)', a(error,"msg",4) )
|
||||
print( 'a(error,"msg",5)', a(error,"msg",5) )
|
||||
print( 'a(error,"msg",6)', a(error,"msg",6) )
|
||||
|
||||
-- call errors
|
||||
print( 'a(nil())', a(function() return n() end) )
|
||||
print( 'a(t()) ', a(function() return t() end) )
|
||||
print( 'a(s()) ', a(function() return s() end) )
|
||||
print( 'a(true())', a(function() local b = true; return b() end) )
|
||||
|
||||
-- arithmetic errors
|
||||
print( 'a(nil+1)', a(function() return nil+1 end) )
|
||||
print( 'a(a+1) ', a(function() return a+1 end) )
|
||||
print( 'a(s+1) ', a(function() return s+1 end) )
|
||||
print( 'a(true+1)', a(function() local b = true; return b+1 end) )
|
||||
|
||||
-- table errors
|
||||
print( 'a(nil.x)', a(function() return n.x end) )
|
||||
print( 'a(a.x) ', a(function() return a.x end) )
|
||||
print( 'a(s.x) ', a(function() return s.x end) )
|
||||
print( 'a(true.x)', a(function() local b = true; return b.x end) )
|
||||
print( 'a(nil.x=5)', a(function() n.x=5 end) )
|
||||
print( 'a(a.x=5) ', a(function() a.x=5 end) )
|
||||
print( 'a(s.x=5) ', a(function() s.x=5 end) )
|
||||
print( 'a(true.x=5)', a(function() local b = true; b.x=5 end) )
|
||||
|
||||
-- len operator
|
||||
print( 'a(#nil) ', a(function() return #n end) )
|
||||
print( 'a(#t) ', a(function() return #t end) )
|
||||
print( 'a(#s) ', a(function() return #s end) )
|
||||
print( 'a(#a) ', a(function() return #a end) )
|
||||
print( 'a(#true)', a(function() local b = true; return #b end) )
|
||||
|
||||
-- comparison errors
|
||||
print( 'a(nil>1)', a(function() return nil>1 end) )
|
||||
print( 'a(a>1) ', a(function() return a>1 end) )
|
||||
print( 'a(s>1) ', a(function() return s>1 end) )
|
||||
print( 'a(true>1)', a(function() local b = true; return b>1 end) )
|
||||
|
||||
-- unary minus errors
|
||||
print( 'a(-nil)', a(function() return -n end) )
|
||||
print( 'a(-a) ', a(function() return -a end) )
|
||||
print( 'a(-s) ', a(function() return -s end) )
|
||||
print( 'a(-true)', a(function() local b = true; return -b end) )
|
||||
|
||||
-- string concatenation
|
||||
local function concatsuite(comparefunc)
|
||||
print( '"a".."b"', comparefunc("a","b") )
|
||||
print( '"a"..nil', comparefunc("a",nil) )
|
||||
print( 'nil.."b"', comparefunc(nil,"b") )
|
||||
print( '"a"..{}', comparefunc("a",{}) )
|
||||
print( '{}.."b"', comparefunc({},"b") )
|
||||
print( '"a"..2', comparefunc("a",2) )
|
||||
print( '2.."b"', comparefunc(2,"b") )
|
||||
print( '"a"..print', comparefunc("a",print) )
|
||||
print( 'print.."b"', comparefunc(print,"b") )
|
||||
print( '"a"..true', comparefunc("a",true) )
|
||||
print( 'true.."b"', comparefunc(true,"b") )
|
||||
print( 'nil..true', comparefunc(nil,true) )
|
||||
print( '"a"..3.5', comparefunc("a",3.5) )
|
||||
print( '3.5.."b"', comparefunc(3.5,"b") )
|
||||
end
|
||||
local function strconcat(a,b)
|
||||
return (pcall( function() return a..b end) )
|
||||
end
|
||||
local function tblconcat(a,b)
|
||||
local t={a,b}
|
||||
return (pcall( function() return table.concat(t,'-',1,2) end ))
|
||||
end
|
||||
|
||||
print( '-------- string concatenation' )
|
||||
concatsuite(strconcat)
|
||||
print( '-------- table concatenation' )
|
||||
concatsuite(tblconcat)
|
||||
|
||||
-- pairs
|
||||
print( '-------- pairs tests' )
|
||||
print( 'a(pairs(nil))', a(function() return pairs(nil,{}) end) )
|
||||
print( 'a(pairs(a)) ', a(function() return pairs(a,{}) end) )
|
||||
print( 'a(pairs(s)) ', a(function() return pairs(s,{}) end) )
|
||||
print( 'a(pairs(t)) ', a(function() return pairs(t,{}) end) )
|
||||
print( 'a(pairs(true))', a(function() local b = true; return pairs(b,{}) end) )
|
||||
|
||||
-- setmetatable
|
||||
print( '-------- setmetatable tests' )
|
||||
function sm(...)
|
||||
return tostring(setmetatable(...))
|
||||
end
|
||||
print( 'a(setmetatable(nil))', a(function() return sm(nil,{}) end) )
|
||||
print( 'a(setmetatable(a)) ', a(function() return sm(a,{}) end) )
|
||||
print( 'a(setmetatable(s)) ', a(function() return sm(s,{}) end) )
|
||||
print( 'a(setmetatable(true))', a(function() local b = true; return sm(b,{}) end) )
|
||||
print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) )
|
||||
print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) )
|
||||
print( 'a(setmetatable(t*)) ', a(function() return sm(t,{__metatable={}}) end) )
|
||||
print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) )
|
||||
print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) )
|
||||
print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) )
|
||||
t = {}
|
||||
print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) )
|
||||
print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) )
|
||||
print( 'a(setmetatable(t*)) ', a(function() return sm(t,{__metatable='some string'}) end) )
|
||||
print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) )
|
||||
print( 'a(setmetatable(t)) ', a(function() return sm(t,{}) end) )
|
||||
print( 'a(getmetatable(t)) ', a(function() return getmetatable(t),type(getmetatable(t)) end) )
|
||||
print( 'a(setmetatable(t,nil)) ', a(function() return sm(t,nil) end) )
|
||||
print( 'a(setmetatable(t)) ', a(function() return sm(t) end) )
|
||||
print( 'a(setmetatable({},"abc")) ', a(function() return sm({},'abc') end) )
|
||||
|
||||
-- bad args to error!
|
||||
print( 'error("msg","arg")', a(function() error('some message', 'some bad arg') end) )
|
||||
|
||||
-- loadfile, dofile on missing files
|
||||
print( 'loadfile("bogus.txt")', a(function() return loadfile("bogus.txt") end) )
|
||||
print( 'dofile("bogus.txt")', a(function() return dofile("bogus.txt") end) )
|
||||
0
luaj-test/src/test/resources/errors/abc.txt
Normal file
0
luaj-test/src/test/resources/errors/abc.txt
Normal file
198
luaj-test/src/test/resources/errors/args.lua
Normal file
198
luaj-test/src/test/resources/errors/args.lua
Normal file
@@ -0,0 +1,198 @@
|
||||
-- utilities to check that args of various types pass or fail
|
||||
-- argument type checking
|
||||
local ok = '-\t'
|
||||
local fail = 'fail '
|
||||
local needcheck = 'needcheck '
|
||||
local badmsg = 'badmsg '
|
||||
|
||||
akey = 'aa'
|
||||
astring = 'abc'
|
||||
astrnum = '789'
|
||||
anumber = 1.25
|
||||
ainteger = 345
|
||||
adouble = 12.75
|
||||
aboolean = true
|
||||
atable = {[akey]=456}
|
||||
afunction = function() end
|
||||
anil = nil
|
||||
athread = coroutine.create(afunction)
|
||||
|
||||
anylua = { nil, astring, anumber, aboolean, atable, afunction, athread }
|
||||
|
||||
somestring = { astring, anumber }
|
||||
somenumber = { anumber, astrnum }
|
||||
someboolean = { aboolean }
|
||||
sometable = { atable }
|
||||
somefunction = { afunction }
|
||||
somenil = { anil }
|
||||
somekey = { akey }
|
||||
notakey = { astring, anumber, aboolean, atable, afunction }
|
||||
|
||||
notastring = { nil, aboolean, atable, afunction, athread }
|
||||
notanumber = { nil, astring, aboolean, atable, afunction, athread }
|
||||
notaboolean = { nil, astring, anumber, atable, afunction, athread }
|
||||
notatable = { nil, astring, anumber, aboolean, afunction, athread }
|
||||
notafunction = { nil, astring, anumber, aboolean, atable, athread }
|
||||
notathread = { nil, astring, anumber, aboolean, atable, afunction }
|
||||
notanil = { astring, anumber, aboolean, atable, afunction, athread }
|
||||
|
||||
nonstring = { aboolean, atable, afunction, athread }
|
||||
nonnumber = { astring, aboolean, atable, afunction, athread }
|
||||
nonboolean = { astring, anumber, atable, afunction, athread }
|
||||
nontable = { astring, anumber, aboolean, afunction, athread }
|
||||
nonfunction = { astring, anumber, aboolean, atable, athread }
|
||||
nonthread = { astring, anumber, aboolean, atable, afunction }
|
||||
nonkey = { astring, anumber, aboolean, atable, afunction }
|
||||
|
||||
local structtypes = {
|
||||
['table']='<table>',
|
||||
['function']='<function>',
|
||||
['thread']='<thread>',
|
||||
['userdata']='<userdata>',
|
||||
}
|
||||
|
||||
local function bracket(v)
|
||||
return "<"..type(v)..">"
|
||||
end
|
||||
|
||||
local function quote(v)
|
||||
return "'"..v.."'"
|
||||
end
|
||||
|
||||
local function ellipses(v)
|
||||
local s = tostring(v)
|
||||
return #s <= 8 and s or (string.sub(s,1,8)..'...')
|
||||
end
|
||||
|
||||
local pretty = {
|
||||
['table']=bracket,
|
||||
['function']=bracket,
|
||||
['thread']=bracket,
|
||||
['userdata']=bracket,
|
||||
['string']= quote,
|
||||
['number']= ellipses,
|
||||
}
|
||||
|
||||
local function values(list)
|
||||
local t = {}
|
||||
for i=1,(list.n or #list) do
|
||||
local ai = list[i]
|
||||
local fi = pretty[type(ai)]
|
||||
t[i] = fi and fi(ai) or tostring(ai)
|
||||
end
|
||||
return table.concat(t,',')
|
||||
end
|
||||
|
||||
local function types(list)
|
||||
local t = {}
|
||||
for i=1,(list.n or #list) do
|
||||
local ai = list[i]
|
||||
t[i] = type(ai)
|
||||
end
|
||||
return table.concat(t,',')
|
||||
end
|
||||
|
||||
local function signature(name,arglist)
|
||||
return name..'('..values(arglist)..')'
|
||||
end
|
||||
|
||||
local function dup(t)
|
||||
local s = {}
|
||||
for i=1,(t.n or #t) do
|
||||
s[i] = t[i]
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local function split(t)
|
||||
local s = {}
|
||||
local n = (t.n or #t)
|
||||
for i=1,n-1 do
|
||||
s[i] = t[i]
|
||||
end
|
||||
return s,t[n]
|
||||
end
|
||||
|
||||
local function expand(argsets, typesets, ...)
|
||||
local arg = table.pack(...)
|
||||
local n = typesets and #typesets or 0
|
||||
if n <= 0 then
|
||||
table.insert(argsets,arg)
|
||||
return argsets
|
||||
end
|
||||
|
||||
local s,v = split(typesets)
|
||||
for i=1,(v.n or #v) do
|
||||
expand(argsets, s, v[i], table.unpack(arg,1,arg.n))
|
||||
end
|
||||
return argsets
|
||||
end
|
||||
|
||||
local function arglists(typesets)
|
||||
local argsets = expand({},typesets)
|
||||
return ipairs(argsets)
|
||||
end
|
||||
|
||||
function lookup( name )
|
||||
return load('return '..name)()
|
||||
end
|
||||
|
||||
function invoke( name, arglist )
|
||||
local s,c = pcall(lookup, name)
|
||||
if not s then return s,c end
|
||||
return pcall(c, table.unpack(arglist,1,arglist.n or #arglist))
|
||||
end
|
||||
|
||||
-- messages, banners
|
||||
local _print = print
|
||||
local _tostring = tostring
|
||||
local _find = string.find
|
||||
function banner(name)
|
||||
_print( '====== '.._tostring(name)..' ======' )
|
||||
end
|
||||
|
||||
local function subbanner(name)
|
||||
_print( '--- '.._tostring(name) )
|
||||
end
|
||||
|
||||
local function pack(s,...)
|
||||
return s,{...}
|
||||
end
|
||||
|
||||
-- check that all combinations of arguments pass
|
||||
function checkallpass( name, typesets, typesonly )
|
||||
subbanner('checkallpass')
|
||||
for i,v in arglists(typesets) do
|
||||
local sig = signature(name,v)
|
||||
local s,r = pack( invoke( name, v ) )
|
||||
if s then
|
||||
if typesonly then
|
||||
_print( ok, sig, types(r) )
|
||||
else
|
||||
_print( ok, sig, values(r) )
|
||||
end
|
||||
else
|
||||
_print( fail, sig, values(r) )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- check that all combinations of arguments fail in some way,
|
||||
-- ignore error messages
|
||||
function checkallerrors( name, typesets, template )
|
||||
subbanner('checkallerrors')
|
||||
template = _tostring(template)
|
||||
for i,v in arglists(typesets) do
|
||||
local sig = signature(name,v)
|
||||
local s,e = invoke( name, v )
|
||||
if not s then
|
||||
if _find(e, template, 1, true) then
|
||||
_print( ok, sig, '...'..template..'...' )
|
||||
else
|
||||
_print( badmsg, sig, "template='"..template.."' actual='"..e.."'" )
|
||||
end
|
||||
else
|
||||
_print( needcheck, sig, e )
|
||||
end
|
||||
end
|
||||
end
|
||||
145
luaj-test/src/test/resources/errors/baselibargs.lua
Normal file
145
luaj-test/src/test/resources/errors/baselibargs.lua
Normal file
@@ -0,0 +1,145 @@
|
||||
package.path = "?.lua;test/lua/errors/?.lua"
|
||||
require 'args'
|
||||
|
||||
-- arg types for basic library functions
|
||||
|
||||
-- assert
|
||||
banner('assert')
|
||||
checkallpass('assert',{{true,123},anylua})
|
||||
checkallerrors('assert',{{nil,false,n=2},{nil,n=1}},'assertion failed')
|
||||
checkallerrors('assert',{{nil,false,n=2},{'message'}},'message')
|
||||
|
||||
-- collectgarbage
|
||||
banner('collectgarbage')
|
||||
checkallpass('collectgarbage',{{'collect','count'}},true)
|
||||
checkallerrors('collectgarbage',{{astring, anumber}},'bad argument')
|
||||
checkallerrors('collectgarbage',{{aboolean, atable, afunction, athread}},'string expected')
|
||||
|
||||
-- dofile
|
||||
banner('dofile')
|
||||
--checkallpass('dofile', {})
|
||||
--checkallpass('dofile', {{'test/lua/errors/args.lua'}})
|
||||
--checkallerrors('dofile', {{'foo.bar'}}, 'cannot open foo.bar')
|
||||
--checkallerrors('dofile', {nonstring}, 'bad argument')
|
||||
|
||||
-- error
|
||||
banner('error')
|
||||
--checkallerrors('error', {{'message'},{nil,0,1,2,n=4}}, 'message')
|
||||
--checkallerrors('error', {{123},{nil,1,2,n=3}}, 123)
|
||||
|
||||
-- getmetatable
|
||||
banner('getmetatable')
|
||||
checkallpass('getmetatable', {notanil})
|
||||
checkallerrors('getmetatable',{},'bad argument')
|
||||
|
||||
-- ipairs
|
||||
banner('ipairs')
|
||||
checkallpass('ipairs', {sometable})
|
||||
checkallerrors('ipairs', {notatable}, 'bad argument')
|
||||
|
||||
-- load
|
||||
banner('load')
|
||||
checkallpass('load', {somefunction,{nil,astring,n=2}})
|
||||
checkallerrors('load', {notafunction,{nil,astring,anumber,n=3}}, 'bad argument')
|
||||
checkallerrors('load', {somefunction,{afunction,atable}}, 'bad argument')
|
||||
|
||||
-- loadfile
|
||||
banner('loadfile')
|
||||
--checkallpass('loadfile', {})
|
||||
--checkallpass('loadfile', {{'bogus'}})
|
||||
--checkallpass('loadfile', {{'test/lua/errors/args.lua'}})
|
||||
--checkallpass('loadfile', {{'args.lua'}})
|
||||
--checkallerrors('loadfile', {nonstring}, 'bad argument')
|
||||
|
||||
-- load
|
||||
banner('load')
|
||||
checkallpass('load', {{'return'}})
|
||||
checkallpass('load', {{'return'},{'mychunk'}})
|
||||
checkallpass('load', {{'return a ... b'},{'mychunk'}},true)
|
||||
checkallerrors('load', {notastring,{nil,astring,anumber,n=3}}, 'bad argument')
|
||||
checkallerrors('load', {{'return'},{afunction,atable}}, 'bad argument')
|
||||
|
||||
-- next
|
||||
banner('next')
|
||||
checkallpass('next', {sometable,somekey})
|
||||
checkallerrors('next', {notatable,{nil,1,n=2}}, 'bad argument')
|
||||
checkallerrors('next', {sometable,nonkey}, 'invalid key')
|
||||
|
||||
-- pairs
|
||||
banner('pairs')
|
||||
checkallpass('pairs', {sometable})
|
||||
checkallerrors('pairs', {notatable}, 'bad argument')
|
||||
|
||||
-- pcall
|
||||
banner('pcall')
|
||||
checkallpass('pcall', {notanil,anylua}, true)
|
||||
checkallerrors('pcall',{},'bad argument')
|
||||
|
||||
-- print
|
||||
banner('print')
|
||||
checkallpass('print', {})
|
||||
checkallpass('print', {{nil,astring,anumber,aboolean,n=4}})
|
||||
|
||||
-- rawequal
|
||||
banner('rawequal')
|
||||
checkallpass('rawequal', {notanil,notanil})
|
||||
checkallerrors('rawequal', {}, 'bad argument')
|
||||
checkallerrors('rawequal', {notanil}, 'bad argument')
|
||||
|
||||
-- rawget
|
||||
banner('rawget')
|
||||
checkallpass('rawget', {sometable,somekey})
|
||||
checkallpass('rawget', {sometable,nonkey})
|
||||
checkallerrors('rawget', {sometable,somenil},'bad argument')
|
||||
checkallerrors('rawget', {notatable,notakey}, 'bad argument')
|
||||
checkallerrors('rawget', {}, 'bad argument')
|
||||
|
||||
-- rawset
|
||||
banner('rawset')
|
||||
checkallpass('rawset', {sometable,somekey,notanil})
|
||||
checkallpass('rawset', {sometable,nonkey,notanil})
|
||||
checkallerrors('rawset', {sometable,somenil},'table index is nil')
|
||||
checkallerrors('rawset', {}, 'bad argument')
|
||||
checkallerrors('rawset', {notatable,somestring,somestring}, 'bad argument')
|
||||
checkallerrors('rawset', {sometable,somekey}, 'bad argument')
|
||||
|
||||
-- select
|
||||
banner('select')
|
||||
checkallpass('select', {{anumber,'#'},anylua})
|
||||
checkallerrors('select', {notanumber}, 'bad argument')
|
||||
|
||||
-- setmetatable
|
||||
banner('setmetatable')
|
||||
checkallpass('setmetatable', {sometable,sometable})
|
||||
checkallpass('setmetatable', {sometable,{}})
|
||||
checkallerrors('setmetatable',{notatable,sometable},'bad argument')
|
||||
checkallerrors('setmetatable',{sometable,nontable},'bad argument')
|
||||
|
||||
-- tonumber
|
||||
banner('tonumber')
|
||||
checkallpass('tonumber',{somenumber,{nil,2,10,36,n=4}})
|
||||
checkallpass('tonumber',{notanil,{nil,10,n=2}})
|
||||
checkallerrors('tonumber',{{nil,afunction,atable,n=3},{2,9,11,36}},'bad argument')
|
||||
checkallerrors('tonumber',{somenumber,{1,37,atable,afunction,aboolean}},'bad argument')
|
||||
|
||||
-- tostring
|
||||
banner('tostring')
|
||||
checkallpass('tostring',{{astring,anumber,aboolean}})
|
||||
checkallpass('tostring',{{atable,afunction,athread}},true)
|
||||
checkallpass('tostring',{{astring,anumber,aboolean},{'anchor'}})
|
||||
checkallpass('tostring',{{atable,afunction,athread},{'anchor'}},true)
|
||||
checkallerrors('tostring',{},'bad argument')
|
||||
|
||||
-- type
|
||||
banner('type')
|
||||
checkallpass('type',{notanil})
|
||||
checkallpass('type',{anylua,{'anchor'}})
|
||||
checkallerrors('type',{},'bad argument')
|
||||
|
||||
-- xpcall
|
||||
banner('xpcall')
|
||||
checkallpass('xpcall', {notanil,nonfunction})
|
||||
checkallpass('xpcall', {notanil,{function(...)return 'aaa', 'bbb', #{...} end}})
|
||||
checkallerrors('xpcall',{anylua},'bad argument')
|
||||
|
||||
|
||||
47
luaj-test/src/test/resources/errors/coroutinelibargs.lua
Normal file
47
luaj-test/src/test/resources/errors/coroutinelibargs.lua
Normal file
@@ -0,0 +1,47 @@
|
||||
package.path = "?.lua;test/lua/errors/?.lua"
|
||||
require 'args'
|
||||
|
||||
-- arg type tests for coroutine library functions
|
||||
|
||||
-- coroutine.create
|
||||
banner('coroutine.create')
|
||||
checkallpass('coroutine.create',{somefunction})
|
||||
checkallerrors('coroutine.create',{notafunction},'bad argument')
|
||||
|
||||
-- coroutine.resume
|
||||
banner('coroutine.resume')
|
||||
local co = coroutine.create(function() while true do coroutine.yield() end end)
|
||||
checkallpass('coroutine.resume',{{co},anylua})
|
||||
checkallerrors('coroutine.resume',{notathread},'bad argument')
|
||||
|
||||
-- coroutine.running
|
||||
banner('coroutine.running')
|
||||
checkallpass('coroutine.running',{anylua})
|
||||
|
||||
-- coroutine.status
|
||||
banner('coroutine.status')
|
||||
checkallpass('coroutine.status',{{co}})
|
||||
checkallerrors('coroutine.status',{notathread},'bad argument')
|
||||
|
||||
-- coroutine.wrap
|
||||
banner('coroutine.wrap')
|
||||
checkallpass('coroutine.wrap',{somefunction})
|
||||
checkallerrors('coroutine.wrap',{notafunction},'bad argument')
|
||||
|
||||
-- coroutine.yield
|
||||
banner('coroutine.yield')
|
||||
local function f()
|
||||
print( 'yield', coroutine.yield() )
|
||||
print( 'yield', coroutine.yield(astring,anumber,aboolean) )
|
||||
error('error within coroutine thread')
|
||||
end
|
||||
local co = coroutine.create( f )
|
||||
print( 'status', coroutine.status(co) )
|
||||
print( coroutine.resume(co,astring,anumber) )
|
||||
print( 'status', coroutine.status(co) )
|
||||
print( coroutine.resume(co,astring,anumber) )
|
||||
print( 'status', coroutine.status(co) )
|
||||
local s,e = coroutine.resume(co,astring,anumber)
|
||||
print( s, string.match(e,'error within coroutine thread') or 'bad message: '..tostring(e) )
|
||||
print( 'status', coroutine.status(co) )
|
||||
|
||||
150
luaj-test/src/test/resources/errors/debuglibargs.lua
Normal file
150
luaj-test/src/test/resources/errors/debuglibargs.lua
Normal file
@@ -0,0 +1,150 @@
|
||||
package.path = "?.lua;test/lua/errors/?.lua"
|
||||
require 'args'
|
||||
|
||||
local alevel = {25,'25'}
|
||||
local afuncorlevel = {afunction,25,'25'}
|
||||
local notafuncorlevel = {nil,astring,aboolean,athread}
|
||||
local notafuncorthread = {nil,astring,aboolean}
|
||||
|
||||
-- debug.debug()
|
||||
banner('debug.debug - no tests')
|
||||
|
||||
-- debug.gethook ([thread])
|
||||
banner('debug.gethook')
|
||||
checkallpass('debug.gethook',{})
|
||||
|
||||
-- debug.getinfo ([thread,] f [, what])
|
||||
banner('debug.getinfo')
|
||||
local awhat = {"","n","flnStu"}
|
||||
local notawhat = {"qzQZ"}
|
||||
checkallpass('debug.getinfo',{afuncorlevel})
|
||||
checkallpass('debug.getinfo',{somethread,afuncorlevel})
|
||||
checkallpass('debug.getinfo',{afuncorlevel,awhat})
|
||||
checkallpass('debug.getinfo',{somethread,afuncorlevel,awhat})
|
||||
checkallerrors('debug.getinfo',{},'function or level')
|
||||
checkallerrors('debug.getinfo',{notafuncorlevel},'function or level')
|
||||
checkallerrors('debug.getinfo',{somefunction,nonstring}, 'string expected')
|
||||
checkallerrors('debug.getinfo',{notafuncorthread,somefunction}, 'string expected')
|
||||
checkallerrors('debug.getinfo',{nonthread,somefunction,{astring}}, 'string expected')
|
||||
checkallerrors('debug.getinfo',{somethread,somefunction,notawhat}, 'invalid option')
|
||||
|
||||
-- debug.getlocal ([thread,] f, local)
|
||||
banner('debug.getlocal')
|
||||
local p,q = 'p','q';
|
||||
f = function(x,y)
|
||||
print('f: x,y,a,b,p,q', x, y, a, b, p, q)
|
||||
local a,b = x,y
|
||||
local t = coroutine.running()
|
||||
checkallpass('debug.getlocal',{{f,1},{1,'2'}})
|
||||
checkallpass('debug.getlocal',{{t},{f},{1}})
|
||||
checkallerrors('debug.getlocal',{},'number expected')
|
||||
checkallerrors('debug.getlocal',{afuncorlevel,notanumber},'number expected')
|
||||
checkallerrors('debug.getlocal',{notafuncorlevel,somenumber}, 'number expected')
|
||||
checkallerrors('debug.getlocal',{{t},afuncorlevel}, 'got no value')
|
||||
checkallerrors('debug.getlocal',{nonthread,{f},{1,'2'}}, 'number expected')
|
||||
checkallerrors('debug.getlocal',{{t},{100},{1}}, 'level out of range')
|
||||
end
|
||||
f(1,2)
|
||||
|
||||
-- debug.getmetatable (value)
|
||||
banner('debug.getmetatable')
|
||||
checkallpass('debug.getmetatable',{anylua})
|
||||
checkallerrors('debug.getmetatable',{},'value expected')
|
||||
|
||||
-- debug.getregistry ()
|
||||
banner('debug.getregistry')
|
||||
checkallpass('debug.getregistry',{})
|
||||
checkallpass('debug.getregistry',{anylua})
|
||||
|
||||
-- debug.getupvalue (f, up)
|
||||
banner('debug.getupvalue')
|
||||
checkallpass('debug.getupvalue',{{f},{1,'2'}})
|
||||
checkallerrors('debug.getupvalue',{},'number expected')
|
||||
checkallerrors('debug.getupvalue',{notafunction,{1,'2'}}, 'function expected')
|
||||
checkallerrors('debug.getupvalue',{{f},notanumber}, 'number expected')
|
||||
|
||||
-- debug.getuservalue (u)
|
||||
checkallpass('debug.getuservalue',{})
|
||||
checkallpass('debug.getuservalue',{anylua})
|
||||
|
||||
-- debug.sethook ([thread,] hook, mask [, count])
|
||||
local ahookstr = {"cr","l"}
|
||||
checkallpass('debug.sethook',{})
|
||||
checkallpass('debug.sethook',{somenil,ahookstr})
|
||||
checkallpass('debug.sethook',{somefunction,ahookstr})
|
||||
checkallpass('debug.sethook',{{nil,athread,n=2},somefunction,ahookstr})
|
||||
checkallerrors('debug.sethook',{{astring,afunction,aboolean}},'string expected')
|
||||
checkallerrors('debug.sethook',{{astring,afunction,aboolean},{nil,afunction,n=2},ahookstr},'string expected')
|
||||
|
||||
-- debug.setlocal ([thread,] level, local, value)
|
||||
banner('debug.setlocal')
|
||||
local p,q = 'p','q';
|
||||
f = function(x,y)
|
||||
print('f: x,y,a,b,p,q', x, y, a, b, p, q)
|
||||
local a,b = x,y
|
||||
local t = coroutine.running()
|
||||
checkallpass('debug.setlocal',{{1},{1},{nil,'foo',n=2}})
|
||||
print('f: x,y,a,b,p,q', x, y, a, b, p, q)
|
||||
checkallpass('debug.setlocal',{{t},{1},{2},{nil,'bar',n=2}})
|
||||
print('f: x,y,a,b,p,q', x, y, a, b, p, q)
|
||||
checkallerrors('debug.setlocal',{},'number expected')
|
||||
checkallerrors('debug.setlocal',{{1}},'value expected')
|
||||
checkallerrors('debug.setlocal',{{1},{1}}, 'value expected')
|
||||
checkallerrors('debug.setlocal',{{t},{1},{2}}, 'value expected')
|
||||
checkallerrors('debug.setlocal',{{atable,astring},{1}}, 'number expected')
|
||||
checkallerrors('debug.setlocal',{{1},nonnumber}, 'value expected')
|
||||
checkallerrors('debug.setlocal',{{atable,astring},{1},{1},{nil,'foo',n=2}}, 'number expected')
|
||||
checkallerrors('debug.setlocal',{{10},{1},{'foo'}}, 'level out of range')
|
||||
return p,q
|
||||
end
|
||||
f(1,2)
|
||||
|
||||
-- debug.setmetatable (value, table)
|
||||
banner('debug.setmetatable')
|
||||
checkallpass('debug.setmetatable',{anylua,{atable,nil,n=2}})
|
||||
checkallerrors('debug.setmetatable',{},'nil or table')
|
||||
checkallerrors('debug.setmetatable',{anylua},'nil or table')
|
||||
|
||||
-- debug.setupvalue (f, up, value)
|
||||
banner('debug.setupvalue')
|
||||
checkallpass('debug.setupvalue',{{f},{2,'3'},{nil,aboolean,astring,n=3}})
|
||||
print('p,q', p, q)
|
||||
checkallerrors('debug.setupvalue',{},'value expected')
|
||||
checkallerrors('debug.setupvalue',{{f}},'value expected')
|
||||
checkallerrors('debug.setupvalue',{{f},{2}},'value expected')
|
||||
checkallerrors('debug.setupvalue',{notafunction,{2}}, 'value expected')
|
||||
checkallerrors('debug.setupvalue',{{f},notanumber}, 'value expected')
|
||||
|
||||
-- debug.setuservalue (udata, value)
|
||||
banner('debug.setuservalue')
|
||||
checkallerrors('debug.setuservalue',{},'userdata expected')
|
||||
checkallerrors('debug.setuservalue',{anylua},'userdata expected')
|
||||
checkallerrors('debug.setuservalue',{anylua,somestring},'userdata expected')
|
||||
|
||||
-- debug.traceback ([thread,] [message [, level]])
|
||||
banner('debug.traceback')
|
||||
local t = coroutine.running()
|
||||
checkallpass('debug.traceback',{})
|
||||
checkallpass('debug.traceback',{{astring}})
|
||||
checkallpass('debug.traceback',{{astring},{anumber}})
|
||||
checkallpass('debug.traceback',{{t}})
|
||||
checkallpass('debug.traceback',{{t},{astring}})
|
||||
checkallpass('debug.traceback',{{t},{astring},{anumber}})
|
||||
checkallpass('debug.traceback',{{afunction,aboolean,atable}})
|
||||
checkallpass('debug.traceback',{{afunction,aboolean,atable},notanumber})
|
||||
|
||||
-- debug.upvalueid (f, n)
|
||||
banner('debug.upvalueid')
|
||||
checkallpass('debug.upvalueid',{{f},{1,'2'}})
|
||||
checkallerrors('debug.upvalueid',{},'number expected')
|
||||
checkallerrors('debug.upvalueid',{notafunction,{1,'2'}}, 'function expected')
|
||||
checkallerrors('debug.upvalueid',{{f},notanumber}, 'number expected')
|
||||
|
||||
-- debug.upvaluejoin (f1, n1, f2, n2)
|
||||
banner('debug.upvaluejoin')
|
||||
checkallpass('debug.upvaluejoin',{{f},{1,'2'},{f},{1,'2'}})
|
||||
checkallerrors('debug.upvaluejoin',{},'number expected')
|
||||
checkallerrors('debug.upvaluejoin',{notafunction,{1,'2'}}, 'function expected')
|
||||
checkallerrors('debug.upvaluejoin',{{f},notanumber}, 'number expected')
|
||||
checkallerrors('debug.upvaluejoin',{{f},{1},notafunction,{1,'2'}}, 'function expected')
|
||||
checkallerrors('debug.upvaluejoin',{{f},{1},{f},notanumber}, 'number expected')
|
||||
85
luaj-test/src/test/resources/errors/iolibargs.lua
Normal file
85
luaj-test/src/test/resources/errors/iolibargs.lua
Normal file
@@ -0,0 +1,85 @@
|
||||
package.path = "?.lua;test/lua/errors/?.lua"
|
||||
require 'args'
|
||||
|
||||
-- arg type tests for io library functions
|
||||
local f
|
||||
|
||||
-- io.close ([file])
|
||||
banner('io.close')
|
||||
f = io.open("abc.txt","w")
|
||||
checkallpass('io.close',{{f}})
|
||||
checkallerrors('io.close',{notanil},'bad argument')
|
||||
|
||||
-- io.input ([file])
|
||||
banner('io.input')
|
||||
f = io.open("abc.txt","r")
|
||||
checkallpass('io.input',{{nil,f,"abc.txt",n=3}})
|
||||
checkallerrors('io.input',{nonstring},'bad argument')
|
||||
|
||||
-- io.lines ([filename])
|
||||
banner('io.lines')
|
||||
io.input("abc.txt")
|
||||
checkallpass('io.lines',{{"abc.txt"}})
|
||||
checkallerrors('io.lines',{{f}},'bad argument')
|
||||
checkallerrors('io.lines',{notastring},'bad argument')
|
||||
|
||||
-- io.open (filename [, mode])
|
||||
banner('io.open')
|
||||
checkallpass('io.open',{{"abc.txt"},{nil,"r","w","a","r+","w+","a+"}})
|
||||
checkallerrors('io.open',{notastring},'bad argument')
|
||||
checkallerrors('io.open',{{"abc.txt"},{nonstring}},'bad argument')
|
||||
|
||||
-- io.output ([file])
|
||||
banner('io.output')
|
||||
checkallpass('io.output',{{nil,f,"abc.txt",n=3}})
|
||||
checkallerrors('io.output',{nonstring},'bad argument')
|
||||
|
||||
-- io.popen (prog [, mode])
|
||||
banner('io.popen')
|
||||
--checkallpass('io.popen',{{"hostname"},{nil,"w",n=2}})
|
||||
checkallerrors('io.popen',{notastring},'bad argument')
|
||||
checkallerrors('io.popen',{{"hostname"},{nonstring}},'bad argument')
|
||||
|
||||
-- io.read (<28><><EFBFBD>)
|
||||
banner('io.read')
|
||||
checkallpass('io.read',{})
|
||||
checkallpass('io.read',{{2,"*n","*a","*l"}})
|
||||
checkallpass('io.read',{{2,"*n","*a","*l"},{2,"*a","*l"}})
|
||||
checkallerrors('io.read',{{aboolean,afunction,atable,"3"}},'bad argument')
|
||||
|
||||
-- io.write (<28><><EFBFBD>)
|
||||
banner('io.write')
|
||||
checkallpass('io.write',{})
|
||||
checkallpass('io.write',{somestring})
|
||||
checkallpass('io.write',{somestring,somestring})
|
||||
checkallerrors('io.write',{nonstring},'bad argument')
|
||||
checkallerrors('io.write',{somestring,nonstring},'bad argument')
|
||||
|
||||
-- file:write ()
|
||||
banner('file:write')
|
||||
file = io.open("seektest.txt","w")
|
||||
checkallpass('file.write',{{file},somestring})
|
||||
checkallpass('file.write',{{file},somestring,somestring})
|
||||
checkallerrors('file.write',{},'bad argument')
|
||||
checkallerrors('file.write',{{file},nonstring},'bad argument')
|
||||
checkallerrors('file.write',{{file},somestring,nonstring},'bad argument')
|
||||
pcall( file.close, file )
|
||||
|
||||
-- file:seek ([whence] [, offset])
|
||||
banner('file:seek')
|
||||
file = io.open("seektest.txt","r")
|
||||
checkallpass('file.seek',{{file}})
|
||||
checkallpass('file.seek',{{file},{"set","cur","end"}})
|
||||
checkallpass('file.seek',{{file},{"set","cur","end"},{2,"3"}})
|
||||
checkallerrors('file.seek',{},'bad argument')
|
||||
checkallerrors('file.seek',{{file},nonstring},'bad argument')
|
||||
checkallerrors('file.seek',{{file},{"set","cur","end"},nonnumber},'bad argument')
|
||||
|
||||
-- file:setvbuf (mode [, size])
|
||||
banner('file:setvbuf')
|
||||
checkallpass('file.setvbuf',{{file},{"no","full","line"}})
|
||||
checkallpass('file.setvbuf',{{file},{"full"},{1024,"512"}})
|
||||
checkallerrors('file.setvbuf',{},'bad argument')
|
||||
checkallerrors('file.setvbuf',{{file},notastring},'bad argument')
|
||||
checkallerrors('file.setvbuf',{{file},{"full"},nonnumber},'bad argument')
|
||||
|
||||
112
luaj-test/src/test/resources/errors/mathlibargs.lua
Normal file
112
luaj-test/src/test/resources/errors/mathlibargs.lua
Normal file
@@ -0,0 +1,112 @@
|
||||
package.path = "?.lua;test/lua/errors/?.lua"
|
||||
require 'args'
|
||||
|
||||
local tostring = tostring
|
||||
_G.tostring = function(x)
|
||||
local s = tostring(x)
|
||||
return type(x)=='number' and #s>4 and (s:sub(1,5)..'...') or s
|
||||
end
|
||||
|
||||
-- arg type tests for math library functions
|
||||
local somenumber = {1,0.75,'-1','-0.25'}
|
||||
local somepositive = {1,0.75,'2', '2.5'}
|
||||
local notanumber = {nil,astring,aboolean,afunction,atable,athread}
|
||||
local nonnumber = {astring,aboolean,afunction,atable}
|
||||
|
||||
local singleargfunctions = {
|
||||
'abs', 'acos', 'asin', 'atan', 'cos', 'cosh', 'deg', 'exp', 'floor',
|
||||
'rad', 'randomseed', 'sin', 'sinh', 'tan', 'tanh', 'frexp',
|
||||
}
|
||||
|
||||
local singleargposdomain = {
|
||||
'log', 'sqrt', 'ceil',
|
||||
}
|
||||
|
||||
local twoargfunctions = {
|
||||
'atan2',
|
||||
}
|
||||
|
||||
local twoargsposdomain = {
|
||||
'pow', 'fmod',
|
||||
}
|
||||
|
||||
-- single argument tests
|
||||
for i,v in ipairs(singleargfunctions) do
|
||||
local funcname = 'math.'..v
|
||||
banner(funcname)
|
||||
checkallpass(funcname,{somenumber})
|
||||
checkallerrors(funcname,{notanumber},'bad argument')
|
||||
end
|
||||
|
||||
-- single argument, positive domain tests
|
||||
for i,v in ipairs(singleargposdomain) do
|
||||
local funcname = 'math.'..v
|
||||
banner(funcname)
|
||||
checkallpass(funcname,{somepositive})
|
||||
checkallerrors(funcname,{notanumber},'bad argument')
|
||||
end
|
||||
|
||||
-- two-argument tests
|
||||
for i,v in ipairs(twoargfunctions) do
|
||||
local funcname = 'math.'..v
|
||||
banner(funcname)
|
||||
checkallpass(funcname,{somenumber,somenumber})
|
||||
checkallerrors(funcname,{},'bad argument')
|
||||
checkallerrors(funcname,{notanumber},'bad argument')
|
||||
checkallerrors(funcname,{notanumber,somenumber},'bad argument')
|
||||
checkallerrors(funcname,{somenumber},'bad argument')
|
||||
checkallerrors(funcname,{somenumber,notanumber},'bad argument')
|
||||
end
|
||||
|
||||
-- two-argument, positive domain tests
|
||||
for i,v in ipairs(twoargsposdomain) do
|
||||
local funcname = 'math.'..v
|
||||
banner(funcname)
|
||||
checkallpass(funcname,{somepositive,somenumber})
|
||||
checkallerrors(funcname,{},'bad argument')
|
||||
checkallerrors(funcname,{notanumber},'bad argument')
|
||||
checkallerrors(funcname,{notanumber,somenumber},'bad argument')
|
||||
checkallerrors(funcname,{somenumber},'bad argument')
|
||||
checkallerrors(funcname,{somenumber,notanumber},'bad argument')
|
||||
end
|
||||
|
||||
-- math.max
|
||||
banner('math.max')
|
||||
checkallpass('math.max',{somenumber})
|
||||
checkallpass('math.max',{somenumber,somenumber})
|
||||
checkallerrors('math.max',{},'bad argument')
|
||||
checkallerrors('math.max',{nonnumber},'bad argument')
|
||||
checkallerrors('math.max',{somenumber,nonnumber},'bad argument')
|
||||
|
||||
-- math.min
|
||||
banner('math.min')
|
||||
checkallpass('math.min',{somenumber})
|
||||
checkallpass('math.min',{somenumber,somenumber})
|
||||
checkallerrors('math.min',{},'bad argument')
|
||||
checkallerrors('math.min',{nonnumber},'bad argument')
|
||||
checkallerrors('math.min',{somenumber,nonnumber},'bad argument')
|
||||
|
||||
-- math.random
|
||||
local somem = {3,4.5,'6.7'}
|
||||
local somen = {8,9.10,'12.34'}
|
||||
local notamn = {astring,aboolean,atable,afunction}
|
||||
banner('math.random')
|
||||
checkallpass('math.random',{},true)
|
||||
checkallpass('math.random',{somem},true)
|
||||
checkallpass('math.random',{somem,somen},true)
|
||||
checkallpass('math.random',{{-4,-5.6,'-7','-8.9'},{-1,100,23.45,'-1.23'}},true)
|
||||
checkallerrors('math.random',{{-4,-5.6,'-7','-8.9'}},'interval is empty')
|
||||
checkallerrors('math.random',{somen,somem},'interval is empty')
|
||||
checkallerrors('math.random',{notamn,somen},'bad argument')
|
||||
checkallerrors('math.random',{somem,notamn},'bad argument')
|
||||
|
||||
-- math.ldexp
|
||||
local somee = {-3,0,3,9.10,'12.34'}
|
||||
local notae = {nil,astring,aboolean,atable,afunction}
|
||||
banner('math.ldexp')
|
||||
checkallpass('math.ldexp',{somenumber,somee})
|
||||
checkallerrors('math.ldexp',{},'bad argument')
|
||||
checkallerrors('math.ldexp',{notanumber},'bad argument')
|
||||
checkallerrors('math.ldexp',{notanumber,somee},'bad argument')
|
||||
checkallerrors('math.ldexp',{somenumber},'bad argument')
|
||||
checkallerrors('math.ldexp',{somenumber,notae},'bad argument')
|
||||
21
luaj-test/src/test/resources/errors/modulelibargs.lua
Normal file
21
luaj-test/src/test/resources/errors/modulelibargs.lua
Normal file
@@ -0,0 +1,21 @@
|
||||
package.path = "?.lua;test/lua/errors/?.lua"
|
||||
require 'args'
|
||||
|
||||
-- arg type tests for module library functions
|
||||
|
||||
-- require
|
||||
banner('require')
|
||||
checkallpass('require',{{'math','coroutine','package','string','table'}},true)
|
||||
checkallerrors('require',{{anumber}},'not found')
|
||||
checkallerrors('require',{{anil,aboolean,afunction,atable}},'bad argument')
|
||||
|
||||
-- package.loadlib
|
||||
banner('package.loadlib')
|
||||
checkallpass('package.loadlib',{{'foo'},{'bar'}},true)
|
||||
checkallerrors('package.loadlib',{notastring},'bad argument')
|
||||
|
||||
-- package.seeall
|
||||
banner('package.seeall')
|
||||
checkallpass('package.seeall',{sometable})
|
||||
checkallerrors('package.seeall',{notatable},'bad argument')
|
||||
|
||||
157
luaj-test/src/test/resources/errors/operators.lua
Normal file
157
luaj-test/src/test/resources/errors/operators.lua
Normal file
@@ -0,0 +1,157 @@
|
||||
package.path = "?.lua;test/lua/errors/?.lua"
|
||||
require 'args'
|
||||
|
||||
-- arg types for language operator
|
||||
|
||||
-- ========= unary operators: - # not
|
||||
|
||||
-- unary minus -
|
||||
banner('unary -')
|
||||
negative = function(a) return - a end
|
||||
checkallpass('negative',{somenumber})
|
||||
checkallerrors('negative',{notanumber},'attempt to perform arithmetic')
|
||||
|
||||
-- length
|
||||
banner('#')
|
||||
lengthop = function(a) return #a end
|
||||
checkallpass('lengthop',{sometable})
|
||||
checkallerrors('lengthop',{notatable},'attempt to get length of')
|
||||
|
||||
-- length
|
||||
banner('not')
|
||||
notop = function(a) return not a end
|
||||
checkallpass('notop',{somenumber})
|
||||
checkallpass('notop',{notanumber})
|
||||
|
||||
-- function call
|
||||
banner( '()' )
|
||||
funcop = function(a) return a() end
|
||||
checkallpass('funcop',{somefunction})
|
||||
checkallerrors('funcop',{notafunction},'attempt to call')
|
||||
|
||||
-- ========= binary ops: .. + - * / % ^ == ~= <= >= < > [] . and or
|
||||
banner( '..' )
|
||||
concatop = function(a,b) return a..b end
|
||||
checkallpass('concatop',{somestring,somestring})
|
||||
checkallerrors('concatop',{notastring,somestring},'attempt to concatenate')
|
||||
checkallerrors('concatop',{somestring,notastring},'attempt to concatenate')
|
||||
|
||||
banner( '+' )
|
||||
plusop = function(a,b) return a+b end
|
||||
checkallpass('plusop',{somenumber,somenumber})
|
||||
checkallerrors('plusop',{notanumber,somenumber},'attempt to perform arithmetic')
|
||||
checkallerrors('plusop',{somenumber,notanumber},'attempt to perform arithmetic')
|
||||
|
||||
banner( '-' )
|
||||
minusop = function(a,b) return a-b end
|
||||
checkallpass('minusop',{somenumber,somenumber})
|
||||
checkallerrors('minusop',{notanumber,somenumber},'attempt to perform arithmetic')
|
||||
checkallerrors('minusop',{somenumber,notanumber},'attempt to perform arithmetic')
|
||||
|
||||
banner( '*' )
|
||||
timesop = function(a,b) return a*b end
|
||||
checkallpass('timesop',{somenumber,somenumber})
|
||||
checkallerrors('timesop',{notanumber,somenumber},'attempt to perform arithmetic')
|
||||
checkallerrors('timesop',{somenumber,notanumber},'attempt to perform arithmetic')
|
||||
|
||||
banner( '/' )
|
||||
divideop = function(a,b) return a/b end
|
||||
checkallpass('divideop',{somenumber,somenumber})
|
||||
checkallerrors('divideop',{notanumber,somenumber},'attempt to perform arithmetic')
|
||||
checkallerrors('divideop',{somenumber,notanumber},'attempt to perform arithmetic')
|
||||
|
||||
banner( '%' )
|
||||
modop = function(a,b) return a%b end
|
||||
checkallpass('modop',{somenumber,somenumber})
|
||||
checkallerrors('modop',{notanumber,somenumber},'attempt to perform arithmetic')
|
||||
checkallerrors('modop',{somenumber,notanumber},'attempt to perform arithmetic')
|
||||
|
||||
banner( '^' )
|
||||
powerop = function(a,b) return a^b end
|
||||
checkallpass('powerop',{{2,'2.5'},{3,'3.5'}})
|
||||
checkallerrors('powerop',{notanumber,{3,'3.1'}},'attempt to perform arithmetic')
|
||||
checkallerrors('powerop',{{2,'2.1'},notanumber},'attempt to perform arithmetic')
|
||||
|
||||
banner( '==' )
|
||||
equalsop = function(a,b) return a==b end
|
||||
checkallpass('equalsop',{anylua,anylua})
|
||||
|
||||
banner( '~=' )
|
||||
noteqop = function(a,b) return a~=b end
|
||||
checkallpass('noteqop',{anylua,anylua})
|
||||
|
||||
banner( '<=' )
|
||||
leop = function(a,b) return a<=b end
|
||||
checkallpass('leop',{{anumber},{anumber}})
|
||||
checkallpass('leop',{{astring,astrnum},{astring,astrnum}})
|
||||
checkallerrors('leop',{notanumber,{anumber}},'attempt to compare')
|
||||
checkallerrors('leop',{{astrnum},{anumber}},'attempt to compare')
|
||||
checkallerrors('leop',{notastring,{astring,astrnum}},'attempt to compare')
|
||||
checkallerrors('leop',{{anumber},notanumber},'attempt to compare')
|
||||
checkallerrors('leop',{{anumber},{astrnum}},'attempt to compare')
|
||||
checkallerrors('leop',{{astring,astrnum},notastring},'attempt to compare')
|
||||
|
||||
banner( '>=' )
|
||||
geop = function(a,b) return a>=b end
|
||||
checkallpass('geop',{{anumber},{anumber}})
|
||||
checkallpass('geop',{{astring,astrnum},{astring,astrnum}})
|
||||
checkallerrors('geop',{notanumber,{anumber}},'attempt to compare')
|
||||
checkallerrors('geop',{{astrnum},{anumber}},'attempt to compare')
|
||||
checkallerrors('geop',{notastring,{astring,astrnum}},'attempt to compare')
|
||||
checkallerrors('geop',{{anumber},notanumber},'attempt to compare')
|
||||
checkallerrors('geop',{{anumber},{astrnum}},'attempt to compare')
|
||||
checkallerrors('geop',{{astring,astrnum},notastring},'attempt to compare')
|
||||
|
||||
banner( '<' )
|
||||
ltop = function(a,b) return a<b end
|
||||
checkallpass('ltop',{{anumber},{anumber}})
|
||||
checkallpass('ltop',{{astring,astrnum},{astring,astrnum}})
|
||||
checkallerrors('ltop',{notanumber,{anumber}},'attempt to compare')
|
||||
checkallerrors('ltop',{{astrnum},{anumber}},'attempt to compare')
|
||||
checkallerrors('ltop',{notastring,{astring,astrnum}},'attempt to compare')
|
||||
checkallerrors('ltop',{{anumber},notanumber},'attempt to compare')
|
||||
checkallerrors('ltop',{{anumber},{astrnum}},'attempt to compare')
|
||||
checkallerrors('ltop',{{astring,astrnum},notastring},'attempt to compare')
|
||||
|
||||
banner( '>' )
|
||||
gtop = function(a,b) return a>b end
|
||||
checkallpass('gtop',{{anumber},{anumber}})
|
||||
checkallpass('gtop',{{astring,astrnum},{astring,astrnum}})
|
||||
checkallerrors('gtop',{notanumber,{anumber}},'attempt to compare')
|
||||
checkallerrors('gtop',{{astrnum},{anumber}},'attempt to compare')
|
||||
checkallerrors('gtop',{notastring,{astring,astrnum}},'attempt to compare')
|
||||
checkallerrors('gtop',{{anumber},notanumber},'attempt to compare')
|
||||
checkallerrors('gtop',{{anumber},{astrnum}},'attempt to compare')
|
||||
checkallerrors('gtop',{{astring,astrnum},notastring},'attempt to compare')
|
||||
|
||||
banner( '[]' )
|
||||
bracketop = function(a,b) return a[b] end
|
||||
checkallpass('bracketop',{sometable,notanil})
|
||||
checkallerrors('bracketop',{notatable,notanil},'attempt to index')
|
||||
checkallerrors('bracketop',{sometable},'attempt to index')
|
||||
|
||||
banner( '.' )
|
||||
dotop = function(a,b) return a.b end
|
||||
checkallpass('dotop',{sometable,notanil})
|
||||
checkallerrors('dotop',{notatable,notanil},'attempt to index')
|
||||
checkallerrors('dotop',{sometable},'attempt to index')
|
||||
|
||||
banner( 'and' )
|
||||
types = {['table']='table',['function']='function',['thread']='thread'}
|
||||
clean = function(x) return types[type(x)] or x end
|
||||
andop = function(a,b) return clean(a and b) end
|
||||
checkallpass('andop',{anylua,anylua})
|
||||
|
||||
banner( 'or' )
|
||||
orop = function(a,b) return clean(a or b) end
|
||||
checkallpass('orop',{anylua,anylua})
|
||||
|
||||
-- ========= for x in y
|
||||
banner( 'for x=a,b,c' )
|
||||
forop = function(a,b,c) for x=a,b,c do end end
|
||||
checkallpass('forop',{{1,'1.1'},{10,'10.1'},{2,'2.1'}})
|
||||
checkallerrors('forop',{notanumber,{10,'10.1'},{2,'2.1'}},"'for' initial value must be a number")
|
||||
checkallerrors('forop',{{1,'1.1'},notanumber,{2,'2.1'}},"'for' limit must be a number")
|
||||
checkallerrors('forop',{{1,'1.1'},{10,'10.1'},notanumber},"'for' step must be a number")
|
||||
|
||||
|
||||
0
luaj-test/src/test/resources/errors/seektest.txt
Normal file
0
luaj-test/src/test/resources/errors/seektest.txt
Normal file
120
luaj-test/src/test/resources/errors/stringlibargs.lua
Normal file
120
luaj-test/src/test/resources/errors/stringlibargs.lua
Normal file
@@ -0,0 +1,120 @@
|
||||
package.path = "?.lua;test/lua/errors/?.lua"
|
||||
require 'args'
|
||||
|
||||
-- arg type tests for string library functions
|
||||
|
||||
-- string.byte
|
||||
banner('string.byte')
|
||||
checkallpass('string.byte',{somestring})
|
||||
checkallpass('string.byte',{somestring,somenumber})
|
||||
checkallpass('string.byte',{somestring,somenumber,somenumber})
|
||||
checkallerrors('string.byte',{somestring,{astring,afunction,atable}},'bad argument')
|
||||
checkallerrors('string.byte',{notastring,{nil,111,n=2}},'bad argument')
|
||||
|
||||
-- string.char
|
||||
function string_char(...)
|
||||
return string.byte( string.char( ... ) )
|
||||
end
|
||||
banner('string_char')
|
||||
checkallpass('string.char',{{60}})
|
||||
checkallpass('string.char',{{60},{70}})
|
||||
checkallpass('string.char',{{60},{70},{80}})
|
||||
checkallpass('string_char',{{0,9,40,127,128,255,'0','9','255','9.2',9.2}})
|
||||
checkallpass('string_char',{{0,127,255},{0,127,255}})
|
||||
checkallerrors('string_char',{},'bad argument')
|
||||
checkallerrors('string_char',{{nil,-1,256,3}},'bad argument')
|
||||
checkallerrors('string_char',{notanumber,{23,'45',6.7}},'bad argument')
|
||||
checkallerrors('string_char',{{23,'45',6.7},nonnumber},'bad argument')
|
||||
|
||||
-- string.dump
|
||||
banner('string.dump')
|
||||
local someupval = 435
|
||||
local function funcwithupvals() return someupval end
|
||||
checkallpass('string.dump',{{function() return 123 end}})
|
||||
checkallpass('string.dump',{{funcwithupvals}})
|
||||
checkallerrors('string.dump',{notafunction},'bad argument')
|
||||
|
||||
-- string.find
|
||||
banner('string.find')
|
||||
checkallpass('string.find',{somestring,somestring})
|
||||
checkallpass('string.find',{somestring,somestring,{nil,-3,3,n=3}})
|
||||
checkallpass('string.find',{somestring,somestring,somenumber,anylua})
|
||||
checkallerrors('string.find',{notastring,somestring},'bad argument')
|
||||
checkallerrors('string.find',{somestring,notastring},'bad argument')
|
||||
checkallerrors('string.find',{somestring,somestring,nonnumber},'bad argument')
|
||||
|
||||
-- string.format
|
||||
--local numfmts = {'%c','%d','%E','%e','%f','%g','%G','%i','%o','%u','%X','%x'}
|
||||
local numfmts = {'%c','%d','%i','%o','%u','%X','%x'}
|
||||
local strfmts = {'%q','%s'}
|
||||
local badfmts = {'%w'}
|
||||
banner('string.format')
|
||||
checkallpass('string.format',{somestring,anylua})
|
||||
checkallpass('string.format',{numfmts,somenumber})
|
||||
checkallpass('string.format',{strfmts,somestring})
|
||||
checkallerrors('string.format',{numfmts,notanumber},'bad argument')
|
||||
checkallerrors('string.format',{strfmts,notastring},'bad argument')
|
||||
checkallerrors('string.format',{badfmts,somestring},"invalid option '%w'")
|
||||
|
||||
-- string.gmatch
|
||||
banner('string.gmatch')
|
||||
checkallpass('string.gmatch',{somestring,somestring})
|
||||
checkallerrors('string.gmatch',{notastring,somestring},'bad argument')
|
||||
checkallerrors('string.gmatch',{somestring,notastring},'bad argument')
|
||||
|
||||
-- string.gsub
|
||||
local somerepl = {astring,atable,afunction}
|
||||
local notarepl = {nil,aboolean,n=2}
|
||||
banner('string.gsub')
|
||||
checkallpass('string.gsub',{somestring,somestring,somerepl,{nil,-1,n=2}})
|
||||
checkallerrors('string.gsub',{nonstring,somestring,somerepl},'bad argument')
|
||||
checkallerrors('string.gsub',{somestring,nonstring,somerepl},'bad argument')
|
||||
checkallerrors('string.gsub',{{astring},{astring},notarepl},'bad argument')
|
||||
checkallerrors('string.gsub',{{astring},{astring},somerepl,nonnumber},'bad argument')
|
||||
|
||||
-- string.len
|
||||
banner('string.len')
|
||||
checkallpass('string.len',{somestring})
|
||||
checkallerrors('string.len',{notastring},'bad argument')
|
||||
|
||||
-- string.lower
|
||||
banner('string.lower')
|
||||
checkallpass('string.lower',{somestring})
|
||||
checkallerrors('string.lower',{notastring},'bad argument')
|
||||
|
||||
-- string.match
|
||||
banner('string.match')
|
||||
checkallpass('string.match',{somestring,somestring})
|
||||
checkallpass('string.match',{somestring,somestring,{nil,-3,3,n=3}})
|
||||
checkallerrors('string.match',{},'bad argument')
|
||||
checkallerrors('string.match',{nonstring,somestring},'bad argument')
|
||||
checkallerrors('string.match',{somestring},'bad argument')
|
||||
checkallerrors('string.match',{somestring,nonstring},'bad argument')
|
||||
checkallerrors('string.match',{somestring,somestring,notanumber},'bad argument')
|
||||
|
||||
-- string.reverse
|
||||
banner('string.reverse')
|
||||
checkallpass('string.reverse',{somestring})
|
||||
checkallerrors('string.reverse',{notastring},'bad argument')
|
||||
|
||||
-- string.rep
|
||||
banner('string.rep')
|
||||
checkallpass('string.rep',{somestring,somenumber})
|
||||
checkallerrors('string.rep',{notastring,somenumber},'bad argument')
|
||||
checkallerrors('string.rep',{somestring,notanumber},'bad argument')
|
||||
|
||||
-- string.sub
|
||||
banner('string.sub')
|
||||
checkallpass('string.sub',{somestring,somenumber})
|
||||
checkallpass('string.sub',{somestring,somenumber,somenumber})
|
||||
checkallerrors('string.sub',{},'bad argument')
|
||||
checkallerrors('string.sub',{nonstring,somenumber,somenumber},'bad argument')
|
||||
checkallerrors('string.sub',{somestring},'bad argument')
|
||||
checkallerrors('string.sub',{somestring,nonnumber,somenumber},'bad argument')
|
||||
checkallerrors('string.sub',{somestring,somenumber,nonnumber},'bad argument')
|
||||
|
||||
-- string.upper
|
||||
banner('string.upper')
|
||||
checkallpass('string.upper',{somestring})
|
||||
checkallerrors('string.upper',{notastring},'bad argument')
|
||||
|
||||
70
luaj-test/src/test/resources/errors/tablelibargs.lua
Normal file
70
luaj-test/src/test/resources/errors/tablelibargs.lua
Normal file
@@ -0,0 +1,70 @@
|
||||
package.path = "?.lua;test/lua/errors/?.lua"
|
||||
require 'args'
|
||||
|
||||
-- arg type tests for table library functions
|
||||
|
||||
-- table.concat
|
||||
local somestringstable = {{8,7,6,5,4,3,2,1,}}
|
||||
local somenonstringtable = {{true,true,true,true,true,true,true,true,}}
|
||||
local somesep = {',',1.23}
|
||||
local notasep = {aboolean,atable,afunction}
|
||||
local somei = {2,'2','2.2'}
|
||||
local somej = {4,'4','4.4'}
|
||||
local notij = {astring,aboolean,atable,afunction}
|
||||
banner('table.concat')
|
||||
checkallpass('table.concat',{somestringstable})
|
||||
checkallpass('table.concat',{somestringstable,somesep})
|
||||
checkallpass('table.concat',{somestringstable,{'-'},somei})
|
||||
checkallpass('table.concat',{somestringstable,{'-'},{2},somej})
|
||||
checkallerrors('table.concat',{notatable},'bad argument')
|
||||
checkallerrors('table.concat',{somenonstringtable},'boolean')
|
||||
checkallerrors('table.concat',{somestringstable,notasep},'bad argument')
|
||||
checkallerrors('table.concat',{somestringstable,{'-'},notij},'bad argument')
|
||||
checkallerrors('table.concat',{somestringstable,{'-'},{2},notij},'bad argument')
|
||||
|
||||
-- table.insert
|
||||
banner('table.insert')
|
||||
checkallpass('table.insert',{sometable,notanil})
|
||||
checkallpass('table.insert',{sometable,somei,notanil})
|
||||
checkallerrors('table.insert',{notatable,somestring},'bad argument')
|
||||
checkallerrors('table.insert',{sometable,notij,notanil},'bad argument')
|
||||
|
||||
-- table.remove
|
||||
banner('table.remove')
|
||||
checkallpass('table.remove',{sometable})
|
||||
checkallpass('table.remove',{sometable,somei})
|
||||
checkallerrors('table.remove',{notatable},'bad argument')
|
||||
checkallerrors('table.remove',{notatable,somei},'bad argument')
|
||||
checkallerrors('table.remove',{sometable,notij},'bad argument')
|
||||
|
||||
-- table.sort
|
||||
local somecomp = {nil,afunction,n=2}
|
||||
local notacomp = {astring,anumber,aboolean,atable}
|
||||
banner('table.sort')
|
||||
checkallpass('table.sort',{somestringstable,somecomp})
|
||||
checkallerrors('table.sort',{sometable},'attempt to')
|
||||
checkallerrors('table.sort',{notatable,somecomp},'bad argument')
|
||||
checkallerrors('table.sort',{sometable,notacomp},'bad argument')
|
||||
|
||||
-- table get
|
||||
banner('table_get - tbl[key]')
|
||||
function table_get(tbl,key) return tbl[key] end
|
||||
checkallpass('table_get',{sometable,anylua})
|
||||
|
||||
-- table set
|
||||
banner('table_set - tbl[key]=val')
|
||||
function table_set(tbl,key,val) tbl[key]=val end
|
||||
function table_set_nil_key(tbl,val) tbl[nil]=val end
|
||||
checkallpass('table_set',{sometable,notanil,anylua})
|
||||
checkallerrors('table_set_nil_key',{sometable,anylua},'table index')
|
||||
|
||||
-- table.unpack
|
||||
banner('table.unpack')
|
||||
checkallpass('table.unpack',{sometable})
|
||||
checkallpass('table.unpack',{sometable,{3,'5'}})
|
||||
checkallpass('table.unpack',{sometable,{3,'5'},{1.25,'7'}})
|
||||
checkallerrors('table.unpack',{notatable,somenumber,somenumber},'bad argument')
|
||||
checkallerrors('table.unpack',{sometable,nonnumber,somenumber},'bad argument')
|
||||
checkallerrors('table.unpack',{sometable,somenumber,nonnumber},'bad argument')
|
||||
|
||||
|
||||
74
luaj-test/src/test/resources/functions.lua
Normal file
74
luaj-test/src/test/resources/functions.lua
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
function f0() print( "f0:" ) end
|
||||
function f1(a) print( "f1:", a ) end
|
||||
function f2(a,b) print( "f2:", a, b ) end
|
||||
function f3(a,b,c) print( "f3:", a, b, c ) end
|
||||
function f4(a,b,c,d) print( "f4:", a, b, c, d ) end
|
||||
|
||||
f0() f0( "a1/1" ) f0( "a1/2", "a2/2" ) f0( "a1/3", "a2/3", "a3/3" ) f0( "a1/4", "a2/4", "a3/4", "a4/4" )
|
||||
f1() f1( "a1/1" ) f1( "a1/2", "a2/2" ) f1( "a1/3", "a2/3", "a3/3" ) f1( "a1/4", "a2/4", "a3/4", "a4/4" )
|
||||
f2() f2( "a1/1" ) f2( "a1/2", "a2/2" ) f2( "a1/3", "a2/3", "a3/3" ) f2( "a1/4", "a2/4", "a3/4", "a4/4" )
|
||||
f3() f3( "a1/1" ) f3( "a1/2", "a2/2" ) f3( "a1/3", "a2/3", "a3/3" ) f3( "a1/4", "a2/4", "a3/4", "a4/4" )
|
||||
f4() f4( "a1/1" ) f4( "a1/2", "a2/2" ) f4( "a1/3", "a2/3", "a3/3" ) f4( "a1/4", "a2/4", "a3/4", "a4/4" )
|
||||
|
||||
function g0(a,b,c,d) return end
|
||||
function g1(a,b,c,d) return d end
|
||||
function g2(a,b,c,d) return c, d end
|
||||
function g3(a,b,c,d) return b, c, d end
|
||||
function g4(a,b,c,d) return a, b, c, d end
|
||||
|
||||
z = g0("c0.1/4", "c0.2/4", "c0.3/4", "c0.4/4")
|
||||
print( "z0:", z )
|
||||
z = g2("c2.1/4", "c2.2/4", "c2.3/4", "c2.4/4")
|
||||
print( "z2:", z )
|
||||
z = g4("c4.1/4", "c4.2/4", "c4.3/4", "c4.4/4")
|
||||
print( "z4:", z )
|
||||
|
||||
a,b,c,d = g0( "c0.1/4", "c0.2/4", "c0.3/4", "c0.4/4" )
|
||||
print( "g0:", a, b, c, d, "(eol)" )
|
||||
a,b,c,d = g2( "b2.1/4", "b2.2/4", "b2.3/4", "b2.4/4" )
|
||||
print( "g2:", a, b, c, d, "(eol)" )
|
||||
a,b,c,d = g4( "b4.1/4", "b4.2/4", "b4.3/4", "b4.4/4" )
|
||||
print( "g4:", a, b, c, d, "(eol)" )
|
||||
|
||||
function func(a,b,c)
|
||||
return a, b, c
|
||||
end
|
||||
|
||||
print( func(11, 12, 13) )
|
||||
print( func(23, 22, 21) )
|
||||
print( func(func(32,33,34), func(45,46,47), func(58,59,50)) )
|
||||
|
||||
function p(a,...)
|
||||
print("a",a)
|
||||
print("...",...)
|
||||
print("...,a",...,a)
|
||||
print("a,...",a,...)
|
||||
end
|
||||
p()
|
||||
p("q")
|
||||
p("q","r")
|
||||
p("q","r","s")
|
||||
|
||||
-- tail call tests
|
||||
function first(...)
|
||||
return 'abc', ..., '|', ...
|
||||
end
|
||||
|
||||
function second(a,...)
|
||||
return 'def', ..., '|', a, ...
|
||||
end
|
||||
|
||||
function third( a, b, c )
|
||||
print( 'third', first( a, b, c ) )
|
||||
print( 'third', second( a, b, c ) )
|
||||
return second( a, b, c )
|
||||
end
|
||||
|
||||
print( 'third', third() )
|
||||
print( 'third', third('p') )
|
||||
print( 'third', third('p','q') )
|
||||
print( 'third', third('p','q','r') )
|
||||
print( 'third', third('p','q','r','s') )
|
||||
print( 'third', third() )
|
||||
|
||||
153
luaj-test/src/test/resources/iolib.lua
Normal file
153
luaj-test/src/test/resources/iolib.lua
Normal file
@@ -0,0 +1,153 @@
|
||||
local platform = ...
|
||||
--print( 'platform', platform )
|
||||
|
||||
-- simple io-library tests
|
||||
--
|
||||
-- C version on Windows will add change \n into \r\n for text files at least
|
||||
--
|
||||
local tostr,files,nfiles = tostring,{},0
|
||||
tostring = function(x)
|
||||
local s = tostr(x)
|
||||
if s:sub(1,4) ~= 'file' then return s end
|
||||
if files[s] then return files[s] end
|
||||
files[s] = 'file.'..nfiles
|
||||
nfiles = nfiles + 1
|
||||
return files[s]
|
||||
end
|
||||
print( io ~= nil )
|
||||
print( io.open ~= nil )
|
||||
print( io.stdin ~= nil )
|
||||
print( io.stdout ~= nil )
|
||||
print( io.stderr ~= nil )
|
||||
print( 'write', io.write() )
|
||||
print( 'write', io.write("This") )
|
||||
print( 'write', io.write(" is a pen.") )
|
||||
print( 'flush', io.flush() )
|
||||
|
||||
local f = io.open("abc.txt","w")
|
||||
print( 'f', type(f) )
|
||||
print( io.type(f) )
|
||||
print( 'write', f:write("abcdef 12345 \t\t 678910 more\aaaaaaa\bbbbthe rest") )
|
||||
print( 'type(f)', io.type(f) )
|
||||
print( 'close', f:close() )
|
||||
print( 'type(f)', io.type(f) )
|
||||
print( 'type("f")', io.type("f") )
|
||||
|
||||
local g = io.open("abc.txt","r")
|
||||
local t = { g:read(3, 3, "*n", "*n", "*l", "*l", "*a") }
|
||||
for i,v in ipairs(t) do
|
||||
print( string.format("%q",tostring(v)), type(v))
|
||||
print( '----- ', i )
|
||||
end
|
||||
|
||||
local h,s = io.open("abc.txt", "a")
|
||||
print( 'h', io.type(h), string.sub(tostring(h),1,6), s )
|
||||
print( 'write', h:write('and more and more and more text.') )
|
||||
print( 'close', h:close() )
|
||||
|
||||
if platform ~= 'JME' then
|
||||
local j = io.open( "abc.txt", "r" )
|
||||
print( 'j', io.type(j) )
|
||||
print( 'seek', j:seek("set", 3) )
|
||||
print( 'read', j:read(4), j:read(3) )
|
||||
print( 'seek', j:seek("set", 2) )
|
||||
print( 'read', j:read(4), j:read(3) )
|
||||
print( 'seek', j:seek("cur", -8 ) )
|
||||
print( 'read', j:read(4), j:read(3) )
|
||||
print( 'seek(cur,0)', j:seek("cur",0) )
|
||||
print( 'seek(cur,20)', j:seek("cur",20) )
|
||||
print( 'seek(end,-5)', j:seek("end", -5) )
|
||||
print( 'read(4)', string.format("%q", tostring(j:read(4))) )
|
||||
print( 'read(4)', string.format("%q", tostring(j:read(4))) )
|
||||
print( 'read(4)', string.format("%q", tostring(j:read(4))) )
|
||||
print( 'close', j:close() )
|
||||
end
|
||||
|
||||
-- write a few lines, including a non-terminating one
|
||||
files = {}
|
||||
f = io.open("abc.txt","w")
|
||||
print( 'f.type', io.type(f) )
|
||||
print( 'f', f )
|
||||
print( 'write', f:write("line one\nline two\n\nafter blank line\nunterminated line") )
|
||||
print( 'type(f)', io.type(f) )
|
||||
print( 'close', f:close() )
|
||||
files = {}
|
||||
|
||||
-- read using io.lines()
|
||||
for l in io.lines("abc.txt") do
|
||||
print( string.format('%q',l) )
|
||||
end
|
||||
io.input("abc.txt")
|
||||
for l in io.lines() do
|
||||
print( string.format('%q',l) )
|
||||
end
|
||||
io.input(io.open("abc.txt","r"))
|
||||
for l in io.lines() do
|
||||
print( string.format('%q',l) )
|
||||
end
|
||||
io.input("abc.txt")
|
||||
io.input(io.input())
|
||||
for l in io.lines() do
|
||||
print( string.format('%q',l) )
|
||||
end
|
||||
|
||||
local count = 0
|
||||
io.tmpfile = function()
|
||||
count = count + 1
|
||||
return io.open("tmp"..count..".out","w")
|
||||
end
|
||||
|
||||
local a = io.tmpfile()
|
||||
local b = io.tmpfile()
|
||||
print( io.type(a) )
|
||||
print( io.type(b) )
|
||||
print( "a:write", a:write('aaaaaaa') )
|
||||
print( "b:write", b:write('bbbbbbb') )
|
||||
print( "a:setvbuf", a:setvbuf("no") )
|
||||
print( "a:setvbuf", a:setvbuf("full",1024) )
|
||||
print( "a:setvbuf", a:setvbuf("line") )
|
||||
print( "a:write", a:write('ccccc') )
|
||||
print( "b:write", b:write('ddddd') )
|
||||
print( "a:flush", a:flush() )
|
||||
print( "b:flush", b:flush() )
|
||||
--[[
|
||||
print( "a:read", a:read(7) )
|
||||
print( "b:read", b:read(7) )
|
||||
print( "a:seek", a:seek("cur",-4) )
|
||||
print( "b:seek", b:seek("cur",-4) )
|
||||
print( "a:read", ( a:read(7) ) )
|
||||
print( "b:read", ( b:read(7) ) )
|
||||
print( "a:seek", a:seek("cur",-8) )
|
||||
print( "b:seek", b:seek("cur",-8) )
|
||||
print( "a:read", ( a:read(7) ) )
|
||||
print( "b:read", ( b:read(7) ) )
|
||||
--]]
|
||||
|
||||
local pcall = function(...)
|
||||
local s,e = pcall(...)
|
||||
if s then return s end
|
||||
return s,e:match("closed")
|
||||
end
|
||||
|
||||
print( 'a:close', pcall( a.close, a ) )
|
||||
print( 'a:write', pcall( a.write, a, 'eee') )
|
||||
print( 'a:flush', pcall( a.flush, a) )
|
||||
print( 'a:read', pcall( a.read, a, 5) )
|
||||
print( 'a:lines', pcall( a.lines, a) )
|
||||
print( 'a:seek', pcall( a.seek, a, "cur", -2) )
|
||||
print( 'a:setvbuf', pcall( a.setvbuf, a, "no") )
|
||||
print( 'a:close', pcall( a.close, a ) )
|
||||
print( 'io.type(a)', pcall( io.type, a ) )
|
||||
|
||||
print( 'io.close()', pcall( io.close ) )
|
||||
print( 'io.close(io.output())', pcall( io.close, io.output() ) )
|
||||
|
||||
io.output('abc.txt')
|
||||
print( 'io.close()', pcall( io.close ) )
|
||||
print( 'io.write', pcall( io.write, 'eee') )
|
||||
print( 'io.flush', pcall( io.flush) )
|
||||
print( 'io.close', pcall( io.close ) )
|
||||
io.input('abc.txt'):close()
|
||||
print( 'io.read', pcall( io.read, 5) )
|
||||
print( 'io.lines', pcall( io.lines) )
|
||||
|
||||
37
luaj-test/src/test/resources/manyupvals.lua
Normal file
37
luaj-test/src/test/resources/manyupvals.lua
Normal file
@@ -0,0 +1,37 @@
|
||||
local t = {}
|
||||
local template = [[
|
||||
local f<i>
|
||||
do
|
||||
local result
|
||||
function f<i>()
|
||||
if not result then
|
||||
result = f<i-2>() + f<i-1>()
|
||||
end
|
||||
return result
|
||||
end
|
||||
end
|
||||
]]
|
||||
t[1] = [[
|
||||
local f1
|
||||
f1 = function() return 1 end
|
||||
]]
|
||||
t[2] = [[
|
||||
local f2
|
||||
f2 = function() return 1 end
|
||||
]]
|
||||
for i = 3, 199 do
|
||||
t[i] = template:gsub("<([^>]+)>", function(s)
|
||||
local c = assert(load('return '..s, 'f'..i, 'bt', { i = i }), 'could not compile: '..s)
|
||||
return c()
|
||||
end)
|
||||
end
|
||||
t[200] = [[
|
||||
print("5th fibonacci number is", f5())
|
||||
print("10th fibonacci number is", f10())
|
||||
print("199th fibonacci number is", f199())
|
||||
]]
|
||||
|
||||
local s = table.concat(t)
|
||||
print(s)
|
||||
f = load(s)
|
||||
f()
|
||||
239
luaj-test/src/test/resources/mathlib.lua
Normal file
239
luaj-test/src/test/resources/mathlib.lua
Normal file
@@ -0,0 +1,239 @@
|
||||
local platform = ...
|
||||
--print( 'platform', platform )
|
||||
|
||||
local aliases = {
|
||||
['0']='<zero>',
|
||||
['-0']='<zero>',
|
||||
['nan']='<nan>',
|
||||
['inf']='<pos-inf>',
|
||||
['-inf']='<neg-inf>',
|
||||
['1.#INF']='<pos-inf>',
|
||||
['-1.#INF']='<neg-inf>',
|
||||
['1.#IND']='<nan>',
|
||||
['-1.#IND']='<nan>',
|
||||
}
|
||||
|
||||
local UNOPVALUES = { -2.5, -2, 0, 2, 2.5, "'-2.5'", "'-2'", "'0'", "'2'", "'2.5'" }
|
||||
|
||||
local NUMBERPAIRS = {
|
||||
{ 2, 0 }, { -2.5, 0 }, { 2, 1 },
|
||||
{ 5, 2 }, {-5, 2 }, {16, 2}, {-16, -2},
|
||||
{ .5, 0}, {.5, 1}, {.5, 2}, {.5, -1}, {.5, 2},
|
||||
{2.25, 0}, {2.25, 2}, {-2, 0},
|
||||
{ 3, 3 },
|
||||
}
|
||||
|
||||
local STRINGPAIRS = {
|
||||
{ "'2'", "'0'" }, { "'2.5'","'3'" }, { "'-2'", "'1.5'" }, { "'-2.5'", "'-1.5'" },
|
||||
{ "'3.0'", "'3.0'" }, { 2.75, 2.75 }, { "'2.75'", "'2.75'" },
|
||||
}
|
||||
|
||||
local MIXEDPAIRS = {
|
||||
{ 3, "'3'" }, { "'3'", 3 }, { 2.75, "'2.75'" }, { "'2.75'", 2.75 },
|
||||
{ -3, "'-4'" }, { "'-3'", 4 }, { -3, "'4'" }, { "'-3'", -4 },
|
||||
{ -4.75, "'2.75'" }, { "'-2.75'", 1.75 }, { 4.75, "'-2.75'" }, { "'2.75'", -1.75 },
|
||||
}
|
||||
|
||||
local BINOPVALUES = {}
|
||||
|
||||
local RELATIONALOPVALUES = {}
|
||||
|
||||
local function addall( t, s )
|
||||
for i,v in ipairs(s) do
|
||||
t[#t+1] = v
|
||||
end
|
||||
end
|
||||
addall( BINOPVALUES, NUMBERPAIRS )
|
||||
addall( BINOPVALUES, STRINGPAIRS )
|
||||
addall( BINOPVALUES, MIXEDPAIRS )
|
||||
addall( RELATIONALOPVALUES, NUMBERPAIRS )
|
||||
addall( RELATIONALOPVALUES, STRINGPAIRS )
|
||||
|
||||
local VARARGSVALUES = {
|
||||
{ 4, }, { -4.5 }, { "'5.5'" }, { "'-5'" },
|
||||
{ 4, "'8'" }, { -4.5, "'-8'" }, { "'5.5'", 2.2 }, { "'-5'", -2.2 },
|
||||
{ 111,222,333 }, { -222,-333,-111 }, { 444,-111,-222 },
|
||||
}
|
||||
|
||||
local CONSTANTS = {
|
||||
"huge", "pi",
|
||||
}
|
||||
local UNARYOPS = {
|
||||
"-", "not ",
|
||||
}
|
||||
local BINARYOPS = {
|
||||
"+", "-", "*", "^", "/", "%",
|
||||
}
|
||||
local RELATIONALS = {
|
||||
"==", "~=", ">", "<", ">=", "<=",
|
||||
}
|
||||
local ONEARG_JME = {
|
||||
"abs", "ceil", "cos", "deg",
|
||||
"exp", "floor", "frexp", "modf",
|
||||
"rad", "sin", "sqrt", "tan",
|
||||
}
|
||||
local ONEARG_JSE = {
|
||||
"acos", "asin", "atan", "cosh",
|
||||
"log", "sinh", "tanh",
|
||||
}
|
||||
local TWOARGS_JME = {
|
||||
"fmod", "ldexp", "pow",
|
||||
}
|
||||
local TWOARGS_JSE = {
|
||||
"atan2",
|
||||
}
|
||||
local VARARGSFUNCS = {
|
||||
"max", "min",
|
||||
}
|
||||
|
||||
local ts = tostring
|
||||
tostring = function(x)
|
||||
local s = ts(x)
|
||||
if type(x)~='number' then return s end
|
||||
if aliases[s] then return aliases[s] end
|
||||
if #s < 7 then return s end
|
||||
local a,b = string.match(s,'([%-0-9%.]*)([eE]?[%-0-9]*)')
|
||||
return a and (string.sub(a,1,6)..(b or '')) or s
|
||||
end
|
||||
|
||||
local function eval( expr, script )
|
||||
script = script or ('return '..expr)
|
||||
local s,a,b = load( script, 'expr' )
|
||||
if s then print( expr, pcall( s ) )
|
||||
else print( expr, 'load:', a ) end
|
||||
end
|
||||
|
||||
-- misc tests
|
||||
print( '---------- miscellaneous tests ----------' )
|
||||
eval( 'math.sin( 0.0 )' )
|
||||
eval( 'math.cos( math.pi )' )
|
||||
eval( 'math.sqrt( 9.0 )' )
|
||||
eval( 'math.modf( 5.25 )')
|
||||
eval( 'math.frexp(0.00625)' )
|
||||
eval( '-5 ^ 2' )
|
||||
eval( '-5 / 2' )
|
||||
eval( '-5 % 2' )
|
||||
|
||||
-- constants
|
||||
print( '---------- constants ----------' )
|
||||
for i,v in ipairs(CONSTANTS) do
|
||||
eval( 'math.'..v )
|
||||
end
|
||||
|
||||
-- unary operators
|
||||
for i,v in ipairs(UNARYOPS) do
|
||||
print( '---------- unary operator '..v..' ----------' )
|
||||
for j,a in ipairs(UNOPVALUES) do
|
||||
eval( v..a, 'return '..v..a )
|
||||
end
|
||||
end
|
||||
|
||||
-- binary operators
|
||||
for i,v in ipairs(BINARYOPS) do
|
||||
print( '---------- binary operator '..v..' ----------' )
|
||||
for j,xy in ipairs(BINOPVALUES) do
|
||||
eval( xy[1]..v..xy[2],
|
||||
'local x,y='..xy[1]..','..xy[2]..'; return x'..v..'y' )
|
||||
end
|
||||
end
|
||||
|
||||
-- relational operators
|
||||
for i,v in ipairs(RELATIONALS) do
|
||||
print( '---------- binary operator '..v..' ----------' )
|
||||
for j,xy in ipairs(RELATIONALOPVALUES) do
|
||||
eval( xy[1]..v..xy[2],
|
||||
'local x,y='..xy[1]..','..xy[2]..'; return x'..v..'y' )
|
||||
end
|
||||
end
|
||||
|
||||
-- one-argument math functions
|
||||
for i,v in ipairs(ONEARG_JME) do
|
||||
print( '---------- math.'..v..' ----------' )
|
||||
for j,x in ipairs(UNOPVALUES) do
|
||||
eval( 'math.'..v..'('..x..')' )
|
||||
end
|
||||
end
|
||||
if platform ~= 'JME' then
|
||||
for i,v in ipairs(ONEARG_JSE) do
|
||||
print( '---------- math.'..v..' (jse only) ----------' )
|
||||
for j,x in ipairs(UNOPVALUES) do
|
||||
eval( 'math.'..v..'('..x..')' )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- two-argument math functions
|
||||
for i,v in ipairs(TWOARGS_JME) do
|
||||
print( '---------- math.'..v..' ----------' )
|
||||
for j,x in ipairs(BINOPVALUES) do
|
||||
eval( 'math.'..v..'('..x[1]..','..x[2]..')' )
|
||||
end
|
||||
end
|
||||
if platform ~= 'JME' then
|
||||
for i,v in ipairs(TWOARGS_JSE) do
|
||||
print( '---------- math.'..v..' (jse only) ----------' )
|
||||
for j,x in ipairs(BINOPVALUES) do
|
||||
eval( 'math.'..v..'('..x[1]..','..x[2]..')' )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- var-arg math functions
|
||||
for i,v in ipairs(VARARGSFUNCS) do
|
||||
print( '---------- math.'..v..' ----------' )
|
||||
for j,x in ipairs(VARARGSVALUES) do
|
||||
eval( 'math.'..v..'('..table.concat(x,',')..')' )
|
||||
end
|
||||
end
|
||||
|
||||
-- random tests
|
||||
print("----------- Random number tests")
|
||||
local function testrandom(string,lo,hi)
|
||||
local c,e = load('return '..string)
|
||||
for i=1,5 do
|
||||
local s,e = pcall(c)
|
||||
if s then
|
||||
print( string, s and type(e) or e, (e>=lo) and (e<=hi) )
|
||||
else
|
||||
print( string, 'error', e )
|
||||
end
|
||||
end
|
||||
end
|
||||
testrandom('math.random()',0,1)
|
||||
testrandom('math.random(5,10)',5,10)
|
||||
testrandom('math.random(30)',0,30)
|
||||
testrandom('math.random(-4,-2)',-4,-2)
|
||||
local t = {}
|
||||
print( math.randomseed(20) )
|
||||
for i=1,20 do
|
||||
t[i] = math.random()
|
||||
end
|
||||
print( '-- comparing new numbers')
|
||||
for i=1,20 do
|
||||
print( t[i] == math.random(), t[i] == t[0] )
|
||||
end
|
||||
print( '-- resetting seed')
|
||||
|
||||
print( math.randomseed(20) )
|
||||
for i=1,20 do
|
||||
print( t[i] == math.random() )
|
||||
end
|
||||
|
||||
-- tests involving -0, which is folded into 0 for luaj, but not for plain lua
|
||||
print("----------- Tests involving -0 and NaN")
|
||||
print('0 == -0', 0 == -0)
|
||||
t = {[0] = 10, 20, 30, 40, 50}
|
||||
print('t[-0] == t[0]',t[-0] == t[0])
|
||||
local x = -1
|
||||
local mz, z = 0/x, 0 -- minus zero, zero
|
||||
print('mz, z', mz, z)
|
||||
print('mz == z', mz == z)
|
||||
local a = {[mz] = 1}
|
||||
print('a[z] == 1 and a[mz] == 1', a[z] == 1 and a[mz] == 1)
|
||||
-- string with same binary representation as 0.0 (may create problems
|
||||
-- for constant manipulation in the pre-compiler)
|
||||
local a1, a2, a3, a4, a5 = 0, 0, "\0\0\0\0\0\0\0\0", 0, "\0\0\0\0\0\0\0\0"
|
||||
assert(a1 == a2 and a2 == a4 and a1 ~= a3)
|
||||
assert(a3 == a5)
|
||||
|
||||
--]]
|
||||
286
luaj-test/src/test/resources/metatags.lua
Normal file
286
luaj-test/src/test/resources/metatags.lua
Normal file
@@ -0,0 +1,286 @@
|
||||
local anumber,bnumber = 111,23.45
|
||||
local astring,bstring = "abc","def"
|
||||
local anumstr,bnumstr = tostring(anumber),tostring(bnumber)
|
||||
local aboolean,bboolean = false,true
|
||||
local afunction,bfunction = function() end, function() end
|
||||
local athread,bthead = coroutine.create(afunction),coroutine.create(bfunction)
|
||||
local atable,btable = {},{}
|
||||
local values = { anumber, aboolean, afunction, athread, atable }
|
||||
local groups
|
||||
local ts = tostring
|
||||
local tb,count = {},0
|
||||
|
||||
tostring = function(o)
|
||||
local t = type(o)
|
||||
if t~='thread' and t~='function' and t~='table' then return ts(o) end
|
||||
if not tb[o] then
|
||||
count = count + 1
|
||||
tb[o] = t..'.'..count
|
||||
end
|
||||
return tb[o]
|
||||
end
|
||||
|
||||
local buildop = function(name)
|
||||
return function(a,b)
|
||||
print( 'mt.__'..name..'()', a, b )
|
||||
return '__'..name..'-result'
|
||||
end
|
||||
end
|
||||
local buildop3 = function(name)
|
||||
return function(a,b,c)
|
||||
print( 'mt.__'..name..'()', a, b, c )
|
||||
return '__'..name..'-result'
|
||||
end
|
||||
end
|
||||
local buildop1 = function(name)
|
||||
return function(a)
|
||||
print( 'mt.__'..name..'()', a )
|
||||
return '__'..name..'-result'
|
||||
end
|
||||
end
|
||||
|
||||
local mt = {
|
||||
__call=buildop('call'),
|
||||
__add=buildop('add'),
|
||||
__sub=buildop('sub'),
|
||||
__mul=buildop('mul'),
|
||||
__div=buildop('div'),
|
||||
__pow=buildop('pow'),
|
||||
__mod=buildop('mod'),
|
||||
__unm=buildop1('unm'),
|
||||
__len=buildop1('len'),
|
||||
__lt=buildop('lt'),
|
||||
__le=buildop('le'),
|
||||
__index=buildop('index'),
|
||||
__newindex=buildop3('newindex'),
|
||||
__concat=buildop('concat'),
|
||||
}
|
||||
|
||||
-- pcall a function and check for a pattern in the error string
|
||||
ecall = function(pattern, ...)
|
||||
local s,e = pcall(...)
|
||||
if not s then e = string.match(e,pattern) or e end
|
||||
return s,e
|
||||
end
|
||||
|
||||
print( '---- __eq same types' )
|
||||
local eqmt = { __eq=buildop('eq'), }
|
||||
groups = { {nil,nil}, {true,false}, {123,456}, {11,5.5}, {afunction,bfunction}, {athread,bthread}, {astring,bstring}, {anumber,anumstr} }
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'before', pcall( function() return a~=b end ) )
|
||||
print( debug.setmetatable( a, eqmt ) )
|
||||
print( debug.setmetatable( b, eqmt ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a~=b end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
print( '---- __eq, tables - should invoke metatag comparison' )
|
||||
groups = { {atable,btable} }
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'before', pcall( function() return a~=b end ) )
|
||||
print( debug.setmetatable( a, eqmt ) )
|
||||
print( debug.setmetatable( b, eqmt ) )
|
||||
print( type(a), type(b), 'after-a', pcall( function() return a==b end ) )
|
||||
print( type(a), type(b), 'after-a', pcall( function() return a~=b end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
|
||||
print( 'nilmt', debug.getmetatable(nil) )
|
||||
print( 'boolmt', debug.getmetatable(true) )
|
||||
print( 'number', debug.getmetatable(1) )
|
||||
print( 'function', debug.getmetatable(afunction) )
|
||||
print( 'thread', debug.getmetatable(athread) )
|
||||
|
||||
print( '---- __call' )
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( type(a), 'before', ecall( 'attempt to call', function() return a('a','b') end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( type(a), 'after', pcall( function() return a() end ) )
|
||||
print( type(a), 'after', pcall( function() return a('a') end ) )
|
||||
print( type(a), 'after', pcall( function() return a('a','b') end ) )
|
||||
print( type(a), 'after', pcall( function() return a('a','b','c') end ) )
|
||||
print( type(a), 'after', pcall( function() return a('a','b','c','d') end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
|
||||
print( '---- __add, __sub, __mul, __div, __pow, __mod' )
|
||||
local groups = { {aboolean, aboolean}, {aboolean, athread}, {aboolean, afunction}, {aboolean, "abc"}, {aboolean, atable} }
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a+b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b+a end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a-b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b-a end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a*b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b*a end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a^b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b^a end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return a%b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to perform arithmetic', function() return b%a end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a+b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return b+a end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a-b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return b-a end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a*b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return b*a end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a^b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return b^a end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a%b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return b%a end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
print( '---- __len' )
|
||||
values = { aboolean, afunction, athread, anumber }
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( type(a), 'before', ecall( 'attempt to get length of ', function() return #a end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( type(a), 'after', pcall( function() return #a end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
--
|
||||
print( '---- __neg' )
|
||||
values = { aboolean, afunction, athread, "abcd", atable, anumber }
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( type(v), 'before', ecall( 'attempt to perform arithmetic ', function() return -a end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( type(v), 'after', pcall( function() return -a end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
|
||||
print( '---- __lt, __le, same types' )
|
||||
local bfunction = function() end
|
||||
local bthread = coroutine.create( bfunction )
|
||||
local btable = {}
|
||||
local groups
|
||||
groups = { {true, true}, {true, false}, {afunction, bfunction}, {athread, bthread}, {atable, atable}, {atable, btable} }
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a<b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a<=b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a>b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a>=b end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( debug.setmetatable( b, mt ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a<b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a<=b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a>b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a>=b end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
print( '---- __lt, __le, different types' )
|
||||
groups = { {aboolean, athread}, }
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a<b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a<=b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a>b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to compare', function() return a>=b end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( debug.setmetatable( b, mt ) )
|
||||
print( type(a), type(b), 'after-a', ecall( 'attempt to compare', function() return a<b end ) )
|
||||
print( type(a), type(b), 'after-a', ecall( 'attempt to compare', function() return a<=b end ) )
|
||||
print( type(a), type(b), 'after-a', ecall( 'attempt to compare', function() return a>b end ) )
|
||||
print( type(a), type(b), 'after-a', ecall( 'attempt to compare', function() return a>=b end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
print( '---- __tostring' )
|
||||
values = { aboolean, afunction, athread, atable, "abc" }
|
||||
local strmt = { __tostring=function(a)
|
||||
return 'mt.__tostring('..type(a)..')'
|
||||
end,
|
||||
}
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( debug.setmetatable( a, strmt ) )
|
||||
print( type(a), 'after', pcall( function() return ts(a) end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
|
||||
print( '---- __index, __newindex' )
|
||||
values = { aboolean, anumber, afunction, athread }
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( type(a), 'before', ecall( 'attempt to index', function() return a.foo end ) )
|
||||
print( type(a), 'before', ecall( 'attempt to index', function() return a[123] end ) )
|
||||
print( type(a), 'before', ecall( 'index', function() a.foo = 'bar' end ) )
|
||||
print( type(a), 'before', ecall( 'index', function() a[123] = 'bar' end ) )
|
||||
print( type(a), 'before', ecall( 'attempt to index', function() return a:foo() end ) )
|
||||
print( debug.setmetatable( a, mt ) )
|
||||
print( type(a), 'after', pcall( function() return a.foo end ) )
|
||||
print( type(a), 'after', pcall( function() return a[123] end ) )
|
||||
print( type(a), 'after', pcall( function() a.foo = 'bar' end ) )
|
||||
print( type(a), 'after', pcall( function() a[123] = 'bar' end ) )
|
||||
print( type(a), 'after', ecall( 'attempt to call', function() return a:foo() end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
|
||||
print( '---- __concat' )
|
||||
groups = { {atable, afunction}, {afunction, atable}, {123, nil}, {nil, 123} }
|
||||
local s,t,u = 'sss',777
|
||||
local concatresult = setmetatable( { '__concat-result' }, {
|
||||
__tostring=function()
|
||||
return 'concat-string-result'
|
||||
end } )
|
||||
local concatmt = {
|
||||
__concat=function(a,b)
|
||||
print( 'mt.__concat('..type(a)..','..type(b)..')', a, b )
|
||||
return concatresult
|
||||
end
|
||||
}
|
||||
for i=1,#groups do
|
||||
local a,b = groups[i][1], groups[i][2]
|
||||
local amt,bmt = debug.getmetatable(a),debug.getmetatable(b)
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to concatenate ', function() return a..b end ) )
|
||||
print( type(a), type(b), 'before', ecall( 'attempt to concatenate ', function() return b..a end ) )
|
||||
print( type(a), type(s), type(t), 'before', ecall( 'attempt to concatenate ', function() return a..s..t end ) )
|
||||
print( type(s), type(a), type(t), 'before', ecall( 'attempt to concatenate ', function() return s..a..t end ) )
|
||||
print( type(s), type(t), type(a), 'before', ecall( 'attempt to concatenate ', function() return s..t..a end ) )
|
||||
print( debug.setmetatable( a, concatmt ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return a..b end ) )
|
||||
print( type(a), type(b), 'after', pcall( function() return b..a end ) )
|
||||
print( type(a), type(s), type(t), 'before', pcall( function() return a..s..t end ) )
|
||||
print( type(s), type(a), type(t), 'before', ecall( 'attempt to concatenate ', function() return s..a..t end ) )
|
||||
print( type(s), type(t), type(a), 'before', ecall( 'attempt to concatenate ', function() return s..t..a end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
print( debug.setmetatable( b, bmt ) )
|
||||
end
|
||||
|
||||
print( '---- __metatable' )
|
||||
values = { aboolean, afunction, athread, atable, "abc" }
|
||||
local mtmt = { __metatable={}, }
|
||||
for i=1,#values do
|
||||
local a = values[i]
|
||||
local amt = debug.getmetatable(a)
|
||||
print( type(a), 'before', pcall( function() return debug.getmetatable(a), getmetatable(a) end ) )
|
||||
print( debug.setmetatable( a, mtmt ) )
|
||||
print( type(a), 'after', pcall( function() return debug.getmetatable(a), getmetatable(a) end ) )
|
||||
print( debug.setmetatable( a, amt ) )
|
||||
end
|
||||
60
luaj-test/src/test/resources/oslib.lua
Normal file
60
luaj-test/src/test/resources/oslib.lua
Normal file
@@ -0,0 +1,60 @@
|
||||
-- simple os-library tests
|
||||
--
|
||||
-- because the nature of the "os" library is to provide os-specific behavior,
|
||||
-- the compatibility tests must be extremely loose, and can really only
|
||||
-- compare things like return value type to be meaningful.
|
||||
--
|
||||
-- actual os behavior needs to go in an oslib function test
|
||||
--
|
||||
local pcall = function(...)
|
||||
local s,e,f = pcall(...)
|
||||
return s,type(e),type(f)
|
||||
end
|
||||
print( 'os', type(os) )
|
||||
print( 'os.clock()', pcall( os.clock ) )
|
||||
print( 'os.date()', pcall( os.date ) )
|
||||
print( 'os.difftime(123000, 21500)', pcall( os.difftime, 123000, 21250 ) )
|
||||
print( 'os.getenv()', pcall( os.getenv ) )
|
||||
print( 'os.getenv("bogus.key")', pcall( os.getenv, 'bogus.key' ) )
|
||||
local s,p = pcall( os.tmpname )
|
||||
local s,q = pcall( os.tmpname )
|
||||
print( 'os.tmpname()', s, p )
|
||||
print( 'os.tmpname()', s, q )
|
||||
-- permission denied on windows
|
||||
--print( 'os.remove(p)', pcall( os.remove, p ) )
|
||||
--print( 'os.rename(p,q)', pcall( os.rename, p, q ) )
|
||||
local s,f = pcall( io.open, p,"w" )
|
||||
print( 'io.open', s, f )
|
||||
print( 'write', pcall( f.write, f, "abcdef 12345" ) )
|
||||
print( 'close', pcall( f.close, f ) )
|
||||
print( 'os.rename(p,q)', pcall( os.rename, p, q ) )
|
||||
print( 'os.remove(q)', pcall( os.remove, q ) )
|
||||
print( 'os.remove(q)', pcall( os.remove, q ) )
|
||||
-- setlocale not supported on jse yet
|
||||
-- print( 'os.setlocale()', pcall( os.setlocale ) )
|
||||
-- print( 'os.setlocale("jp")', pcall( os.setlocale, "jp" ) )
|
||||
-- print( 'os.setlocale("us","monetary")', pcall( os.setlocale, "us", "monetary" ) )
|
||||
-- print( 'os.setlocale(nil,"all")', pcall( os.setlocale, nil, "all" ) )
|
||||
print( 'os.setlocale("C")', pcall( os.setlocale, "C" ) )
|
||||
print( 'os.exit', type(os.exit) )
|
||||
|
||||
-- os.date() formatting
|
||||
local t = 1281364496 -- Aug 9, 2010, 2:34:56 PM (Monday)
|
||||
local function p(s)
|
||||
if pcall(os.date, s, t) then
|
||||
print( "os.date('"..s.."', "..t..")", pcall(os.date, s, t))
|
||||
end
|
||||
end
|
||||
for i= 65, 90 do
|
||||
p('%'..string.char(i + 97 - 65))
|
||||
p('%'..string.char(i))
|
||||
end
|
||||
local tbl = os.date('*t', t)
|
||||
for i,k in ipairs({'year', 'month', 'day', 'hour', 'min', 'sec', 'wday', 'yday', 'isdst'}) do
|
||||
local v = tbl[k]
|
||||
print('k', type(k), k, 'v', type(v), v)
|
||||
end
|
||||
|
||||
print('type(os.time())', type(os.time()))
|
||||
print('os.time({year=1971, month=2, day=25})', os.time({year=1971, month=2, day=25}))
|
||||
print('os.time({year=1971, month=2, day=25, hour=11, min=22, sec=33})', os.time({year=1971, month=2, day=25, hour=11, min=22, sec=33}))
|
||||
50
luaj-test/src/test/resources/perf/binarytrees.lua
Normal file
50
luaj-test/src/test/resources/perf/binarytrees.lua
Normal file
@@ -0,0 +1,50 @@
|
||||
-- The Computer Language Benchmarks Game
|
||||
-- http://shootout.alioth.debian.org/
|
||||
-- contributed by Mike Pall
|
||||
|
||||
local function BottomUpTree(item, depth)
|
||||
if depth > 0 then
|
||||
local i = item + item
|
||||
depth = depth - 1
|
||||
local left, right = BottomUpTree(i-1, depth), BottomUpTree(i, depth)
|
||||
return { item, left, right }
|
||||
else
|
||||
return { item }
|
||||
end
|
||||
end
|
||||
|
||||
local function ItemCheck(tree)
|
||||
if tree[2] then
|
||||
return tree[1] + ItemCheck(tree[2]) - ItemCheck(tree[3])
|
||||
else
|
||||
return tree[1]
|
||||
end
|
||||
end
|
||||
|
||||
local N = tonumber(arg and arg[1]) or 0
|
||||
local mindepth = 4
|
||||
local maxdepth = mindepth + 2
|
||||
if maxdepth < N then maxdepth = N end
|
||||
|
||||
do
|
||||
local stretchdepth = maxdepth + 1
|
||||
local stretchtree = BottomUpTree(0, stretchdepth)
|
||||
io.write(string.format("stretch tree of depth %d\t check: %d\n",
|
||||
stretchdepth, ItemCheck(stretchtree)))
|
||||
end
|
||||
|
||||
local longlivedtree = BottomUpTree(0, maxdepth)
|
||||
|
||||
for depth=mindepth,maxdepth,2 do
|
||||
local iterations = 2 ^ (maxdepth - depth + mindepth)
|
||||
local check = 0
|
||||
for i=1,iterations do
|
||||
check = check + ItemCheck(BottomUpTree(1, depth)) +
|
||||
ItemCheck(BottomUpTree(-1, depth))
|
||||
end
|
||||
io.write(string.format("%d\t trees of depth %d\t check: %d\n",
|
||||
iterations*2, depth, check))
|
||||
end
|
||||
|
||||
io.write(string.format("long lived tree of depth %d\t check: %d\n",
|
||||
maxdepth, ItemCheck(longlivedtree)))
|
||||
51
luaj-test/src/test/resources/perf/fannkuch.lua
Normal file
51
luaj-test/src/test/resources/perf/fannkuch.lua
Normal file
@@ -0,0 +1,51 @@
|
||||
-- The Computer Language Benchmarks Game
|
||||
-- http://shootout.alioth.debian.org/
|
||||
-- contributed by Mike Pall
|
||||
|
||||
local function fannkuch(n)
|
||||
local p, q, s, odd, check, maxflips = {}, {}, {}, true, 0, 0
|
||||
for i=1,n do p[i] = i; q[i] = i; s[i] = i end
|
||||
repeat
|
||||
-- Print max. 30 permutations.
|
||||
if check < 30 then
|
||||
if not p[n] then return maxflips end -- Catch n = 0, 1, 2.
|
||||
io.write(table.unpack(p)); io.write("\n")
|
||||
check = check + 1
|
||||
end
|
||||
-- Copy and flip.
|
||||
local q1 = p[1] -- Cache 1st element.
|
||||
if p[n] ~= n and q1 ~= 1 then -- Avoid useless work.
|
||||
for i=2,n do q[i] = p[i] end -- Work on a copy.
|
||||
for flips=1,1000000 do -- Flip ...
|
||||
local qq = q[q1]
|
||||
if qq == 1 then -- ... until 1st element is 1.
|
||||
if flips > maxflips then maxflips = flips end -- New maximum?
|
||||
break
|
||||
end
|
||||
q[q1] = q1
|
||||
if q1 >= 4 then
|
||||
local i, j = 2, q1 - 1
|
||||
repeat q[i], q[j] = q[j], q[i]; i = i + 1; j = j - 1; until i >= j
|
||||
end
|
||||
q1 = qq
|
||||
end
|
||||
end
|
||||
-- Permute.
|
||||
if odd then
|
||||
p[2], p[1] = p[1], p[2]; odd = false -- Rotate 1<-2.
|
||||
else
|
||||
p[2], p[3] = p[3], p[2]; odd = true -- Rotate 1<-2 and 1<-2<-3.
|
||||
for i=3,n do
|
||||
local sx = s[i]
|
||||
if sx ~= 1 then s[i] = sx-1; break end
|
||||
if i == n then return maxflips end -- Out of permutations.
|
||||
s[i] = i
|
||||
-- Rotate 1<-...<-i+1.
|
||||
local t = p[1]; for j=1,i do p[j] = p[j+1] end; p[i+1] = t
|
||||
end
|
||||
end
|
||||
until false
|
||||
end
|
||||
|
||||
local n = tonumber(arg and arg[1]) or 1
|
||||
io.write("Pfannkuchen(", n, ") = ", fannkuch(n), "\n")
|
||||
123
luaj-test/src/test/resources/perf/nbody.lua
Normal file
123
luaj-test/src/test/resources/perf/nbody.lua
Normal file
@@ -0,0 +1,123 @@
|
||||
-- The Great Computer Language Shootout
|
||||
-- http://shootout.alioth.debian.org/
|
||||
-- contributed by Isaac Gouy, tuned by Mike Pall
|
||||
|
||||
local sqrt = math.sqrt
|
||||
|
||||
local PI = 3.141592653589793
|
||||
local SOLAR_MASS = 4 * PI * PI
|
||||
local DAYS_PER_YEAR = 365.24
|
||||
|
||||
local Jupiter = {
|
||||
x = 4.84143144246472090e+00
|
||||
,y = -1.16032004402742839e+00
|
||||
,z = -1.03622044471123109e-01
|
||||
,vx = 1.66007664274403694e-03 * DAYS_PER_YEAR
|
||||
,vy = 7.69901118419740425e-03 * DAYS_PER_YEAR
|
||||
,vz = -6.90460016972063023e-05 * DAYS_PER_YEAR
|
||||
,mass = 9.54791938424326609e-04 * SOLAR_MASS
|
||||
}
|
||||
|
||||
local Saturn = {
|
||||
x = 8.34336671824457987e+00
|
||||
,y = 4.12479856412430479e+00
|
||||
,z = -4.03523417114321381e-01
|
||||
,vx = -2.76742510726862411e-03 * DAYS_PER_YEAR
|
||||
,vy = 4.99852801234917238e-03 * DAYS_PER_YEAR
|
||||
,vz = 2.30417297573763929e-05 * DAYS_PER_YEAR
|
||||
,mass = 2.85885980666130812e-04 * SOLAR_MASS
|
||||
}
|
||||
|
||||
local Uranus = {
|
||||
x = 1.28943695621391310e+01
|
||||
,y = -1.51111514016986312e+01
|
||||
,z = -2.23307578892655734e-01
|
||||
,vx = 2.96460137564761618e-03 * DAYS_PER_YEAR
|
||||
,vy = 2.37847173959480950e-03 * DAYS_PER_YEAR
|
||||
,vz = -2.96589568540237556e-05 * DAYS_PER_YEAR
|
||||
,mass = 4.36624404335156298e-05 * SOLAR_MASS
|
||||
}
|
||||
|
||||
local Neptune = {
|
||||
x = 1.53796971148509165e+01
|
||||
,y = -2.59193146099879641e+01
|
||||
,z = 1.79258772950371181e-01
|
||||
,vx = 2.68067772490389322e-03 * DAYS_PER_YEAR
|
||||
,vy = 1.62824170038242295e-03 * DAYS_PER_YEAR
|
||||
,vz = -9.51592254519715870e-05 * DAYS_PER_YEAR
|
||||
,mass = 5.15138902046611451e-05 * SOLAR_MASS
|
||||
}
|
||||
|
||||
local Sun = { x = 0, y = 0, z = 0,
|
||||
vx = 0, vy = 0, vz = 0, mass = SOLAR_MASS }
|
||||
|
||||
local function advance(bodies, nbody, dt)
|
||||
for i=1,nbody do
|
||||
local bi = bodies[i]
|
||||
local bix, biy, biz, bimass = bi.x, bi.y, bi.z, bi.mass
|
||||
local bivx, bivy, bivz = bi.vx, bi.vy, bi.vz
|
||||
for j=i+1,nbody do
|
||||
local bj = bodies[j]
|
||||
local dx, dy, dz = bix-bj.x, biy-bj.y, biz-bj.z
|
||||
local distance = sqrt(dx*dx + dy*dy + dz*dz)
|
||||
local mag = dt / (distance * distance * distance)
|
||||
local bim, bjm = bimass*mag, bj.mass*mag
|
||||
bivx = bivx - (dx * bjm)
|
||||
bivy = bivy - (dy * bjm)
|
||||
bivz = bivz - (dz * bjm)
|
||||
bj.vx = bj.vx + (dx * bim)
|
||||
bj.vy = bj.vy + (dy * bim)
|
||||
bj.vz = bj.vz + (dz * bim)
|
||||
end
|
||||
bi.vx = bivx
|
||||
bi.vy = bivy
|
||||
bi.vz = bivz
|
||||
end
|
||||
for i=1,nbody do
|
||||
local bi = bodies[i]
|
||||
bi.x = bi.x + (dt * bi.vx)
|
||||
bi.y = bi.y + (dt * bi.vy)
|
||||
bi.z = bi.z + (dt * bi.vz)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function energy(bodies, nbody)
|
||||
local e = 0
|
||||
for i=1,nbody do
|
||||
local bi = bodies[i]
|
||||
local vx, vy, vz, bim = bi.vx, bi.vy, bi.vz, bi.mass
|
||||
e = e + (0.5 * bim * (vx*vx + vy*vy + vz*vz))
|
||||
for j=i+1,nbody do
|
||||
local bj = bodies[j]
|
||||
local dx, dy, dz = bi.x-bj.x, bi.y-bj.y, bi.z-bj.z
|
||||
local distance = sqrt(dx*dx + dy*dy + dz*dz)
|
||||
e = e - ((bim * bj.mass) / distance)
|
||||
end
|
||||
end
|
||||
return e
|
||||
end
|
||||
|
||||
|
||||
local function offsetMomentum(b, nbody)
|
||||
local px, py, pz = 0, 0, 0
|
||||
for i=1,nbody do
|
||||
local bi = b[i]
|
||||
local bim = bi.mass
|
||||
px = px + (bi.vx * bim)
|
||||
py = py + (bi.vy * bim)
|
||||
pz = pz + (bi.vz * bim)
|
||||
end
|
||||
b[1].vx = -px / SOLAR_MASS
|
||||
b[1].vy = -py / SOLAR_MASS
|
||||
b[1].vz = -pz / SOLAR_MASS
|
||||
end
|
||||
|
||||
local N = tonumber(arg and arg[1]) or 1000
|
||||
local bodies = { Sun, Jupiter, Saturn, Uranus, Neptune }
|
||||
local nbody = #bodies
|
||||
|
||||
offsetMomentum(bodies, nbody)
|
||||
io.write( string.format("%0.9f",energy(bodies, nbody)), "\n")
|
||||
for i=1,N do advance(bodies, nbody, 0.01) end
|
||||
io.write( string.format("%0.9f",energy(bodies, nbody)), "\n")
|
||||
35
luaj-test/src/test/resources/perf/nsieve.lua
Normal file
35
luaj-test/src/test/resources/perf/nsieve.lua
Normal file
@@ -0,0 +1,35 @@
|
||||
-- The Computer Language Shootout
|
||||
-- http://shootout.alioth.debian.org/
|
||||
-- contributed by Isaac Gouy
|
||||
-- modified by Mike Pall
|
||||
|
||||
|
||||
local function nsieve(m,isPrime)
|
||||
for i=2,m do
|
||||
isPrime[i] = true
|
||||
end
|
||||
local count = 0
|
||||
|
||||
for i=2,m do
|
||||
if isPrime[i] then
|
||||
for k=i+i, m, i do
|
||||
if isPrime[k] then isPrime[k] = false end
|
||||
end
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
|
||||
local n = tonumber(arg and arg[1]) or 1
|
||||
local flags = {}
|
||||
|
||||
local m = (2^n)*10000
|
||||
print( string.format("Primes up to %8d %8d", m, nsieve(m,flags)))
|
||||
|
||||
m = (2^(n-1))*10000
|
||||
print( string.format("Primes up to %8d %8d", m, nsieve(m,flags)))
|
||||
|
||||
m = (2^(n-2))*10000
|
||||
print( string.format("Primes up to %8d %8d", m, nsieve(m,flags)))
|
||||
192
luaj-test/src/test/resources/stringlib.lua
Normal file
192
luaj-test/src/test/resources/stringlib.lua
Normal file
@@ -0,0 +1,192 @@
|
||||
print( string.find("1234567890", ".", 0, true) )
|
||||
print( string.find( 'alo alx 123 b\0o b\0o', '(..*) %1' ) )
|
||||
print( string.find( 'aloALO', '%l*' ) )
|
||||
print( string.find( ' \n isto <20> assim', '%S%S*' ) )
|
||||
|
||||
print( string.find( "", "" ) )
|
||||
print( string.find( "ababaabbaba", "abb" ) )
|
||||
print( string.find( "ababaabbaba", "abb", 7 ) )
|
||||
|
||||
print( string.match( "aabaa", "a*" ) )
|
||||
print( string.match( "aabaa", "a*", 3 ) )
|
||||
print( string.match( "aabaa", "a*b" ) )
|
||||
print( string.match( "aabaa", "a*b", 3 ) )
|
||||
|
||||
print( string.match( "abbaaababaabaaabaa", "b(a*)b" ) )
|
||||
|
||||
print( string.match( "abbaaababaabaaabaa", "b(a*)()b" ) )
|
||||
print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 3 ) )
|
||||
print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 8 ) )
|
||||
print( string.match( "abbaaababaabaaabaa", "b(a*)()b", 12 ) )
|
||||
|
||||
print( string.byte("hi", -3) )
|
||||
|
||||
print( string.gsub("ABC", "@(%x+)", function(s) return "|abcd" end) )
|
||||
print( string.gsub("@123", "@(%x+)", function(s) return "|abcd" end) )
|
||||
print( string.gsub("ABC@123", "@(%x+)", function(s) return "|abcd" end) )
|
||||
print( string.gsub("ABC@123@def", "@(%x+)", function(s) return "|abcd" end) )
|
||||
print( string.gsub("ABC@123@qrs@def@tuv", "@(%x+)", function(s) return "|abcd" end) )
|
||||
print( string.gsub("ABC@123@qrs@def@tuv", "@(%x+)", function(s) return "@ab" end) )
|
||||
|
||||
print( tostring(1234567890123) )
|
||||
print( tostring(1234567890124) )
|
||||
print( tostring(1234567890125) )
|
||||
|
||||
function f1(s, p)
|
||||
print(p)
|
||||
p = string.gsub(p, "%%([0-9])", function (s) return "%" .. (s+1) end)
|
||||
print(p)
|
||||
p = string.gsub(p, "^(^?)", "%1()", 1)
|
||||
print(p)
|
||||
p = string.gsub(p, "($?)$", "()%1", 1)
|
||||
print(p)
|
||||
local t = {string.match(s, p)}
|
||||
return string.sub(s, t[1], t[#t] - 1)
|
||||
end
|
||||
|
||||
print( pcall( f1, 'alo alx 123 b\0o b\0o', '(..*) %1' ) )
|
||||
|
||||
local function badpat()
|
||||
print( string.gsub( "alo", "(.)", "%2" ) )
|
||||
end
|
||||
|
||||
print( ( pcall( badpat ) ) )
|
||||
|
||||
for k, v in string.gmatch("w=200&h=150", "(%w+)=(%w+)") do
|
||||
print(k, v)
|
||||
end
|
||||
|
||||
-- string.sub
|
||||
function t(str)
|
||||
local i = { 0, 1, 2, 8, -1 }
|
||||
for ki,vi in ipairs(i) do
|
||||
local s,v = pcall( string.sub, str, vi )
|
||||
print( 'string.sub("'..str..'",'..tostring(vi)..')='..tostring(s)..',"'..tostring(v)..'"' )
|
||||
local j = { 0, 1, 2, 4, 8, -1 }
|
||||
for kj,vj in ipairs(j) do
|
||||
local s,v = pcall( string.sub, str, vi, vj )
|
||||
print( 'string.sub("'..str..'",'..tostring(vi)..','..tostring(vj)..')='..tostring(s)..',"'..tostring(v)..'"' )
|
||||
end
|
||||
end
|
||||
end
|
||||
t( 'abcdefghijklmn' )
|
||||
t( 'abcdefg' )
|
||||
t( 'abcd' )
|
||||
t( 'abc' )
|
||||
t( 'ab' )
|
||||
t( 'a' )
|
||||
t( '' )
|
||||
|
||||
print(string.len("Hello, world"))
|
||||
print(#"Hello, world")
|
||||
print(string.len("\0\0\0"))
|
||||
print(#"\0\0\0")
|
||||
print(string.len("\0\1\2\3"))
|
||||
print(#"\0\1\2\3")
|
||||
local s = "My JaCk-O-lAnTeRn CaSe TeXt"
|
||||
print(s, string.len(s), #s)
|
||||
|
||||
|
||||
-- string.format
|
||||
print(string.format("(%.0d) (%.0d) (%.0d)", 0, -5, 9))
|
||||
print(string.format("(%.1d) (%.1d) (%.1d)", 0, -5, 9))
|
||||
print(string.format("(%.2d) (%.2d) (%.2d)", 0, -5, 9))
|
||||
|
||||
print(string.format("(%+.0d) (%+.0d) (%+.0d)", 0, -5, 9))
|
||||
print(string.format("(%+.1d) (%+.1d) (%+.1d)", 0, -5, 9))
|
||||
print(string.format("(%+.2d) (%+.2d) (%+.2d)", 0, -5, 9))
|
||||
|
||||
print(string.format("(%+3d) (% 3d) (%+ 3d)", 55, 55, 55))
|
||||
|
||||
print(string.format("(%-1d) (%-1d) (%-1d)", 1, 12, -12))
|
||||
print(string.format("(%-2d) (%-2d) (%-2d)", 1, 12, -12))
|
||||
print(string.format("(%-3d) (%-3d) (%-3d)", 1, 12, -12))
|
||||
|
||||
|
||||
print(string.format("(%8x) (%8d) (%8o)", 255, 255, 255))
|
||||
print(string.format("(%08x) (%08d) (%08o)", 255, 255, 255))
|
||||
|
||||
print(string.format("simple%ssimple", " simple "))
|
||||
|
||||
local testformat = function(message,fmt,...)
|
||||
local s,e = pcall( string.format, fmt, ... )
|
||||
if s then
|
||||
if string.find(fmt, 'q') then
|
||||
print(message, e)
|
||||
end
|
||||
print( message, string.byte(e,1,#e) )
|
||||
else
|
||||
print( message, 'error', e )
|
||||
end
|
||||
end
|
||||
|
||||
testformat('plain %', "%%")
|
||||
testformat("specials (%s)", "---%s---", " %% \000 \r \n ")
|
||||
testformat("specials (%q)", "---%q---", " %% \000 \r \n ")
|
||||
testformat("specials (%q)", "---%q---", "0%%0\0000\r0\n0")
|
||||
testformat("controls (%q)", "---%q---", ' \a \b \f \t \v \\ ')
|
||||
testformat("controls (%q)", "---%q---", '0\a0\b0\f0\t0\v0\\0')
|
||||
testformat("extended (%q)", "---%q---", ' \222 \223 \224 ')
|
||||
testformat("extended (%q)", "---%q---", '0\2220\2230\2240')
|
||||
testformat("embedded newlines", "%s\r%s\n%s", '===', '===', '===')
|
||||
|
||||
-- format long string
|
||||
print("this is a %s long string", string.rep("really, ", 30))
|
||||
|
||||
local function pc(...)
|
||||
local s,e = pcall(...)
|
||||
return s and e or 'false-'..type(e)
|
||||
end
|
||||
|
||||
local function strtests(name,func,...)
|
||||
print(name, 'good', pc( func, ... ) )
|
||||
print(name, 'empty', pc( func ) )
|
||||
print(name, 'table', pc( func, {} ) )
|
||||
print(name, 'nil', pc( func, nil ) )
|
||||
end
|
||||
|
||||
strtests('lower', string.lower, s )
|
||||
strtests('upper', string.upper, s )
|
||||
strtests('reverse', string.reverse, s )
|
||||
strtests('char', string.char, 92, 60, 61, 93 )
|
||||
stringdumptest = function()
|
||||
return load(string.dump(function(x) return 'foo->'..x end),'bar')('bat')
|
||||
end
|
||||
print( 'string.dump test:', pcall(stringdumptest) )
|
||||
|
||||
|
||||
-- floating point formats (not supported yet)
|
||||
--[==[
|
||||
local prefixes = {'','+','-'}
|
||||
local lengths = {'7','2','0','1',''}
|
||||
local letters = {'f','e','g'}
|
||||
local fmt, spec, desc
|
||||
for i,letter in ipairs(letters) do
|
||||
for k,before in ipairs(lengths) do
|
||||
for j,prefix in ipairs(prefixes) do
|
||||
spec = '(%'..prefix..before..letter..')'
|
||||
fmt = spec..'\t'..spec..'\t'..spec..'\t'..spec..'\t'..spec..'\t'..spec
|
||||
print(spec, string.format(fmt, 12.34, -12.34, 1/11, -1/11, 300/11, -300/11) )
|
||||
for l,after in ipairs(lengths) do
|
||||
spec = '(%'..prefix..before..'.'..after..letter..')'
|
||||
fmt = spec..' '..spec..' '..spec..' '..spec..' '..spec..' '..spec
|
||||
print(spec, string.format(fmt, 12.34, -12.34, 1/11, -1/11, 300/11, -300/11) )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--]==]
|
||||
|
||||
local function fmterr(...)
|
||||
local r, s = pcall(...)
|
||||
if r then
|
||||
return s
|
||||
else
|
||||
s = string.gsub(s, "stdin:%d+:%s*", "")
|
||||
return s
|
||||
end
|
||||
end
|
||||
|
||||
print(fmterr(string.find, "ab%c)0(", "%"))
|
||||
print(fmterr(string.find, "ab%c)0(", "("))
|
||||
print(pcall(string.find, "ab%c)0(", ")"))
|
||||
284
luaj-test/src/test/resources/tablelib.lua
Normal file
284
luaj-test/src/test/resources/tablelib.lua
Normal file
@@ -0,0 +1,284 @@
|
||||
local func = function(t,...)
|
||||
return (...)
|
||||
end
|
||||
local tbl = setmetatable({},{__index=func})
|
||||
print( tbl[2] )
|
||||
|
||||
|
||||
-- tostring replacement that assigns ids
|
||||
local ts,id,nid,types = tostring,{},0,{table='tbl',thread='thr',userdata='uda',['function']='func'}
|
||||
tostring = function(x)
|
||||
if not x or not types[type(x)] then return ts(x) end
|
||||
if not id[x] then nid=nid+1; id[x]=types[type(x)]..'.'..nid end
|
||||
return id[x]
|
||||
end
|
||||
|
||||
local t = { "one", "two", "three", a='aaa', b='bbb', c='ccc' }
|
||||
|
||||
table.insert(t,'six');
|
||||
table.insert(t,1,'seven');
|
||||
table.insert(t,4,'eight');
|
||||
table.insert(t,7,'nine');
|
||||
table.insert(t,10,'ten'); print( #t )
|
||||
|
||||
-- concat
|
||||
print( '-- concat tests' )
|
||||
function tryconcat(t)
|
||||
print( table.concat(t) )
|
||||
print( table.concat(t,'--') )
|
||||
print( table.concat(t,',',2) )
|
||||
print( table.concat(t,',',2,2) )
|
||||
print( table.concat(t,',',5,2) )
|
||||
end
|
||||
tryconcat( { "one", "two", "three", a='aaa', b='bbb', c='ccc' } )
|
||||
tryconcat( { "one", "two", "three", "four", "five" } )
|
||||
function tryconcat(t)
|
||||
print( table.concat(t) )
|
||||
print( table.concat(t,'--') )
|
||||
print( table.concat(t,',',2) )
|
||||
end
|
||||
tryconcat( { a='aaa', b='bbb', c='ccc', d='ddd', e='eee' } )
|
||||
tryconcat( { [501]="one", [502]="two", [503]="three", [504]="four", [505]="five" } )
|
||||
tryconcat( {} )
|
||||
|
||||
-- print the elements of a table in a platform-independent way
|
||||
function eles(t,f)
|
||||
f = f or pairs
|
||||
all = {}
|
||||
for k,v in f(t) do
|
||||
table.insert( all, "["..tostring(k).."]="..tostring(v) )
|
||||
end
|
||||
table.sort( all )
|
||||
return "{"..table.concat(all,',').."}"
|
||||
end
|
||||
|
||||
-- insert, len
|
||||
print( '-- insert, len tests' )
|
||||
local t = { "one", "two", "three", a='aaa', b='bbb', c='ccc' }
|
||||
|
||||
print( eles(t), #t )
|
||||
table.insert(t,'six'); print( eles(t), #t )
|
||||
table.insert(t,1,'seven'); print( eles(t), #t )
|
||||
table.insert(t,4,'eight'); print( eles(t), #t )
|
||||
table.insert(t,7,'nine'); print( eles(t), #t )
|
||||
table.insert(t,10,'ten'); print( eles(t), #t )
|
||||
print( '#{}', #{} )
|
||||
print( '#{"a"}', #{"a"} )
|
||||
print( '#{"a","b"}', #{"a","b"} )
|
||||
print( '#{"a",nil}', #{"a",nil} )
|
||||
print( '#{nil,nil}', #{nil,nil} )
|
||||
print( '#{nil,"b"}', #{nil,"b"}==0 or #{nil,"b"}==2 )
|
||||
print( '#{"a","b","c"}', #{"a","b","c"} )
|
||||
print( '#{"a","b",nil}', #{"a","b",nil} )
|
||||
print( '#{"a",nil,nil}', #{"a",nil,nil} )
|
||||
print( '#{nil,nil,nil}', #{nil,nil,nil} )
|
||||
print( '#{nil,nil,"c"}', #{nil,nil,"c"}==0 or #{nil,nil,"c"}==3 )
|
||||
print( '#{nil,"b","c"}', #{nil,"b","c"}==0 or #{nil,"b","c"}==3 )
|
||||
print( '#{nil,"b",nil}', #{nil,"b",nil}==0 or #{nil,"b",nil}==2 )
|
||||
print( '#{"a",nil,"c"}', #{"a",nil,"c"}==1 or #{"a",nil,"c"}==3 )
|
||||
|
||||
-- remove
|
||||
print( '-- remove tests' )
|
||||
t = { "one", "two", "three", "four", "five", "six", "seven", [10]="ten", a='aaa', b='bbb', c='ccc' }
|
||||
print( eles(t), #t )
|
||||
print( 'table.remove(t)', table.remove(t) ); print( eles(t), #t )
|
||||
print( 'table.remove(t,1)', table.remove(t,1) ); print( eles(t), #t )
|
||||
print( 'table.remove(t,3)', table.remove(t,3) ); print( eles(t), #t )
|
||||
print( 'table.remove(t,5)', table.remove(t,5) ); print( eles(t), #t )
|
||||
print( 'table.remove(t,10)', table.remove(t,10) ); print( eles(t), #t )
|
||||
print( 'table.remove(t,-1)', table.remove(t,-1) ); print( eles(t), #t )
|
||||
print( 'table.remove(t,-1)', table.remove(t,-1) ) ; print( eles(t), #t )
|
||||
|
||||
-- sort
|
||||
print( '-- sort tests' )
|
||||
function sorttest(t,f)
|
||||
t = (t)
|
||||
print( table.concat(t,'-') )
|
||||
if f then
|
||||
table.sort(t,f)
|
||||
else
|
||||
table.sort(t)
|
||||
end
|
||||
print( table.concat(t,'-') )
|
||||
end
|
||||
sorttest{ "one", "two", "three" }
|
||||
sorttest{ "www", "vvv", "uuu", "ttt", "sss", "zzz", "yyy", "xxx" }
|
||||
sorttest( { "www", "vvv", "uuu", "ttt", "sss", "zzz", "yyy", "xxx" }, function(a,b) return b<a end)
|
||||
|
||||
-- pairs, ipairs
|
||||
--[[
|
||||
function testpairs(f, t, name)
|
||||
print( name )
|
||||
for a,b in f(t) do
|
||||
print( ' ', a, b )
|
||||
end
|
||||
end
|
||||
function testbothpairs(t)
|
||||
testpairs( pairs, t, 'pairs( '..eles(t)..' )' )
|
||||
testpairs( ipairs, t, 'ipairs( '..eles(t)..' )' )
|
||||
end
|
||||
for i,t in ipairs({t0,t1,t2,t3}) do
|
||||
testbothpairs(t)
|
||||
end
|
||||
|
||||
t = { 'one', 'two', 'three', 'four', 'five' }
|
||||
testbothpairs(t)
|
||||
t[6] = 'six'
|
||||
testbothpairs(t)
|
||||
t[4] = nil
|
||||
testbothpairs(t)
|
||||
--]]
|
||||
|
||||
-- tests of setlist table constructors
|
||||
-- length is tested elsewhere
|
||||
print('----- unpack tests -------')
|
||||
local unpack = table.unpack
|
||||
print( 'pcall(unpack)', (pcall(unpack)) );
|
||||
print( 'pcall(unpack,nil)', (pcall(unpack,nil)) );
|
||||
print( 'pcall(unpack,"abc")', (pcall(unpack,"abc")) );
|
||||
print( 'pcall(unpack,1)', (pcall(unpack,1)) );
|
||||
print( 'unpack({"aa"})', unpack({"aa"}) );
|
||||
print( 'unpack({"aa","bb"})', unpack({"aa","bb"}) );
|
||||
print( 'unpack({"aa","bb","cc"})', unpack({"aa","bb","cc"}) );
|
||||
local function a(...) return ... end
|
||||
print('unpack -',unpack({}))
|
||||
print('unpack a',unpack({'a'}))
|
||||
print('unpack .',unpack({nil},1,1))
|
||||
print('unpack ab',unpack({'a', 'b'}))
|
||||
print('unpack .b',unpack({nil, 'b'},1,2))
|
||||
print('unpack a.',unpack({'a', nil},1,2))
|
||||
print('unpack abc',unpack({'a', 'b', 'c'}))
|
||||
print('unpack .ab',unpack({nil, 'a', 'b'},1,3))
|
||||
print('unpack a.b',unpack({'a', nil, 'b'},1,3))
|
||||
print('unpack ab.',unpack({'a', 'b', nil},1,3))
|
||||
print('unpack ..b',unpack({nil, nil, 'b'},1,3))
|
||||
print('unpack a..',unpack({'a', nil, nil},1,3))
|
||||
print('unpack .b.',unpack({nil, 'b', nil},1,3))
|
||||
print('unpack ...',unpack({nil, nil, nil},1,3))
|
||||
print('unpack (-)',unpack({a()}))
|
||||
print('unpack (a)',unpack({a('a')}))
|
||||
print('unpack (.)',unpack({a(nil)},1,1))
|
||||
print('unpack (ab)',unpack({a('a', 'b')}))
|
||||
print('unpack (.b)',unpack({a(nil, 'b')},1,2))
|
||||
print('unpack (a.)',unpack({a('a', nil)},1,2))
|
||||
print('unpack (abc)',unpack({a('a', 'b', 'c')}))
|
||||
print('unpack (.ab)',unpack({a(nil, 'a', 'b')},1,3))
|
||||
print('unpack (a.b)',unpack({a('a', nil, 'b')},1,3))
|
||||
print('unpack (ab.)',unpack({a('a', 'b', nil)},1,3))
|
||||
print('unpack (..b)',unpack({a(nil, nil, 'b')},1,3))
|
||||
print('unpack (a..)',unpack({a('a', nil, nil)},1,3))
|
||||
print('unpack (.b.)',unpack({a(nil, 'b', nil)},1,3))
|
||||
print('unpack (...)',unpack({a(nil, nil, nil)},1,3))
|
||||
local t = {"aa","bb","cc","dd","ee","ff"}
|
||||
print( 'pcall(unpack,t)', pcall(unpack,t) );
|
||||
print( 'pcall(unpack,t,2)', pcall(unpack,t,2) );
|
||||
print( 'pcall(unpack,t,2,5)', pcall(unpack,t,2,5) );
|
||||
print( 'pcall(unpack,t,2,6)', pcall(unpack,t,2,6) );
|
||||
print( 'pcall(unpack,t,2,7)', pcall(unpack,t,2,7) );
|
||||
print( 'pcall(unpack,t,1)', pcall(unpack,t,1) );
|
||||
print( 'pcall(unpack,t,1,5)', pcall(unpack,t,1,5) );
|
||||
print( 'pcall(unpack,t,1,6)', pcall(unpack,t,1,6) );
|
||||
print( 'pcall(unpack,t,1,7)', pcall(unpack,t,1,7) );
|
||||
print( 'pcall(unpack,t,0)', pcall(unpack,t,0) );
|
||||
print( 'pcall(unpack,t,0,5)', pcall(unpack,t,0,5) );
|
||||
print( 'pcall(unpack,t,0,6)', pcall(unpack,t,0,6) );
|
||||
print( 'pcall(unpack,t,0,7)', pcall(unpack,t,0,7) );
|
||||
print( 'pcall(unpack,t,-1)', pcall(unpack,t,-1) );
|
||||
print( 'pcall(unpack,t,-1,5)', pcall(unpack,t,-1,5) );
|
||||
print( 'pcall(unpack,t,-1,6)', pcall(unpack,t,-1,6) );
|
||||
print( 'pcall(unpack,t,-1,7)', pcall(unpack,t,-1,7) );
|
||||
print( 'pcall(unpack,t,2,4)', pcall(unpack,t,2,4) );
|
||||
print( 'pcall(unpack,t,2,5)', pcall(unpack,t,2,5) );
|
||||
print( 'pcall(unpack,t,2,6)', pcall(unpack,t,2,6) );
|
||||
print( 'pcall(unpack,t,2,7)', pcall(unpack,t,2,7) );
|
||||
print( 'pcall(unpack,t,2,8)', pcall(unpack,t,2,8) );
|
||||
print( 'pcall(unpack,t,2,2)', pcall(unpack,t,2,0) );
|
||||
print( 'pcall(unpack,t,2,1)', pcall(unpack,t,2,0) );
|
||||
print( 'pcall(unpack,t,2,0)', pcall(unpack,t,2,0) );
|
||||
print( 'pcall(unpack,t,2,-1)', pcall(unpack,t,2,-1) );
|
||||
t[0] = 'zz'
|
||||
t[-1] = 'yy'
|
||||
t[-2] = 'xx'
|
||||
print( 'pcall(unpack,t,0)', pcall(unpack,t,0) );
|
||||
print( 'pcall(unpack,t,2,0)', pcall(unpack,t,2,0) );
|
||||
print( 'pcall(unpack,t,2,-1)', pcall(unpack,t,2,-1) );
|
||||
print( 'pcall(unpack,t,"3")', pcall(unpack,t,"3") );
|
||||
print( 'pcall(unpack,t,"a")', (pcall(unpack,t,"a")) );
|
||||
print( 'pcall(unpack,t,function() end)', (pcall(unpack,t,function() end)) );
|
||||
|
||||
-- misc tests
|
||||
print('----- misc table initializer tests -------')
|
||||
print( # { 'abc', 'def', 'ghi', nil } ) -- should be 3 !
|
||||
print( # { 'abc', 'def', 'ghi', false } ) -- should be 4 !
|
||||
print( # { 'abc', 'def', 'ghi', 0 } ) -- should be 4 !
|
||||
|
||||
-- basic table operation tests
|
||||
print('----- basic table operations -------')
|
||||
|
||||
local dummyfunc = function(t,...)
|
||||
print( 'metatable call args', type(t), ...)
|
||||
return 'dummy'
|
||||
end
|
||||
local makeloud = function(t)
|
||||
return setmetatable(t,{
|
||||
__index=function(t,k)
|
||||
print( '__index', type(t), k )
|
||||
return rawset(t,k)
|
||||
end,
|
||||
__newindex=function(t,k,v)
|
||||
print( '__newindex', type(t), k, v )
|
||||
rawset(t,k,v)
|
||||
end})
|
||||
end
|
||||
local tests = {
|
||||
{'basic table', {}},
|
||||
{'function metatable on __index', setmetatable({},{__index=dummyfunc})},
|
||||
{'function metatable on __newindex', setmetatable({},{__newindex=dummyfunc})},
|
||||
{'plain metatable on __index', setmetatable({},makeloud({}))},
|
||||
{'plain metatable on __newindex', setmetatable({},makeloud({}))},
|
||||
}
|
||||
local function shoulderr(s,e)
|
||||
return s,type(e)
|
||||
end
|
||||
for i,test in ipairs(tests) do
|
||||
local testname = test[1]
|
||||
local testtable = test[2]
|
||||
print( '------ basic table tests on '..testname..' '..type(testtable) )
|
||||
print( 't[1]=2', pcall( function() testtable[1]=2 end ) )
|
||||
print( 't[1]', pcall( function() return testtable[1] end ) )
|
||||
print( 't[1]=nil', pcall( function() testtable[1]=nil end ) )
|
||||
print( 't[1]', pcall( function() return testtable[1] end ) )
|
||||
print( 't["a"]="b"', pcall( function() testtable["a"]="b" end ) )
|
||||
print( 't["a"],t.a', pcall( function() return testtable["a"],testtable.a end ) )
|
||||
print( 't.a="c"', pcall( function() testtable.a="c" end ) )
|
||||
print( 't["a"],t.a', pcall( function() return testtable["a"],testtable.a end ) )
|
||||
print( 't.a=nil', pcall( function() testtable.a=nil end ) )
|
||||
print( 't["a"],t.a', pcall( function() return testtable["a"],testtable.a end ) )
|
||||
print( 't[nil]="d"', shoulderr( pcall( function() testtable[nil]="d" end ) ) )
|
||||
print( 't[nil]', pcall( function() return testtable[nil] end ) )
|
||||
print( 't[nil]=nil', shoulderr( pcall( function() testtable[nil]=nil end ) ) )
|
||||
print( 't[nil]', pcall( function() return testtable[nil] end ) )
|
||||
end
|
||||
|
||||
print( '-- sort tests' )
|
||||
local function tryall(cmp)
|
||||
local function try(t)
|
||||
print( table.concat(t,'-') )
|
||||
if pcall( table.sort, t, cmp ) then
|
||||
print( table.concat(t,'-') )
|
||||
else
|
||||
print( 'sort failed' )
|
||||
end
|
||||
end
|
||||
try{ 2, 4, 6, 8, 1, 3, 5, 7 }
|
||||
try{ 333, 222, 111 }
|
||||
try{ "www", "xxx", "yyy", "aaa", "bbb", "ccc" }
|
||||
try{ 21, 23, "25", 27, 22, "24", 26, 28 }
|
||||
end
|
||||
local function comparator(a,b)
|
||||
return tonumber(a)<tonumber(b)
|
||||
end
|
||||
print ( 'default (lexical) comparator' )
|
||||
tryall()
|
||||
print ( 'custom (numerical) comparator' )
|
||||
tryall(comparator)
|
||||
153
luaj-test/src/test/resources/tailcalls.lua
Normal file
153
luaj-test/src/test/resources/tailcalls.lua
Normal file
@@ -0,0 +1,153 @@
|
||||
|
||||
-- tostring replacement that assigns ids
|
||||
local ts,id,nid,types = tostring,{},0,{table='tbl',thread='thr',userdata='uda',['function']='func'}
|
||||
tostring = function(x)
|
||||
if not x or not types[type(x)] then return ts(x) end
|
||||
if not id[x] then nid=nid+1; id[x]=types[type(x)]..'.'..nid end
|
||||
return id[x]
|
||||
end
|
||||
|
||||
|
||||
function a()
|
||||
return pcall( function() end )
|
||||
end
|
||||
|
||||
function b()
|
||||
return pcall( function() print 'b' end )
|
||||
end
|
||||
|
||||
function c()
|
||||
return pcall( function() return 'c' end )
|
||||
end
|
||||
|
||||
print( pcall( a ) )
|
||||
print( pcall( b ) )
|
||||
print( pcall( c ) )
|
||||
|
||||
local function sum(...)
|
||||
local s = 0
|
||||
for i,v in ipairs({...}) do
|
||||
s = s + v
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local function f1(n,a,b,c)
|
||||
local a = a or 0
|
||||
local b = b or 0
|
||||
local c = c or 0
|
||||
if n <= 0 then
|
||||
return a,a+b,a+b+c
|
||||
end
|
||||
return f1(n-1,a,a+b,a+b+c)
|
||||
end
|
||||
|
||||
local function f2(n,...)
|
||||
if n <= 0 then
|
||||
print( " --f2, n<=0, returning sum(...)", ... )
|
||||
return sum(...)
|
||||
end
|
||||
print( " --f2, n>0, returning f2(n-1,n,...)", n-1,n,... )
|
||||
return f2(n-1,n,...)
|
||||
end
|
||||
|
||||
local function f3(n,...)
|
||||
if n <= 0 then
|
||||
return sum(...)
|
||||
end
|
||||
print( " f3,n-1,n,...", f3,n-1,n,... )
|
||||
return pcall(f3,n-1,n,...)
|
||||
end
|
||||
|
||||
local function all(f)
|
||||
for n=0,3 do
|
||||
t = {}
|
||||
for m=1,5 do
|
||||
print( "--f, n, table.unpack(t)", f, n, table.unpack(t) )
|
||||
print( pcall( f, n, table.unpack(t)) )
|
||||
t[m] = m
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
all(f1)
|
||||
all(f2)
|
||||
all(f3)
|
||||
|
||||
|
||||
local function f(x)
|
||||
-- tailcall to a builtin
|
||||
return math.abs(x)
|
||||
end
|
||||
|
||||
local function factorial(i)
|
||||
local function helper(product, n)
|
||||
if n <= 0 then
|
||||
return product
|
||||
else
|
||||
-- tail call to a nested Lua function
|
||||
return helper(n * product, n - 1)
|
||||
end
|
||||
end
|
||||
return helper(1, i)
|
||||
end
|
||||
|
||||
local result1 = factorial(5)
|
||||
print(result1)
|
||||
print(factorial(5))
|
||||
|
||||
local result2 = f(-1234)
|
||||
print( result2 )
|
||||
|
||||
local function fib_bad(n)
|
||||
local function helper(i, a, b)
|
||||
if i >= n then
|
||||
return a
|
||||
else
|
||||
-- not recognized by luac as a tailcall!
|
||||
local result = helper(i + 1, b, a + b)
|
||||
return result
|
||||
end
|
||||
end
|
||||
return helper(1, 1, 1)
|
||||
end
|
||||
|
||||
local function fib_good(n)
|
||||
local function helper(i, a, b)
|
||||
if i >= n then
|
||||
return a
|
||||
else
|
||||
-- must be a tail call!
|
||||
return helper(i + 1, b, a + b)
|
||||
end
|
||||
end
|
||||
return helper(1, 1, 1)
|
||||
end
|
||||
|
||||
local aliases = {
|
||||
['1.#INF'] = 'inf',
|
||||
['-1.#INF'] = '-inf',
|
||||
['1.#IND'] = 'nan',
|
||||
['-1.#IND'] = 'nan',
|
||||
}
|
||||
|
||||
local p = function( s,e )
|
||||
print( s, e and aliases[tostring(e)] or e )
|
||||
end
|
||||
p(pcall(fib_bad, 30))
|
||||
--p((pcall(fib_bad, 25000)))
|
||||
p(pcall(fib_good, 30))
|
||||
p(pcall(fib_good, 25000))
|
||||
|
||||
local function fib_all(n, i, a, b)
|
||||
i = i or 1
|
||||
a = a or 1
|
||||
b = b or 1
|
||||
if i >= n then
|
||||
return
|
||||
else
|
||||
return a, fib_all(n, i+1, b, a+b)
|
||||
end
|
||||
end
|
||||
|
||||
print(fib_all(10))
|
||||
97
luaj-test/src/test/resources/upvalues.lua
Normal file
97
luaj-test/src/test/resources/upvalues.lua
Normal file
@@ -0,0 +1,97 @@
|
||||
|
||||
print( '-------- simple upvalues tests --------' )
|
||||
local function simpleupvalues()
|
||||
function test()
|
||||
local x = 5
|
||||
function f()
|
||||
x = x + 1
|
||||
return x
|
||||
end
|
||||
function g()
|
||||
x = x - 1
|
||||
return x
|
||||
end
|
||||
print(f())
|
||||
print(g())
|
||||
return f, g
|
||||
end
|
||||
|
||||
f1, g1 = test()
|
||||
print("f1()=", f1())
|
||||
print("g1()=", g1())
|
||||
|
||||
f2, g2 = test()
|
||||
print("f2()=", f2())
|
||||
print("g2()=", g2())
|
||||
|
||||
print("g1()=", g1())
|
||||
print("f1()=", f1())
|
||||
end
|
||||
print( 'simplevalues result:', pcall( simpleupvalues ) )
|
||||
|
||||
|
||||
-- The point of this test is that when an upvalue is created, it may
|
||||
-- need to be inserted in the middle of the list, rather than always
|
||||
-- appended at the end. Otherwise, it may not be found when it is
|
||||
-- needed by another closure.
|
||||
print( '----------- upvalued in middle ------------' )
|
||||
local function middleupvaluestest()
|
||||
local function test()
|
||||
local x = 3
|
||||
local y = 5
|
||||
local z = 7
|
||||
|
||||
local function f()
|
||||
print("y=", y)
|
||||
end
|
||||
|
||||
local function g()
|
||||
print("z=", z)
|
||||
end
|
||||
|
||||
local function h()
|
||||
print("x=", x)
|
||||
end
|
||||
|
||||
local function setter(x1, y1, z1)
|
||||
x = x1
|
||||
y = y1
|
||||
z = z1
|
||||
end
|
||||
|
||||
return f, g, h, setter
|
||||
end
|
||||
|
||||
local f, g, h, setter = test()
|
||||
|
||||
h()
|
||||
f()
|
||||
g()
|
||||
|
||||
setter("x", "y", "z")
|
||||
|
||||
h()
|
||||
f()
|
||||
g()
|
||||
end
|
||||
print( pcall( middleupvaluestest ) )
|
||||
|
||||
|
||||
print( '--------- nested upvalues ----------' )
|
||||
local function nestedupvaluestest()
|
||||
local f
|
||||
do
|
||||
local x = 10
|
||||
function g()
|
||||
print(x, f())
|
||||
end
|
||||
end
|
||||
|
||||
function f()
|
||||
return 20
|
||||
end
|
||||
|
||||
g()
|
||||
end
|
||||
print( 'nestedupvaluestest result:', pcall( nestedupvaluestest ) )
|
||||
|
||||
250
luaj-test/src/test/resources/vm.lua
Normal file
250
luaj-test/src/test/resources/vm.lua
Normal file
@@ -0,0 +1,250 @@
|
||||
|
||||
print( '-------- basic vm tests --------' )
|
||||
|
||||
print( '-- boolean tests' )
|
||||
local function booleantests()
|
||||
t = true
|
||||
f = false
|
||||
n = nil
|
||||
s = "Hello"
|
||||
z = 0
|
||||
one = 1
|
||||
|
||||
print(t)
|
||||
print(f)
|
||||
|
||||
print(not t)
|
||||
print(not f)
|
||||
print(not n)
|
||||
print(not z)
|
||||
print(not s)
|
||||
print(not(not(t)))
|
||||
print(not(not(z)))
|
||||
print(not(not(n)))
|
||||
|
||||
print(t and f)
|
||||
print(t or f)
|
||||
print(f and t)
|
||||
print(f or t)
|
||||
|
||||
print(f or one)
|
||||
print(f or z)
|
||||
print(f or n)
|
||||
|
||||
print(t and one)
|
||||
print(t and z)
|
||||
print(t and n)
|
||||
end
|
||||
print( 'booleantests result:', pcall( booleantests ) )
|
||||
|
||||
|
||||
print( '------------- varargs' )
|
||||
local function varargstest()
|
||||
function p(a,...)
|
||||
print("a",a)
|
||||
print("...",...)
|
||||
print("...,a",...,a)
|
||||
print("a,...",a,...)
|
||||
end
|
||||
function q(a,...)
|
||||
print("a,arg[1],arg[2],arg[3]",a,arg.n,arg[1],arg[2],arg[3])
|
||||
end
|
||||
function r(a,...)
|
||||
print("a,arg[1],arg[2],arg[3]",a,arg.n,arg[1],arg[2],arg[3])
|
||||
print("a",a)
|
||||
print("...",...)
|
||||
print("...,a",...,a)
|
||||
print("a,...",a,...)
|
||||
end
|
||||
function s(a)
|
||||
local arg = { '1', '2', '3' }
|
||||
print("a,arg[1],arg[2],arg[3]",a,arg[1],arg[2],arg[3])
|
||||
print("a",a)
|
||||
end
|
||||
function t(a,...)
|
||||
local arg = { '1', '2', '3' }
|
||||
print("a,arg[1],arg[2],arg[3]",a,arg[1],arg[2],arg[3])
|
||||
print("a",a)
|
||||
print("...",...)
|
||||
print("...,a",...,a)
|
||||
print("a,...",a,...)
|
||||
end
|
||||
function u(arg)
|
||||
print( 'arg', arg )
|
||||
end
|
||||
function v(arg,...)
|
||||
print( 'arg', arg )
|
||||
print("...",...)
|
||||
print("arg,...",arg,...)
|
||||
end
|
||||
arg = { "global-1", "global-2", "global-3" }
|
||||
function tryall(f,name)
|
||||
print( '---- function '..name..'()' )
|
||||
print( '--'..name..'():' )
|
||||
print( ' ->', pcall( f ) )
|
||||
print( '--'..name..'("q"):' )
|
||||
print( ' ->', pcall( f, "q" ) )
|
||||
print( '--'..name..'("q","r"):' )
|
||||
print( ' ->', pcall( f, "q", "r" ) )
|
||||
print( '--'..name..'("q","r","s"):' )
|
||||
print( ' ->', pcall( f, "q", "r", "s" ) )
|
||||
end
|
||||
tryall(p,'p')
|
||||
tryall(q,'q')
|
||||
tryall(r,'r')
|
||||
tryall(s,'s')
|
||||
tryall(t,'t')
|
||||
tryall(u,'u')
|
||||
tryall(v,'v')
|
||||
end
|
||||
print( 'varargstest result:', pcall( varargstest ) )
|
||||
|
||||
-- The purpose of this test case is to demonstrate that
|
||||
-- basic metatable operations on non-table types work.
|
||||
-- i.e. that s.sub(s,...) could be used in place of string.sub(s,...)
|
||||
print( '---------- metatable tests' )
|
||||
local function metatabletests()
|
||||
|
||||
-- tostring replacement that assigns ids
|
||||
local ts,id,nid,types = tostring,{},0,{table='tbl',thread='thr',userdata='uda',['function']='func'}
|
||||
tostring = function(x)
|
||||
if not x or not types[type(x)] then return ts(x) end
|
||||
if not id[x] then nid=nid+1; id[x]=types[type(x)]..'.'..nid end
|
||||
return id[x]
|
||||
end
|
||||
local results = function(s,e,...)
|
||||
if s then return e,... end
|
||||
return false,type(e)
|
||||
end
|
||||
local pcall = function(...)
|
||||
return results( pcall(...) )
|
||||
end
|
||||
|
||||
|
||||
local s = "hello"
|
||||
print(s:sub(2,4))
|
||||
|
||||
local t = {}
|
||||
function op(name,...)
|
||||
local a,b = pcall( setmetatable, t, ... )
|
||||
print( name, t, getmetatable(t), a, b )
|
||||
end
|
||||
op('set{} ',{})
|
||||
op('set-nil',nil)
|
||||
op('set{} ',{})
|
||||
op('set')
|
||||
op('set{} ',{})
|
||||
op('set{} ',{})
|
||||
op('set{}{}',{},{})
|
||||
op('set-nil',nil)
|
||||
op('set{__}',{__metatable={}})
|
||||
op('set{} ',{})
|
||||
op('set-nil',nil)
|
||||
t = {}
|
||||
op('set{} ',{})
|
||||
op('set-nil',nil)
|
||||
op('set{__}',{__metatable='abc'})
|
||||
op('set{} ',{})
|
||||
op('set-nil',nil)
|
||||
|
||||
|
||||
local i = 1234
|
||||
local t = setmetatable( {}, {
|
||||
__mode="v",
|
||||
__index=function(t,k)
|
||||
local v = i
|
||||
i = i + 1
|
||||
rawset(t,k,v)
|
||||
return v
|
||||
end,
|
||||
} )
|
||||
|
||||
local l = { 'a', 'b', 'a', 'b', 'c', 'a', 'b', 'c', 'd' }
|
||||
for i,key in ipairs(l) do
|
||||
print( 't.'..key, t[key] )
|
||||
end
|
||||
end
|
||||
print( 'metatabletests result:', pcall( metatabletests ) )
|
||||
|
||||
-- test tables with more than 50 elements
|
||||
print( '------------ huge tables' )
|
||||
local function hugetables()
|
||||
local t = { 1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,
|
||||
}
|
||||
print ("#t=",#t,'t[1,50,51,59]', t[1], t[50], t[51], t[59])
|
||||
print (table.concat(t,','))
|
||||
|
||||
local t2= { 0,3,4,7,9,8,12,15,23,5,
|
||||
10,13,14,17,19,18,112,115,123,15,
|
||||
20,33,24,27,29,28,212,215,223,25,
|
||||
40,43,44,47,49,48,412,415,423,45,
|
||||
50,53,54,57,59,58,512,515,523,55,
|
||||
60,63,64,67,69,68,612,615,623,65,
|
||||
70,73,74,77,79,78,72,715,723,75,
|
||||
}
|
||||
|
||||
print ("#t2=",#t2,'t[1,50,51,59]', t[1], t[50], t[51], t[59])
|
||||
print (table.concat(t2,','))
|
||||
|
||||
local t = {
|
||||
[2000]='a', [2001]='b', [2002]='c', [2003]='d', [2004]='e', [2005]='f', [2006]='g', [2007]='h', [2008]='i', [2009]='j',
|
||||
[3000]='a', [3001]='b', [3002]='c', [3003]='d', [3004]='e', [3005]='f', [3006]='g', [3007]='h', [3008]='i', [3009]='j',
|
||||
[4000]='a', [4001]='b', [4002]='c', [4003]='d', [4004]='e', [4005]='f', [4006]='g', [4007]='h', [4008]='i', [4009]='j',
|
||||
[5000]='a', [5001]='b', [5002]='c', [5003]='d', [5004]='e', [5005]='f', [5006]='g', [5007]='h', [5008]='i', [5009]='j',
|
||||
[6000]='a', [6001]='b', [6002]='c', [6003]='d', [6004]='e', [6005]='f', [6006]='g', [6007]='h', [6008]='i', [6009]='j',
|
||||
[7000]='a', [7001]='b', [7002]='c', [7003]='d', [7004]='e', [7005]='f', [7006]='g', [7007]='h', [7008]='i', [7009]='j',
|
||||
[8000]='a', [8001]='b', [8002]='c', [8003]='d', [8004]='e', [8005]='f', [8006]='g', [8007]='h', [8008]='i', [8009]='j',
|
||||
}
|
||||
|
||||
for i=2000,8000,1000 do
|
||||
for j=0,9,1 do
|
||||
print( 't['..tostring(i+j)..']', t[i+j] )
|
||||
end
|
||||
end
|
||||
end
|
||||
print( 'hugetables result:', pcall( hugetables ) )
|
||||
|
||||
print( '--------- many locals' )
|
||||
local function manylocals()
|
||||
-- test program with more than 50 non-sequential integer elements
|
||||
local t0000='a'; local t0001='b'; local t0002='c'; local t0003='d'; local t0004='e'; local t0005='f'; local t0006='g'; local t0007='h'; local t0008='i'; local t0009='j';
|
||||
local t1000='a'; local t1001='b'; local t1002='c'; local t1003='d'; local t1004='e'; local t1005='f'; local t1006='g'; local t1007='h'; local t1008='i'; local t1009='j';
|
||||
local t2000='a'; local t2001='b'; local t2002='c'; local t2003='d'; local t2004='e'; local t2005='f'; local t2006='g'; local t2007='h'; local t2008='i'; local t2009='j';
|
||||
local t3000='a'; local t3001='b'; local t3002='c'; local t3003='d'; local t3004='e'; local t3005='f'; local t3006='g'; local t3007='h'; local t3008='i'; local t3009='j';
|
||||
local t4000='a'; local t4001='b'; local t4002='c'; local t4003='d'; local t4004='e'; local t4005='f'; local t4006='g'; local t4007='h'; local t4008='i'; local t4009='j';
|
||||
local t5000='a'; local t5001='b'; local t5002='c'; local t5003='d'; local t5004='e'; local t5005='f'; local t5006='g'; local t5007='h'; local t5008='i'; local t5009='j';
|
||||
local t6000='a'; local t6001='b'; local t6002='c'; local t6003='d'; local t6004='e'; local t6005='f'; local t6006='g'; local t6007='h'; local t6008='i'; local t6009='j';
|
||||
local t7000='a'; local t7001='b'; local t7002='c'; local t7003='d'; local t7004='e'; local t7005='f'; local t7006='g'; local t7007='h'; local t7008='i'; local t7009='j';
|
||||
local t8000='a'; local t8001='b'; local t8002='c'; local t8003='d'; local t8004='e'; local t8005='f'; local t8006='g'; local t8007='h'; local t8008='i'; local t8009='j';
|
||||
local t9000='a'; local t9001='b'; local t9002='c'; local t9003='d'; local t9004='e'; local t9005='f'; local t9006='g'; local t9007='h'; local t9008='i'; local t9009='j';
|
||||
local t10000='a'; local t10001='b'; local t10002='c'; local t10003='d'; local t10004='e'; local t10005='f'; local t10006='g'; local t10007='h'; local t10008='i'; local t10009='j';
|
||||
local t11000='a'; local t11001='b'; local t11002='c'; local t11003='d'; local t11004='e'; local t11005='f'; local t11006='g'; local t11007='h'; local t11008='i'; local t11009='j';
|
||||
local t12000='a'; local t12001='b'; local t12002='c'; local t12003='d'; local t12004='e'; local t12005='f'; local t12006='g'; local t12007='h'; local t12008='i'; local t12009='j';
|
||||
local t13000='a'; local t13001='b'; local t13002='c'; local t13003='d'; local t13004='e'; local t13005='f'; local t13006='g'; local t13007='h'; local t13008='i'; local t13009='j';
|
||||
|
||||
-- print the variables
|
||||
print(t0000,'a'); print(t0001,'b'); print(t0002,'c'); print(t0003,'d'); print(t0004,'e'); print(t0005,'f'); print(t0006,'g'); print(t0007,'h'); print(t0008,'i'); print(t0009,'j');
|
||||
print(t1000,'a'); print(t1001,'b'); print(t1002,'c'); print(t1003,'d'); print(t1004,'e'); print(t1005,'f'); print(t1006,'g'); print(t1007,'h'); print(t1008,'i'); print(t1009,'j');
|
||||
print(t2000,'a'); print(t2001,'b'); print(t2002,'c'); print(t2003,'d'); print(t2004,'e'); print(t2005,'f'); print(t2006,'g'); print(t2007,'h'); print(t2008,'i'); print(t2009,'j');
|
||||
print(t3000,'a'); print(t3001,'b'); print(t3002,'c'); print(t3003,'d'); print(t3004,'e'); print(t3005,'f'); print(t3006,'g'); print(t3007,'h'); print(t3008,'i'); print(t3009,'j');
|
||||
print(t4000,'a'); print(t4001,'b'); print(t4002,'c'); print(t4003,'d'); print(t4004,'e'); print(t4005,'f'); print(t4006,'g'); print(t4007,'h'); print(t4008,'i'); print(t4009,'j');
|
||||
print(t5000,'a'); print(t5001,'b'); print(t5002,'c'); print(t5003,'d'); print(t5004,'e'); print(t5005,'f'); print(t5006,'g'); print(t5007,'h'); print(t5008,'i'); print(t5009,'j');
|
||||
print(t6000,'a'); print(t6001,'b'); print(t6002,'c'); print(t6003,'d'); print(t6004,'e'); print(t6005,'f'); print(t6006,'g'); print(t6007,'h'); print(t6008,'i'); print(t6009,'j');
|
||||
print(t7000,'a'); print(t7001,'b'); print(t7002,'c'); print(t7003,'d'); print(t7004,'e'); print(t7005,'f'); print(t7006,'g'); print(t7007,'h'); print(t7008,'i'); print(t7009,'j');
|
||||
print(t8000,'a'); print(t8001,'b'); print(t8002,'c'); print(t8003,'d'); print(t8004,'e'); print(t8005,'f'); print(t8006,'g'); print(t8007,'h'); print(t8008,'i'); print(t8009,'j');
|
||||
print(t9000,'a'); print(t9001,'b'); print(t9002,'c'); print(t9003,'d'); print(t9004,'e'); print(t9005,'f'); print(t9006,'g'); print(t9007,'h'); print(t9008,'i'); print(t9009,'j');
|
||||
print(t10000,'a'); print(t10001,'b'); print(t10002,'c'); print(t10003,'d'); print(t10004,'e'); print(t10005,'f'); print(t10006,'g'); print(t10007,'h'); print(t10008,'i'); print(t10009,'j');
|
||||
print(t11000,'a'); print(t11001,'b'); print(t11002,'c'); print(t11003,'d'); print(t11004,'e'); print(t11005,'f'); print(t11006,'g'); print(t11007,'h'); print(t11008,'i'); print(t11009,'j');
|
||||
print(t12000,'a'); print(t12001,'b'); print(t12002,'c'); print(t12003,'d'); print(t12004,'e'); print(t12005,'f'); print(t12006,'g'); print(t12007,'h'); print(t12008,'i'); print(t12009,'j');
|
||||
print(t13000,'a'); print(t13001,'b'); print(t13002,'c'); print(t13003,'d'); print(t13004,'e'); print(t13005,'f'); print(t13006,'g'); print(t13007,'h'); print(t13008,'i'); print(t13009,'j');
|
||||
end
|
||||
print( 'manylocals result:', pcall( manylocals ) )
|
||||
Reference in New Issue
Block a user