Initial sources for planned 2.0 luaj vm release. Most interpreter features and library functions working.
This commit is contained in:
66
test/junit/org/luaj/vm2/AllTests.java
Normal file
66
test/junit/org/luaj/vm2/AllTests.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*******************************************************************************
|
||||
* 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.CompatibiltyTest.LuaJCCompatibilityTest;
|
||||
import org.luaj.vm2.WeakTableTest.WeakKeyTableTest;
|
||||
import org.luaj.vm2.WeakTableTest.WeakKeyValueTableTest;
|
||||
|
||||
public class AllTests {
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite("All Tests for Luaj-vm2");
|
||||
|
||||
// table tests
|
||||
TestSuite vm = new TestSuite("VM Tests");
|
||||
vm.addTestSuite(TypeTest.class);
|
||||
vm.addTestSuite(UnaryBinaryOperatorsTest.class);
|
||||
vm.addTestSuite(MetatableTest.class);
|
||||
vm.addTestSuite(LuaOperationsTest.class);
|
||||
suite.addTest(vm);
|
||||
|
||||
// table tests
|
||||
TestSuite table = new TestSuite("Table Tests");
|
||||
table.addTestSuite(TableTest.class);
|
||||
table.addTestSuite(TableArrayTest.class);
|
||||
table.addTestSuite(TableHashTest.class);
|
||||
table.addTestSuite(WeakTableTest.class);
|
||||
table.addTestSuite(WeakKeyTableTest.class);
|
||||
table.addTestSuite(WeakKeyValueTableTest.class);
|
||||
suite.addTest(table);
|
||||
|
||||
// compatiblity tests
|
||||
suite.addTest(CompatibiltyTest.suite());
|
||||
|
||||
// luajc regression tests
|
||||
TestSuite luajc = new TestSuite("Luajc Tests");
|
||||
luajc.addTestSuite(FragmentsTest.class);
|
||||
luajc.addTest( new TestSuite( LuaJCCompatibilityTest.class, "LuaJC Compatiblity Tests" ) );
|
||||
suite.addTest(luajc);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
}
|
||||
94
test/junit/org/luaj/vm2/CompatibiltyTest.java
Normal file
94
test/junit/org/luaj/vm2/CompatibiltyTest.java
Normal file
@@ -0,0 +1,94 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Compatibility tests for the Luaj VM
|
||||
*
|
||||
* Results are compared for exact match with
|
||||
* the installed C-based lua environment.
|
||||
*/
|
||||
public class CompatibiltyTest {
|
||||
|
||||
private static final String dir = "test/lua";
|
||||
|
||||
abstract protected static class CompatibiltyTestSuite extends ScriptDrivenTest {
|
||||
protected CompatibiltyTestSuite(PlatformType platform) {
|
||||
super(platform,dir);
|
||||
}
|
||||
|
||||
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 testMathLib() { runTest("mathlib"); }
|
||||
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 Test suite() {
|
||||
TestSuite suite = new TestSuite("Compatibility Tests");
|
||||
suite.addTest( new TestSuite( JseCompatibilityTest.class, "JSE Tests" ) );
|
||||
suite.addTest( new TestSuite( JmeCompatibilityTest.class, "JME 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 {
|
||||
System.setProperty("JME", "false");
|
||||
super.setUp();
|
||||
}
|
||||
}
|
||||
public static class LuaJCCompatibilityTest extends CompatibiltyTestSuite {
|
||||
public LuaJCCompatibilityTest() {
|
||||
super(ScriptDrivenTest.PlatformType.LUAJIT);
|
||||
}
|
||||
protected void setUp() throws Exception {
|
||||
System.setProperty("JME", "false");
|
||||
super.setUp();
|
||||
}
|
||||
// skipping - not supported yet
|
||||
public void testDebugLib() {}
|
||||
}
|
||||
}
|
||||
212
test/junit/org/luaj/vm2/FragmentsTest.java
Normal file
212
test/junit/org/luaj/vm2/FragmentsTest.java
Normal file
@@ -0,0 +1,212 @@
|
||||
/*******************************************************************************
|
||||
* 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.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.luajc.LuaJCompiler;
|
||||
|
||||
/**
|
||||
* Test compilation of various fragments that have
|
||||
* caused problems for jit compiling during development.
|
||||
*
|
||||
*/
|
||||
public class FragmentsTest extends TestCase {
|
||||
|
||||
public void runFragment( Varargs expected, String script ) {
|
||||
try {
|
||||
String name = getName();
|
||||
LuaTable _G = org.luaj.vm2.lib.JsePlatform.standardGlobals();
|
||||
InputStream is = new ByteArrayInputStream(script.getBytes("UTF-8"));
|
||||
String java = LuaJCompiler.compileToJava(is, name);
|
||||
LuaValue chunk = LuaJCompiler.javaCompile(java, name);
|
||||
chunk.setfenv(_G);
|
||||
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 testArgParam() {
|
||||
// the name "arg" is treated specially, and ends up masking the argument value in 5.1
|
||||
runFragment( LuaValue.NIL,
|
||||
"function v(arg,...)\n" +
|
||||
" return arg\n" +
|
||||
"end\n" +
|
||||
"return v('abc')\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 testNeedsArgAndHasArg() {
|
||||
runFragment( LuaValue.varargsOf(LuaValue.valueOf(333),LuaValue.NIL,LuaValue.valueOf(222)),
|
||||
"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" +
|
||||
"return r(111,222,333),s(111,222,333)" );
|
||||
|
||||
}
|
||||
|
||||
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" );
|
||||
}
|
||||
}
|
||||
262
test/junit/org/luaj/vm2/LuaOperationsTest.java
Normal file
262
test/junit/org/luaj/vm2/LuaOperationsTest.java
Normal file
@@ -0,0 +1,262 @@
|
||||
/*******************************************************************************
|
||||
* 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.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
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 LuaFunction somefunc = new ZeroArgFunction("sample",0,table) { public LuaValue call() { return NONE;}};
|
||||
private final LuaThread thread = new LuaThread(somefunc,table);
|
||||
private final Prototype proto = new Prototype();
|
||||
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 void testGetfenv() {
|
||||
throwsLuaError( "getfenv", somenil );
|
||||
throwsLuaError( "getfenv", sometrue );
|
||||
throwsLuaError( "getfenv", somefalse );
|
||||
throwsLuaError( "getfenv", zero );
|
||||
throwsLuaError( "getfenv", intint );
|
||||
throwsLuaError( "getfenv", longdouble );
|
||||
throwsLuaError( "getfenv", doubledouble );
|
||||
throwsLuaError( "getfenv", stringstring );
|
||||
throwsLuaError( "getfenv", stringint );
|
||||
throwsLuaError( "getfenv", stringlong );
|
||||
throwsLuaError( "getfenv", stringdouble );
|
||||
throwsLuaError( "getfenv", table );
|
||||
assertTrue( table == thread.getfenv() );
|
||||
assertTrue( table == someclosure.getfenv() );
|
||||
assertTrue( table == somefunc.getfenv() );
|
||||
throwsLuaError( "getfenv", userdataobj );
|
||||
throwsLuaError( "getfenv", userdatacls );
|
||||
}
|
||||
|
||||
public void testSetfenv() {
|
||||
LuaTable table2 = LuaValue.listOf( new LuaValue[] {
|
||||
LuaValue.valueOf("ccc"),
|
||||
LuaValue.valueOf("ddd") } );
|
||||
throwsLuaError( "setfenv", somenil, table2 );
|
||||
throwsLuaError( "setfenv", sometrue, table2 );
|
||||
throwsLuaError( "setfenv", somefalse, table2 );
|
||||
throwsLuaError( "setfenv", zero, table2 );
|
||||
throwsLuaError( "setfenv", intint, table2 );
|
||||
throwsLuaError( "setfenv", longdouble, table2 );
|
||||
throwsLuaError( "setfenv", doubledouble, table2 );
|
||||
throwsLuaError( "setfenv", stringstring, table2 );
|
||||
throwsLuaError( "setfenv", stringint, table2 );
|
||||
throwsLuaError( "setfenv", stringlong, table2 );
|
||||
throwsLuaError( "setfenv", stringdouble, table2 );
|
||||
throwsLuaError( "setfenv", table, table2 );
|
||||
thread.setfenv(table2);
|
||||
assertTrue( table2 == thread.getfenv() );
|
||||
assertTrue( table == someclosure.getfenv() );
|
||||
assertTrue( table == somefunc.getfenv() );
|
||||
someclosure.setfenv(table2);
|
||||
assertTrue( table2 == someclosure.getfenv() );
|
||||
assertTrue( table == somefunc.getfenv() );
|
||||
somefunc.setfenv(table2);
|
||||
assertTrue( table2 == somefunc.getfenv() );
|
||||
throwsLuaError( "setfenv", userdataobj, table2 );
|
||||
throwsLuaError( "setfenv", userdatacls, table2 );
|
||||
}
|
||||
|
||||
public Prototype createPrototype( String script, String name ) {
|
||||
try {
|
||||
LuaTable _G = org.luaj.vm2.lib.JsePlatform.standardGlobals();
|
||||
InputStream is = new ByteArrayInputStream(script.getBytes("UTF-8"));
|
||||
return LuaC.compile(is, 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");
|
||||
LuaTable _G = org.luaj.vm2.lib.JsePlatform.standardGlobals();
|
||||
LuaC.install();
|
||||
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, _G } );
|
||||
newenv.setmetatable(mt);
|
||||
_G.set("a", aaa);
|
||||
newenv.set("a", eee);
|
||||
|
||||
// function tests
|
||||
{
|
||||
LuaFunction f = new ZeroArgFunction("f",0,_G) { public LuaValue call() { return env.get("a");}};
|
||||
assertEquals( aaa, f.call() );
|
||||
f.setfenv(newenv);
|
||||
assertEquals( newenv, f.getfenv() );
|
||||
assertEquals( eee, f.call() );
|
||||
}
|
||||
|
||||
// closure tests
|
||||
{
|
||||
Prototype p = createPrototype( "return a\n", "closuretester" );
|
||||
LuaClosure c = new LuaClosure(p, _G);
|
||||
assertEquals( aaa, c.call() );
|
||||
c.setfenv(newenv);
|
||||
assertEquals( newenv, c.getfenv() );
|
||||
assertEquals( eee, c.call() );
|
||||
}
|
||||
|
||||
// thread tests, functions created in threads inherit the thread's environment initially
|
||||
// those closures created not in any other function get the thread's enviroment
|
||||
Prototype p2 = createPrototype( "return loadstring('return a')", "threadtester" );
|
||||
{
|
||||
LuaThread t = new LuaThread(new LuaClosure(p2,_G), _G);
|
||||
Varargs v = t.resume(LuaValue.NONE);
|
||||
assertEquals(LuaValue.TRUE, v.arg(1) );
|
||||
LuaValue f = v.arg(2);
|
||||
assertEquals( LuaValue.TFUNCTION, f.type() );
|
||||
assertEquals( aaa, f.call() );
|
||||
assertEquals( _G, f.getfenv() );
|
||||
}
|
||||
{
|
||||
// change the thread environment after creation!
|
||||
LuaThread t = new LuaThread(new LuaClosure(p2,_G), _G);
|
||||
t.setfenv(newenv);
|
||||
Varargs v = t.resume(LuaValue.NONE);
|
||||
assertEquals(LuaValue.TRUE, v.arg(1) );
|
||||
LuaValue f = v.arg(2);
|
||||
assertEquals( LuaValue.TFUNCTION, f.type() );
|
||||
assertEquals( eee, f.call() );
|
||||
assertEquals( newenv, f.getfenv() );
|
||||
}
|
||||
{
|
||||
// let the closure have a different environment from the thread
|
||||
Prototype p3 = createPrototype( "return function() return a end", "envtester" );
|
||||
LuaThread t = new LuaThread(new LuaClosure(p3,newenv), _G);
|
||||
Varargs v = t.resume(LuaValue.NONE);
|
||||
assertEquals(LuaValue.TRUE, v.arg(1) );
|
||||
LuaValue f = v.arg(2);
|
||||
assertEquals( LuaValue.TFUNCTION, f.type() );
|
||||
assertEquals( eee, f.call() );
|
||||
assertEquals( newenv, f.getfenv() );
|
||||
}
|
||||
}
|
||||
}
|
||||
366
test/junit/org/luaj/vm2/MetatableTest.java
Normal file
366
test/junit/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(function,table);
|
||||
private final LuaClosure closure = new LuaClosure();
|
||||
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.toString()+"]=xyz" );
|
||||
}
|
||||
|
||||
});
|
||||
assertEquals( "table[1]=xyz", table.get(1).toString() );
|
||||
assertEquals( "userdata[1]=xyz", userdata.get(1).toString() );
|
||||
assertEquals( "nil[1]=xyz", LuaValue.NIL.get(1).toString() );
|
||||
assertEquals( "boolean[1]=xyz", LuaValue.TRUE.get(1).toString() );
|
||||
assertEquals( "number[1]=xyz", LuaValue.ONE.get(1).toString() );
|
||||
// assertEquals( "string[1]=xyz", string.get(1).toString() );
|
||||
assertEquals( "function[1]=xyz", function.get(1).toString() );
|
||||
assertEquals( "thread[1]=xyz", thread.get(1).toString() );
|
||||
}
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
247
test/junit/org/luaj/vm2/ScriptDrivenTest.java
Normal file
247
test/junit/org/luaj/vm2/ScriptDrivenTest.java
Normal file
@@ -0,0 +1,247 @@
|
||||
/*******************************************************************************
|
||||
* 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.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.luaj.vm2.compiler.LuaC;
|
||||
import org.luaj.vm2.lib.BaseLib;
|
||||
import org.luaj.vm2.lib.CoroutineLib;
|
||||
import org.luaj.vm2.lib.DebugLib;
|
||||
import org.luaj.vm2.luajc.LuaJCompiler;
|
||||
|
||||
abstract
|
||||
public class ScriptDrivenTest extends TestCase {
|
||||
public static final boolean nocompile = "true".equals(System.getProperty("nocompile"));
|
||||
|
||||
public enum PlatformType {
|
||||
JME, JSE, LUAJIT,
|
||||
}
|
||||
|
||||
private final PlatformType platform;
|
||||
private final String basedir;
|
||||
|
||||
protected ScriptDrivenTest( PlatformType platform, String directory ) {
|
||||
this.platform = platform;
|
||||
this.basedir = directory;
|
||||
}
|
||||
|
||||
// */
|
||||
protected void runTest(String testName) {
|
||||
try {
|
||||
|
||||
// create globals
|
||||
LuaC.install();
|
||||
LuaTable _G = null;
|
||||
switch ( platform ) {
|
||||
default:
|
||||
case JSE:
|
||||
case LUAJIT:
|
||||
_G = org.luaj.vm2.lib.JsePlatform.standardGlobals();
|
||||
break;
|
||||
case JME:
|
||||
_G = org.luaj.vm2.lib.JmePlatform.standardGlobals();
|
||||
break;
|
||||
}
|
||||
DebugLib.install( _G );
|
||||
|
||||
// override print()
|
||||
final ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
final PrintStream oldps = BaseLib.STDOUT;
|
||||
final PrintStream ps = new PrintStream( output );
|
||||
BaseLib.STDOUT = ps;
|
||||
|
||||
// run the script
|
||||
try {
|
||||
LuaValue chunk = loadScript(testName, _G);
|
||||
chunk.call(LuaValue.valueOf(platform.toString()));
|
||||
|
||||
ps.flush();
|
||||
final String actualOutput = new String(output.toByteArray());
|
||||
final String expectedOutput = getExpectedOutput(testName);
|
||||
|
||||
assertEquals(expectedOutput, actualOutput);
|
||||
} finally {
|
||||
BaseLib.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, LuaTable _G) throws IOException {
|
||||
File file = new File(basedir+"/"+name+".lua");
|
||||
if ( !file.exists() )
|
||||
fail("Could not load script for test case: " + name);
|
||||
|
||||
InputStream script=null;
|
||||
try {
|
||||
// Use "stdin" instead of resource name so that output matches
|
||||
// standard Lua.
|
||||
switch ( this.platform ) {
|
||||
case LUAJIT:
|
||||
if ( nocompile ) {
|
||||
LuaValue c = (LuaValue) Class.forName(name).newInstance();
|
||||
c.setfenv(_G);
|
||||
return c;
|
||||
} else {
|
||||
script = new FileInputStream(file);
|
||||
return LuaJCompiler.compile( script, name, _G);
|
||||
}
|
||||
default:
|
||||
script = new FileInputStream(file);
|
||||
Prototype p = LoadState.undump(script, "stdin");
|
||||
return new LuaClosure(p,_G);
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
e.printStackTrace();
|
||||
throw new IOException( e.toString() );
|
||||
} finally {
|
||||
if ( script != null )
|
||||
script.close();
|
||||
}
|
||||
}
|
||||
|
||||
private String getExpectedOutput(final String name) throws IOException,
|
||||
InterruptedException {
|
||||
String expectedOutputName = basedir+"/"+name+"-expected.out";
|
||||
File file = new File( expectedOutputName );
|
||||
if ( file.exists() ) {
|
||||
InputStream is = new FileInputStream(file);
|
||||
try {
|
||||
return readString(is);
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
} else {
|
||||
file = new File(basedir+"/"+name+".lua");
|
||||
if ( !file.exists() )
|
||||
fail("Could not load script for test case: " + name);
|
||||
InputStream script = new FileInputStream(file);
|
||||
// }
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String collectProcessOutput(String[] cmd, final InputStream input)
|
||||
throws IOException, InterruptedException {
|
||||
Runtime r = Runtime.getRuntime();
|
||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
final Process p = r.exec(cmd);
|
||||
try {
|
||||
// start a thread to write the given input to the subprocess.
|
||||
Thread inputCopier = (new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
OutputStream processStdIn = p.getOutputStream();
|
||||
try {
|
||||
copy(input, processStdIn);
|
||||
} finally {
|
||||
processStdIn.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
inputCopier.start();
|
||||
|
||||
// start another thread to read output from the subprocess.
|
||||
Thread outputCopier = (new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
InputStream processStdOut = p.getInputStream();
|
||||
try {
|
||||
copy(processStdOut, baos);
|
||||
} finally {
|
||||
processStdOut.close();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
outputCopier.start();
|
||||
|
||||
// start another thread to read output from the subprocess.
|
||||
Thread errorCopier = (new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
InputStream processError = p.getErrorStream();
|
||||
try {
|
||||
copy(processError, System.err);
|
||||
} finally {
|
||||
processError.close();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
errorCopier.start();
|
||||
|
||||
p.waitFor();
|
||||
inputCopier.join();
|
||||
outputCopier.join();
|
||||
errorCopier.join();
|
||||
|
||||
return new String(baos.toByteArray());
|
||||
|
||||
} finally {
|
||||
p.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
private String readString(InputStream is) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
copy(is, baos);
|
||||
return new String(baos.toByteArray());
|
||||
}
|
||||
|
||||
private void copy(InputStream is, OutputStream os) throws IOException {
|
||||
byte[] buf = new byte[1024];
|
||||
int r;
|
||||
while ((r = is.read(buf)) >= 0) {
|
||||
os.write(buf, 0, r);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
355
test/junit/org/luaj/vm2/TableArrayTest.java
Normal file
355
test/junit/org/luaj/vm2/TableArrayTest.java
Normal file
@@ -0,0 +1,355 @@
|
||||
/*******************************************************************************
|
||||
* 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.Vector;
|
||||
|
||||
import org.luaj.vm2.LuaDouble;
|
||||
import org.luaj.vm2.LuaInteger;
|
||||
import org.luaj.vm2.LuaString;
|
||||
import org.luaj.vm2.LuaTable;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests for tables used as lists.
|
||||
*/
|
||||
public class TableArrayTest extends TestCase {
|
||||
|
||||
protected LuaTable new_Table() {
|
||||
return new LuaTable();
|
||||
}
|
||||
|
||||
protected LuaTable new_Table(int n,int m) {
|
||||
return new LuaTable(n,m);
|
||||
}
|
||||
|
||||
public void testInOrderIntegerKeyInsertion() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
t.set( i, LuaString.valueOf( "Test Value! "+i ) );
|
||||
}
|
||||
|
||||
// Ensure all keys are still there.
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
assertEquals( "Test Value! " + i, t.get( i ).toString() );
|
||||
}
|
||||
|
||||
// Ensure capacities make sense
|
||||
assertEquals( 0, t.hashCapacity() );
|
||||
|
||||
assertTrue( t.arrayCapacity() >= 32 );
|
||||
assertTrue( t.arrayCapacity() <= 64 );
|
||||
|
||||
}
|
||||
|
||||
public void testResize() {
|
||||
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.arrayCapacity() >= 0 && t.arrayCapacity() <= 2 );
|
||||
assertTrue( t.hashCapacity() >= 4 );
|
||||
}
|
||||
|
||||
public void testOutOfOrderIntegerKeyInsertion() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 32; i > 0; --i ) {
|
||||
t.set( i, LuaString.valueOf( "Test Value! "+i ) );
|
||||
}
|
||||
|
||||
// Ensure all keys are still there.
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
assertEquals( "Test Value! "+i, t.get( i ).toString() );
|
||||
}
|
||||
|
||||
// Ensure capacities make sense
|
||||
assertTrue( t.arrayCapacity() >= 0 );
|
||||
assertTrue( t.arrayCapacity() <= 6 );
|
||||
|
||||
assertTrue( t.hashCapacity() >= 16 );
|
||||
assertTrue( t.hashCapacity() <= 64 );
|
||||
|
||||
}
|
||||
|
||||
public void testStringAndIntegerKeys() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 0; i < 10; ++i ) {
|
||||
LuaString str = LuaString.valueOf( String.valueOf( i ) );
|
||||
t.set( i, str );
|
||||
t.set( str, LuaInteger.valueOf( i ) );
|
||||
}
|
||||
|
||||
assertTrue( t.arrayCapacity() >= 9 ); // 1, 2, ..., 9
|
||||
assertTrue( t.arrayCapacity() <= 18 );
|
||||
assertTrue( t.hashCapacity() >= 11 ); // 0, "0", "1", ..., "9"
|
||||
assertTrue( t.hashCapacity() <= 33 );
|
||||
|
||||
LuaValue[] keys = t.keys();
|
||||
|
||||
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.toString() );
|
||||
assertEquals( String.valueOf( ik ), k.toString() );
|
||||
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", LuaString.valueOf("foo") );
|
||||
t.set( "explode", LuaString.valueOf("explode") );
|
||||
assertEquals( 2, t.keyCount() );
|
||||
}
|
||||
|
||||
public void testRemove0() {
|
||||
LuaTable t = new_Table(2, 0);
|
||||
|
||||
t.set( 1, LuaString.valueOf("foo") );
|
||||
t.set( 2, LuaString.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);
|
||||
assertEquals( 0, t.keyCount() );
|
||||
|
||||
t.set( "test", LuaString.valueOf("foo") );
|
||||
assertEquals( 1, t.keyCount() );
|
||||
t.set( "explode", LuaValue.NIL );
|
||||
assertEquals( 1, t.keyCount() );
|
||||
t.set( 42, LuaValue.NIL );
|
||||
assertEquals( 1, t.keyCount() );
|
||||
t.set( new_Table(), LuaValue.NIL );
|
||||
assertEquals( 1, t.keyCount() );
|
||||
t.set( "test", LuaValue.NIL );
|
||||
assertEquals( 0, t.keyCount() );
|
||||
|
||||
t.set( 10, LuaInteger.valueOf( 5 ) );
|
||||
t.set( 10, LuaValue.NIL );
|
||||
assertEquals( 0, t.keyCount() );
|
||||
}
|
||||
|
||||
public void testRemove2() {
|
||||
LuaTable t = new_Table(0, 1);
|
||||
|
||||
t.set( "test", LuaString.valueOf("foo") );
|
||||
t.set( "string", LuaInteger.valueOf( 10 ) );
|
||||
assertEquals( 2, t.keyCount() );
|
||||
|
||||
t.set( "string", LuaValue.NIL );
|
||||
t.set( "three", LuaDouble.valueOf( 3.14 ) );
|
||||
assertEquals( 2, t.keyCount() );
|
||||
|
||||
t.set( "test", LuaValue.NIL );
|
||||
assertEquals( 1, t.keyCount() );
|
||||
|
||||
t.set( 10, LuaInteger.valueOf( 5 ) );
|
||||
assertEquals( 2, t.keyCount() );
|
||||
|
||||
t.set( 10, LuaValue.NIL );
|
||||
assertEquals( 1, t.keyCount() );
|
||||
|
||||
t.set( "three", LuaValue.NIL );
|
||||
assertEquals( 0, t.keyCount() );
|
||||
}
|
||||
|
||||
public void testInOrderlen() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
LuaValue v = LuaString.valueOf( "Test Value! "+i );
|
||||
t.set( i, v );
|
||||
assertEquals( i, t.length() );
|
||||
assertEquals( i, t.maxn() );
|
||||
}
|
||||
}
|
||||
|
||||
public void testOutOfOrderlen() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int j=8; j<32; j+=8 ) {
|
||||
for ( int i = j; i > 0; --i ) {
|
||||
t.set( i, LuaString.valueOf( "Test Value! "+i ) );
|
||||
}
|
||||
assertEquals( j, t.length() );
|
||||
assertEquals( j, t.maxn() );
|
||||
}
|
||||
}
|
||||
|
||||
public void testStringKeyslen() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
t.set( "str-"+i, LuaString.valueOf( "String Key Test Value! "+i ) );
|
||||
assertEquals( 0, t.length() );
|
||||
assertEquals( 0, t.maxn() );
|
||||
}
|
||||
}
|
||||
|
||||
public void testMixedKeyslen() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
t.set( "str-"+i, LuaString.valueOf( "String Key Test Value! "+i ) );
|
||||
t.set( i, LuaString.valueOf( "Int Key Test Value! "+i ) );
|
||||
assertEquals( i, t.length() );
|
||||
assertEquals( i, t.maxn() );
|
||||
}
|
||||
}
|
||||
|
||||
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).toString();
|
||||
vj = ((LuaString)vj).toString();
|
||||
assertEquals(vj,tj);
|
||||
}
|
||||
}
|
||||
|
||||
public void testInsertBeginningOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector v = new Vector();
|
||||
|
||||
for ( int i = 1; i <= 32; ++i ) {
|
||||
LuaString test = LuaString.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 = LuaString.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 = LuaString.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 = LuaString.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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
245
test/junit/org/luaj/vm2/TableHashTest.java
Normal file
245
test/junit/org/luaj/vm2/TableHashTest.java
Normal file
@@ -0,0 +1,245 @@
|
||||
/*******************************************************************************
|
||||
* 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.hashCapacity() );
|
||||
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, 4, 4, 7, 7, 7, 10, 10, 14, 14, 14, 14, 19, 19, 19, 19, 25, 25, 25 };
|
||||
for ( int i = 0; i < keys.length; ++i ) {
|
||||
assertEquals( capacities[i], t.hashCapacity() );
|
||||
String si = "Test Value! "+i;
|
||||
t.set( keys[i], si );
|
||||
assertEquals( 0, t.length() );
|
||||
assertEquals( i+1, t.keyCount() );
|
||||
}
|
||||
assertEquals( capacities[keys.length], t.hashCapacity() );
|
||||
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.hashCapacity() );
|
||||
}
|
||||
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.hashCapacity() );
|
||||
else
|
||||
assertTrue( 0<=t.hashCapacity() );
|
||||
}
|
||||
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").toString() );
|
||||
assertEquals( "def", t.get(123).toString() );
|
||||
assertEquals( "nil", t.get("qqq").toString() );
|
||||
assertEquals( "nil", t.get(456).toString() );
|
||||
assertEquals( "nil", fb.get("ppp").toString() );
|
||||
assertEquals( "nil", fb.get(123).toString() );
|
||||
assertEquals( "ghi", fb.get("qqq").toString() );
|
||||
assertEquals( "jkl", fb.get(456).toString() );
|
||||
assertEquals( "nil", mt.get("ppp").toString() );
|
||||
assertEquals( "nil", mt.get(123).toString() );
|
||||
assertEquals( "nil", mt.get("qqq").toString() );
|
||||
assertEquals( "nil", mt.get(456).toString() );
|
||||
|
||||
// check before setting metatable
|
||||
t.setmetatable(mt);
|
||||
assertEquals( mt, t.getmetatable() );
|
||||
assertEquals( "abc", t.get("ppp").toString() );
|
||||
assertEquals( "def", t.get(123).toString() );
|
||||
assertEquals( "ghi", t.get("qqq").toString() );
|
||||
assertEquals( "jkl", t.get(456).toString() );
|
||||
assertEquals( "nil", fb.get("ppp").toString() );
|
||||
assertEquals( "nil", fb.get(123).toString() );
|
||||
assertEquals( "ghi", fb.get("qqq").toString() );
|
||||
assertEquals( "jkl", fb.get(456).toString() );
|
||||
assertEquals( "nil", mt.get("ppp").toString() );
|
||||
assertEquals( "nil", mt.get(123).toString() );
|
||||
assertEquals( "nil", mt.get("qqq").toString() );
|
||||
assertEquals( "nil", mt.get(456).toString() );
|
||||
|
||||
// set metatable to metatable without values
|
||||
t.setmetatable(fb);
|
||||
assertEquals( "abc", t.get("ppp").toString() );
|
||||
assertEquals( "def", t.get(123).toString() );
|
||||
assertEquals( "nil", t.get("qqq").toString() );
|
||||
assertEquals( "nil", t.get(456).toString() );
|
||||
|
||||
// set metatable to null
|
||||
t.setmetatable(null);
|
||||
assertEquals( "abc", t.get("ppp").toString() );
|
||||
assertEquals( "def", t.get(123).toString() );
|
||||
assertEquals( "nil", t.get("qqq").toString() );
|
||||
assertEquals( "nil", t.get(456).toString() );
|
||||
}
|
||||
|
||||
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").toString() );
|
||||
assertEquals( "def", t.get(123).toString() );
|
||||
assertEquals( "nil", t.get("qqq").toString() );
|
||||
assertEquals( "nil", t.get(456).toString() );
|
||||
|
||||
|
||||
// check before setting metatable
|
||||
t.setmetatable(mt);
|
||||
assertEquals( mt, t.getmetatable() );
|
||||
assertEquals( "abc", t.get("ppp").toString() );
|
||||
assertEquals( "def", t.get(123).toString() );
|
||||
assertEquals( "from mt: qqq", t.get("qqq").toString() );
|
||||
assertEquals( "from mt: 456", t.get(456).toString() );
|
||||
|
||||
// use raw set
|
||||
t.rawset("qqq", "alt-qqq");
|
||||
t.rawset(456, "alt-456");
|
||||
assertEquals( "abc", t.get("ppp").toString() );
|
||||
assertEquals( "def", t.get(123).toString() );
|
||||
assertEquals( "alt-qqq", t.get("qqq").toString() );
|
||||
assertEquals( "alt-456", t.get(456).toString() );
|
||||
|
||||
// remove using raw set
|
||||
t.rawset("qqq", LuaValue.NIL);
|
||||
t.rawset(456, LuaValue.NIL);
|
||||
assertEquals( "abc", t.get("ppp").toString() );
|
||||
assertEquals( "def", t.get(123).toString() );
|
||||
assertEquals( "from mt: qqq", t.get("qqq").toString() );
|
||||
assertEquals( "from mt: 456", t.get(456).toString() );
|
||||
|
||||
// set metatable to null
|
||||
t.setmetatable(null);
|
||||
assertEquals( "abc", t.get("ppp").toString() );
|
||||
assertEquals( "def", t.get(123).toString() );
|
||||
assertEquals( "nil", t.get("qqq").toString() );
|
||||
assertEquals( "nil", t.get(456).toString() );
|
||||
}
|
||||
|
||||
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")) );
|
||||
}
|
||||
}
|
||||
340
test/junit/org/luaj/vm2/TableTest.java
Normal file
340
test/junit/org/luaj/vm2/TableTest.java
Normal file
@@ -0,0 +1,340 @@
|
||||
/*******************************************************************************
|
||||
* 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.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);
|
||||
}
|
||||
|
||||
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 ).toString() );
|
||||
}
|
||||
|
||||
// Ensure capacities make sense
|
||||
assertEquals( 0, t.hashCapacity() );
|
||||
|
||||
assertTrue( t.arrayCapacity() >= 32 );
|
||||
assertTrue( t.arrayCapacity() <= 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.arrayCapacity() >= 0 && t.arrayCapacity() <= 2 );
|
||||
assertTrue( t.hashCapacity() >= 4 );
|
||||
}
|
||||
|
||||
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 ).toString() );
|
||||
}
|
||||
|
||||
// Ensure capacities make sense
|
||||
assertTrue( t.arrayCapacity() >= 0 );
|
||||
assertTrue( t.arrayCapacity() <= 6 );
|
||||
|
||||
assertTrue( t.hashCapacity() >= 16 );
|
||||
assertTrue( t.hashCapacity() <= 64 );
|
||||
|
||||
}
|
||||
|
||||
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.arrayCapacity() >= 9 ); // 1, 2, ..., 9
|
||||
assertTrue( t.arrayCapacity() <= 18 );
|
||||
assertTrue( t.hashCapacity() >= 11 ); // 0, "0", "1", ..., "9"
|
||||
assertTrue( t.hashCapacity() <= 33 );
|
||||
|
||||
LuaValue[] keys = t.keys();
|
||||
|
||||
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().toString() );
|
||||
assertEquals( String.valueOf( ik ), k.strvalue().toString() );
|
||||
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, t.keyCount() );
|
||||
}
|
||||
|
||||
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, t.keyCount() );
|
||||
|
||||
t.set( 10, LuaInteger.valueOf( 5 ) );
|
||||
t.set( 10, LuaValue.NIL );
|
||||
assertEquals( 0, t.keyCount() );
|
||||
}
|
||||
|
||||
public void testRemove2() {
|
||||
LuaTable t = new_Table(0, 1);
|
||||
|
||||
t.set( "test", LuaValue.valueOf("foo") );
|
||||
t.set( "string", LuaInteger.valueOf( 10 ) );
|
||||
assertEquals( 2, t.keyCount() );
|
||||
|
||||
t.set( "string", LuaValue.NIL );
|
||||
t.set( "three", LuaValue.valueOf( 3.14 ) );
|
||||
assertEquals( 2, t.keyCount() );
|
||||
|
||||
t.set( "test", LuaValue.NIL );
|
||||
assertEquals( 1, t.keyCount() );
|
||||
|
||||
t.set( 10, LuaInteger.valueOf( 5 ) );
|
||||
assertEquals( 2, t.keyCount() );
|
||||
|
||||
t.set( 10, LuaValue.NIL );
|
||||
assertEquals( 1, t.keyCount() );
|
||||
|
||||
t.set( "three", LuaValue.NIL );
|
||||
assertEquals( 0, t.keyCount() );
|
||||
}
|
||||
|
||||
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() );
|
||||
assertEquals( i, t.maxn() );
|
||||
}
|
||||
}
|
||||
|
||||
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() );
|
||||
assertEquals( j, t.maxn() );
|
||||
}
|
||||
}
|
||||
|
||||
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() );
|
||||
assertEquals( 0, t.maxn() );
|
||||
}
|
||||
}
|
||||
|
||||
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() );
|
||||
assertEquals( i, t.maxn() );
|
||||
}
|
||||
}
|
||||
|
||||
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).toString();
|
||||
vj = ((LuaString)vj).toString();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1242
test/junit/org/luaj/vm2/TypeTest.java
Normal file
1242
test/junit/org/luaj/vm2/TypeTest.java
Normal file
File diff suppressed because it is too large
Load Diff
557
test/junit/org/luaj/vm2/UnaryBinaryOperatorsTest.java
Normal file
557
test/junit/org/luaj/vm2/UnaryBinaryOperatorsTest.java
Normal file
@@ -0,0 +1,557 @@
|
||||
/*******************************************************************************
|
||||
* 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 org.luaj.vm2.LuaDouble;
|
||||
import org.luaj.vm2.LuaInteger;
|
||||
import org.luaj.vm2.LuaString;
|
||||
import org.luaj.vm2.LuaValue;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests of basic unary and binary operators on main value types.
|
||||
*/
|
||||
public class UnaryBinaryOperatorsTest extends TestCase {
|
||||
|
||||
LuaValue dummy;
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
dummy = LuaValue.ZERO;
|
||||
}
|
||||
|
||||
public void testEqualsBool() {
|
||||
assertEquals(LuaValue.FALSE,LuaValue.FALSE);
|
||||
assertEquals(LuaValue.TRUE,LuaValue.TRUE);
|
||||
assertTrue(LuaValue.FALSE.equals(LuaValue.FALSE));
|
||||
assertTrue(LuaValue.TRUE.equals(LuaValue.TRUE));
|
||||
assertTrue(!LuaValue.FALSE.equals(LuaValue.TRUE));
|
||||
assertTrue(!LuaValue.TRUE.equals(LuaValue.FALSE));
|
||||
assertTrue(LuaValue.FALSE.eq_b(LuaValue.FALSE));
|
||||
assertTrue(LuaValue.TRUE.eq_b(LuaValue.TRUE));
|
||||
assertFalse(LuaValue.FALSE.eq_b(LuaValue.TRUE));
|
||||
assertFalse(LuaValue.TRUE.eq_b(LuaValue.FALSE));
|
||||
assertEquals(LuaValue.TRUE, LuaValue.FALSE.eq(LuaValue.FALSE));
|
||||
assertEquals(LuaValue.TRUE, LuaValue.TRUE.eq(LuaValue.TRUE));
|
||||
assertEquals(LuaValue.FALSE, LuaValue.FALSE.eq(LuaValue.TRUE));
|
||||
assertEquals(LuaValue.FALSE, LuaValue.TRUE.eq(LuaValue.FALSE));
|
||||
assertFalse(LuaValue.FALSE.neq_b(LuaValue.FALSE));
|
||||
assertFalse(LuaValue.TRUE.neq_b(LuaValue.TRUE));
|
||||
assertTrue(LuaValue.FALSE.neq_b(LuaValue.TRUE));
|
||||
assertTrue(LuaValue.TRUE.neq_b(LuaValue.FALSE));
|
||||
assertEquals(LuaValue.FALSE, LuaValue.FALSE.neq(LuaValue.FALSE));
|
||||
assertEquals(LuaValue.FALSE, LuaValue.TRUE.neq(LuaValue.TRUE));
|
||||
assertEquals(LuaValue.TRUE, LuaValue.FALSE.neq(LuaValue.TRUE));
|
||||
assertEquals(LuaValue.TRUE, LuaValue.TRUE.neq(LuaValue.FALSE));
|
||||
assertTrue(LuaValue.TRUE.toboolean());
|
||||
assertFalse(LuaValue.FALSE.toboolean());
|
||||
}
|
||||
|
||||
public void testNot() {
|
||||
LuaValue ia=LuaValue.valueOf(3);
|
||||
LuaValue da=LuaValue.valueOf(.25);
|
||||
LuaValue sa=LuaValue.valueOf("1.5");
|
||||
LuaValue ba=LuaValue.TRUE, bb=LuaValue.FALSE;
|
||||
|
||||
// like kinds
|
||||
assertEquals(LuaValue.FALSE, ia.not());
|
||||
assertEquals(LuaValue.FALSE, da.not());
|
||||
assertEquals(LuaValue.FALSE, sa.not());
|
||||
assertEquals(LuaValue.FALSE, ba.not());
|
||||
assertEquals(LuaValue.TRUE, bb.not());
|
||||
}
|
||||
|
||||
public void testNeg() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(-4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(-.5);
|
||||
LuaValue sa=LuaValue.valueOf("1.5"), sb=LuaValue.valueOf("-2.0");
|
||||
|
||||
// like kinds
|
||||
assertEquals(-3., ia.neg().todouble());
|
||||
assertEquals(-.25, da.neg().todouble());
|
||||
assertEquals(-1.5, sa.neg().todouble());
|
||||
assertEquals(4., ib.neg().todouble());
|
||||
assertEquals(.5, db.neg().todouble());
|
||||
assertEquals(2.0, sb.neg().todouble());
|
||||
}
|
||||
|
||||
public void testDoublesBecomeInts() {
|
||||
// DoubleValue.valueOf should return int
|
||||
LuaValue ia=LuaInteger.valueOf(345), da=LuaDouble.valueOf(345.0), db=LuaDouble.valueOf(345.5);
|
||||
LuaValue sa=LuaValue.valueOf("3.0"), sb=LuaValue.valueOf("3"), sc=LuaValue.valueOf("-2.0"), sd=LuaValue.valueOf("-2");
|
||||
|
||||
assertEquals(ia,da);
|
||||
assertTrue(ia instanceof LuaInteger);
|
||||
assertTrue(da instanceof LuaInteger);
|
||||
assertTrue(db instanceof LuaDouble);
|
||||
assertEquals( ia.toint(), 345 );
|
||||
assertEquals( da.toint(), 345 );
|
||||
assertEquals( da.todouble(), 345.0 );
|
||||
assertEquals( db.todouble(), 345.5 );
|
||||
|
||||
assertTrue(sa instanceof LuaString);
|
||||
assertTrue(sb instanceof LuaString);
|
||||
assertTrue(sc instanceof LuaString);
|
||||
assertTrue(sd instanceof LuaString);
|
||||
assertEquals( 3., sa.todouble() );
|
||||
assertEquals( 3., sb.todouble() );
|
||||
assertEquals( -2., sc.todouble() );
|
||||
assertEquals( -2., sd.todouble() );
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testEqualsInt() {
|
||||
LuaValue ia=LuaInteger.valueOf(345), ib=LuaInteger.valueOf(345), ic=LuaInteger.valueOf(-345);
|
||||
LuaString sa=LuaString.valueOf("345"), sb=LuaString.valueOf("345"), sc=LuaString.valueOf("-345");
|
||||
|
||||
// objects should be different
|
||||
assertNotSame(ia, ib);
|
||||
assertNotSame(sa, sb);
|
||||
assertNotSame(ia, ic);
|
||||
assertNotSame(sa, sc);
|
||||
|
||||
// assert equals for same type
|
||||
assertEquals(ia, ib);
|
||||
assertEquals(sa, sb);
|
||||
assertFalse(ia.equals(ic));
|
||||
assertFalse(sa.equals(sc));
|
||||
|
||||
// check object equality for different types
|
||||
assertFalse(ia.equals(sa));
|
||||
assertFalse(sa.equals(ia));
|
||||
}
|
||||
|
||||
public void testEqualsDouble() {
|
||||
LuaValue da=LuaDouble.valueOf(345.5), db=LuaDouble.valueOf(345.5), dc=LuaDouble.valueOf(-345.5);
|
||||
LuaString sa=LuaString.valueOf("345.5"), sb=LuaString.valueOf("345.5"), sc=LuaString.valueOf("-345.5");
|
||||
|
||||
// objects should be different
|
||||
assertNotSame(da, db);
|
||||
assertNotSame(sa, sb);
|
||||
assertNotSame(da, dc);
|
||||
assertNotSame(sa, sc);
|
||||
|
||||
// assert equals for same type
|
||||
assertEquals(da, db);
|
||||
assertEquals(sa, sb);
|
||||
assertFalse(da.equals(dc));
|
||||
assertFalse(sa.equals(sc));
|
||||
|
||||
// check object equality for different types
|
||||
assertFalse(da.equals(sa));
|
||||
assertFalse(sa.equals(da));
|
||||
}
|
||||
|
||||
public void testEqInt() {
|
||||
LuaValue ia=LuaInteger.valueOf(345), ib=LuaInteger.valueOf(345), ic=LuaInteger.valueOf(-123);
|
||||
LuaValue sa=LuaString.valueOf("345"), sb=LuaString.valueOf("345"), sc=LuaString.valueOf("-345");
|
||||
|
||||
// check arithmetic equality among same types
|
||||
assertEquals(ia.eq(ib),LuaValue.TRUE);
|
||||
assertEquals(sa.eq(sb),LuaValue.TRUE);
|
||||
assertEquals(ia.eq(ic),LuaValue.FALSE);
|
||||
assertEquals(sa.eq(sc),LuaValue.FALSE);
|
||||
|
||||
// check arithmetic equality among different types
|
||||
assertEquals(ia.eq(sa),LuaValue.FALSE);
|
||||
assertEquals(sa.eq(ia),LuaValue.FALSE);
|
||||
}
|
||||
|
||||
public void testEqDouble() {
|
||||
LuaValue da=LuaDouble.valueOf(345.5), db=LuaDouble.valueOf(345.5), dc=LuaDouble.valueOf(-345.5);
|
||||
LuaValue sa=LuaString.valueOf("345.5"), sb=LuaString.valueOf("345.5"), sc=LuaString.valueOf("-345.5");
|
||||
|
||||
// check arithmetic equality among same types
|
||||
assertEquals(da.eq(db),LuaValue.TRUE);
|
||||
assertEquals(sa.eq(sb),LuaValue.TRUE);
|
||||
assertEquals(da.eq(dc),LuaValue.FALSE);
|
||||
assertEquals(sa.eq(sc),LuaValue.FALSE);
|
||||
|
||||
// check arithmetic equality among different types
|
||||
assertEquals(da.eq(sa),LuaValue.FALSE);
|
||||
assertEquals(sa.eq(da),LuaValue.FALSE);
|
||||
}
|
||||
|
||||
public void testAdd() {
|
||||
LuaValue ia=LuaValue.valueOf(111), ib=LuaValue.valueOf(44);
|
||||
LuaValue da=LuaValue.valueOf(55.25), db=LuaValue.valueOf(3.5);
|
||||
LuaValue sa=LuaValue.valueOf("22.125"), sb=LuaValue.valueOf("7.25");
|
||||
|
||||
// check types
|
||||
assertTrue( ia instanceof LuaInteger );
|
||||
assertTrue( ib instanceof LuaInteger );
|
||||
assertTrue( da instanceof LuaDouble );
|
||||
assertTrue( db instanceof LuaDouble );
|
||||
assertTrue( sa instanceof LuaString );
|
||||
assertTrue( sb instanceof LuaString );
|
||||
|
||||
// like kinds
|
||||
assertEquals(155.0, ia.add(ib).todouble());
|
||||
assertEquals(58.75, da.add(db).todouble());
|
||||
assertEquals(29.375, sa.add(sb).todouble());
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(166.25, ia.add(da).todouble());
|
||||
assertEquals(166.25, da.add(ia).todouble());
|
||||
assertEquals(133.125,ia.add(sa).todouble());
|
||||
assertEquals(133.125,sa.add(ia).todouble());
|
||||
assertEquals(77.375, da.add(sa).todouble());
|
||||
assertEquals(77.375, sa.add(da).todouble());
|
||||
}
|
||||
|
||||
public void testSub() {
|
||||
LuaValue ia=LuaValue.valueOf(111), ib=LuaValue.valueOf(44);
|
||||
LuaValue da=LuaValue.valueOf(55.25), db=LuaValue.valueOf(3.5);
|
||||
LuaValue sa=LuaValue.valueOf("22.125"), sb=LuaValue.valueOf("7.25");
|
||||
|
||||
// like kinds
|
||||
assertEquals(67.0, ia.sub(ib).todouble());
|
||||
assertEquals(51.75, da.sub(db).todouble());
|
||||
assertEquals(14.875, sa.sub(sb).todouble());
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(55.75, ia.sub(da).todouble());
|
||||
assertEquals(-55.75, da.sub(ia).todouble());
|
||||
assertEquals(88.875, ia.sub(sa).todouble());
|
||||
assertEquals(-88.875, sa.sub(ia).todouble());
|
||||
assertEquals(33.125, da.sub(sa).todouble());
|
||||
assertEquals(-33.125, sa.sub(da).todouble());
|
||||
}
|
||||
|
||||
public void testMul() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
||||
LuaValue sa=LuaValue.valueOf("1.5"), sb=LuaValue.valueOf("2.0");
|
||||
|
||||
// like kinds
|
||||
assertEquals(12.0, ia.mul(ib).todouble());
|
||||
assertEquals(.125, da.mul(db).todouble());
|
||||
assertEquals(3.0, sa.mul(sb).todouble());
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(.75, ia.mul(da).todouble());
|
||||
assertEquals(.75, da.mul(ia).todouble());
|
||||
assertEquals(4.5, ia.mul(sa).todouble());
|
||||
assertEquals(4.5, sa.mul(ia).todouble());
|
||||
assertEquals(.375, da.mul(sa).todouble());
|
||||
assertEquals(.375, sa.mul(da).todouble());
|
||||
}
|
||||
|
||||
public void testDiv() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
||||
LuaValue sa=LuaValue.valueOf("1.5"), sb=LuaValue.valueOf("2.0");
|
||||
|
||||
// like kinds
|
||||
assertEquals(3./4., ia.div(ib).todouble());
|
||||
assertEquals(.25/.5, da.div(db).todouble());
|
||||
assertEquals(1.5/2., sa.div(sb).todouble());
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(3./.25, ia.div(da).todouble());
|
||||
assertEquals(.25/3., da.div(ia).todouble());
|
||||
assertEquals(3./1.5, ia.div(sa).todouble());
|
||||
assertEquals(1.5/3., sa.div(ia).todouble());
|
||||
assertEquals(.25/1.5, da.div(sa).todouble());
|
||||
assertEquals(1.5/.25, sa.div(da).todouble());
|
||||
}
|
||||
|
||||
public void testPow() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||
LuaValue da=LuaValue.valueOf(4.), db=LuaValue.valueOf(.5);
|
||||
LuaValue sa=LuaValue.valueOf("1.5"), sb=LuaValue.valueOf("2.0");
|
||||
|
||||
// like kinds
|
||||
assertEquals(Math.pow(3.,4.), ia.pow(ib).todouble());
|
||||
assertEquals(Math.pow(4.,.5), da.pow(db).todouble());
|
||||
assertEquals(Math.pow(1.5,2.), sa.pow(sb).todouble());
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(Math.pow(3.,4.), ia.pow(da).todouble());
|
||||
assertEquals(Math.pow(4.,3.), da.pow(ia).todouble());
|
||||
assertEquals(Math.pow(3.,1.5), ia.pow(sa).todouble());
|
||||
assertEquals(Math.pow(1.5,3.), sa.pow(ia).todouble());
|
||||
assertEquals(Math.pow(4.,1.5), da.pow(sa).todouble());
|
||||
assertEquals(Math.pow(1.5,4.), sa.pow(da).todouble());
|
||||
}
|
||||
|
||||
private static double luaMod(double x, double y) {
|
||||
return y!=0? x-y*Math.floor(x/y): Double.NaN;
|
||||
}
|
||||
|
||||
public void testMod() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(-4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(-.5);
|
||||
LuaValue sa=LuaValue.valueOf("1.5"), sb=LuaValue.valueOf("-2.0");
|
||||
|
||||
// like kinds
|
||||
assertEquals(luaMod(3.,-4.), ia.mod(ib).todouble());
|
||||
assertEquals(luaMod(.25,-.5), da.mod(db).todouble());
|
||||
assertEquals(luaMod(1.5,-2.), sa.mod(sb).todouble());
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(luaMod(3.,.25), ia.mod(da).todouble());
|
||||
assertEquals(luaMod(.25,3.), da.mod(ia).todouble());
|
||||
assertEquals(luaMod(3.,1.5), ia.mod(sa).todouble());
|
||||
assertEquals(luaMod(1.5,3.), sa.mod(ia).todouble());
|
||||
assertEquals(luaMod(.25,1.5), da.mod(sa).todouble());
|
||||
assertEquals(luaMod(1.5,.25), sa.mod(da).todouble());
|
||||
}
|
||||
|
||||
public void testCompareStrings() {
|
||||
// these are lexical compare!
|
||||
LuaValue sa=LuaValue.valueOf("-1.5");
|
||||
LuaValue sb=LuaValue.valueOf("-2.0");
|
||||
LuaValue sc=LuaValue.valueOf("1.5");
|
||||
LuaValue sd=LuaValue.valueOf("2.0");
|
||||
|
||||
assertEquals(LuaValue.FALSE, sa.lt(sa));
|
||||
assertEquals(LuaValue.TRUE, sa.lt(sb));
|
||||
assertEquals(LuaValue.TRUE, sa.lt(sc));
|
||||
assertEquals(LuaValue.TRUE, sa.lt(sd));
|
||||
assertEquals(LuaValue.FALSE, sb.lt(sa));
|
||||
assertEquals(LuaValue.FALSE, sb.lt(sb));
|
||||
assertEquals(LuaValue.TRUE, sb.lt(sc));
|
||||
assertEquals(LuaValue.TRUE, sb.lt(sd));
|
||||
assertEquals(LuaValue.FALSE, sc.lt(sa));
|
||||
assertEquals(LuaValue.FALSE, sc.lt(sb));
|
||||
assertEquals(LuaValue.FALSE, sc.lt(sc));
|
||||
assertEquals(LuaValue.TRUE, sc.lt(sd));
|
||||
assertEquals(LuaValue.FALSE, sd.lt(sa));
|
||||
assertEquals(LuaValue.FALSE, sd.lt(sb));
|
||||
assertEquals(LuaValue.FALSE, sd.lt(sc));
|
||||
assertEquals(LuaValue.FALSE, sd.lt(sd));
|
||||
}
|
||||
|
||||
public void testLt() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
||||
|
||||
// like kinds
|
||||
assertEquals(3.<4., ia.lt(ib).toboolean());
|
||||
assertEquals(.25<.5, da.lt(db).toboolean());
|
||||
assertEquals(3.<4., ia.lt_b(ib));
|
||||
assertEquals(.25<.5, da.lt_b(db));
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(3.<.25, ia.lt(da).toboolean());
|
||||
assertEquals(.25<3., da.lt(ia).toboolean());
|
||||
assertEquals(3.<.25, ia.lt_b(da));
|
||||
assertEquals(.25<3., da.lt_b(ia));
|
||||
}
|
||||
|
||||
public void testLtEq() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
||||
|
||||
// like kinds
|
||||
assertEquals(3.<=4., ia.lteq(ib).toboolean());
|
||||
assertEquals(.25<=.5, da.lteq(db).toboolean());
|
||||
assertEquals(3.<=4., ia.lteq_b(ib));
|
||||
assertEquals(.25<=.5, da.lteq_b(db));
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(3.<=.25, ia.lteq(da).toboolean());
|
||||
assertEquals(.25<=3., da.lteq(ia).toboolean());
|
||||
assertEquals(3.<=.25, ia.lteq_b(da));
|
||||
assertEquals(.25<=3., da.lteq_b(ia));
|
||||
}
|
||||
|
||||
public void testGt() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
||||
|
||||
// like kinds
|
||||
assertEquals(3.>4., ia.gt(ib).toboolean());
|
||||
assertEquals(.25>.5, da.gt(db).toboolean());
|
||||
assertEquals(3.>4., ia.gt_b(ib));
|
||||
assertEquals(.25>.5, da.gt_b(db));
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(3.>.25, ia.gt(da).toboolean());
|
||||
assertEquals(.25>3., da.gt(ia).toboolean());
|
||||
assertEquals(3.>.25, ia.gt_b(da));
|
||||
assertEquals(.25>3., da.gt_b(ia));
|
||||
}
|
||||
|
||||
public void testGtEq() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
||||
|
||||
// like kinds
|
||||
assertEquals(3.>=4., ia.gteq(ib).toboolean());
|
||||
assertEquals(.25>=.5, da.gteq(db).toboolean());
|
||||
assertEquals(3.>=4., ia.gteq_b(ib));
|
||||
assertEquals(.25>=.5, da.gteq_b(db));
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(3.>=.25, ia.gteq(da).toboolean());
|
||||
assertEquals(.25>=3., da.gteq(ia).toboolean());
|
||||
assertEquals(3.>=.25, ia.gteq_b(da));
|
||||
assertEquals(.25>=3., da.gteq_b(ia));
|
||||
}
|
||||
|
||||
public void testNotEq() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
||||
LuaValue sa=LuaValue.valueOf("1.5"), sb=LuaValue.valueOf("2.0");
|
||||
|
||||
// like kinds
|
||||
assertEquals(3.!=4., ia.neq(ib).toboolean());
|
||||
assertEquals(.25!=.5, da.neq(db).toboolean());
|
||||
assertEquals(1.5!=2., sa.neq(sb).toboolean());
|
||||
assertEquals(3.!=4., ia.neq_b(ib));
|
||||
assertEquals(.25!=.5, da.neq_b(db));
|
||||
assertEquals(1.5!=2., sa.neq_b(sb));
|
||||
|
||||
// unlike kinds
|
||||
assertEquals(3.!=.25, ia.neq(da).toboolean());
|
||||
assertEquals(.25!=3., da.neq(ia).toboolean());
|
||||
assertEquals(3.!=1.5, ia.neq(sa).toboolean());
|
||||
assertEquals(1.5!=3., sa.neq(ia).toboolean());
|
||||
assertEquals(.25!=1.5, da.neq(sa).toboolean());
|
||||
assertEquals(1.5!=.25, sa.neq(da).toboolean());
|
||||
assertEquals(3.!=.25, ia.neq_b(da));
|
||||
assertEquals(.25!=3., da.neq_b(ia));
|
||||
assertEquals(3.!=1.5, ia.neq_b(sa));
|
||||
assertEquals(1.5!=3., sa.neq_b(ia));
|
||||
assertEquals(.25!=1.5, da.neq_b(sa));
|
||||
assertEquals(1.5!=.25, sa.neq_b(da));
|
||||
}
|
||||
|
||||
public void testAnd() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
||||
LuaValue sa=LuaValue.valueOf("1.5"), sb=LuaValue.valueOf("2.0");
|
||||
LuaValue ba=LuaValue.TRUE, bb=LuaValue.FALSE;
|
||||
|
||||
// like kinds
|
||||
assertSame(ib, ia.and(ib));
|
||||
assertSame(db, da.and(db));
|
||||
assertSame(sb, sa.and(sb));
|
||||
|
||||
// unlike kinds
|
||||
assertSame(da, ia.and(da));
|
||||
assertSame(ia, da.and(ia));
|
||||
assertSame(sa, ia.and(sa));
|
||||
assertSame(ia, sa.and(ia));
|
||||
assertSame(sa, da.and(sa));
|
||||
assertSame(da, sa.and(da));
|
||||
|
||||
// boolean values
|
||||
assertSame(bb, ba.and(bb));
|
||||
assertSame(bb, bb.and(ba));
|
||||
assertSame(ia, ba.and(ia));
|
||||
assertSame(bb, bb.and(ia));
|
||||
}
|
||||
|
||||
|
||||
public void testOr() {
|
||||
LuaValue ia=LuaValue.valueOf(3), ib=LuaValue.valueOf(4);
|
||||
LuaValue da=LuaValue.valueOf(.25), db=LuaValue.valueOf(.5);
|
||||
LuaValue sa=LuaValue.valueOf("1.5"), sb=LuaValue.valueOf("2.0");
|
||||
LuaValue ba=LuaValue.TRUE, bb=LuaValue.FALSE;
|
||||
|
||||
// like kinds
|
||||
assertSame(ia, ia.or(ib));
|
||||
assertSame(da, da.or(db));
|
||||
assertSame(sa, sa.or(sb));
|
||||
|
||||
// unlike kinds
|
||||
assertSame(ia, ia.or(da));
|
||||
assertSame(da, da.or(ia));
|
||||
assertSame(ia, ia.or(sa));
|
||||
assertSame(sa, sa.or(ia));
|
||||
assertSame(da, da.or(sa));
|
||||
assertSame(sa, sa.or(da));
|
||||
|
||||
// boolean values
|
||||
assertSame(ba, ba.or(bb));
|
||||
assertSame(ba, bb.or(ba));
|
||||
assertSame(ba, ba.or(ia));
|
||||
assertSame(ia, bb.or(ia));
|
||||
}
|
||||
|
||||
public void testLexicalComparison() {
|
||||
LuaValue aaa = LuaValue.valueOf("aaa");
|
||||
LuaValue baa = LuaValue.valueOf("baa");
|
||||
LuaValue Aaa = LuaValue.valueOf("Aaa");
|
||||
LuaValue aba = LuaValue.valueOf("aba");
|
||||
LuaValue aaaa = LuaValue.valueOf("aaaa");
|
||||
LuaValue t = LuaValue.TRUE;
|
||||
LuaValue f = LuaValue.FALSE;
|
||||
|
||||
// basics
|
||||
assertEquals(t, aaa.eq(aaa));
|
||||
assertEquals(t, aaa.lt(baa));
|
||||
assertEquals(t, aaa.lteq(baa));
|
||||
assertEquals(f, aaa.gt(baa));
|
||||
assertEquals(f, aaa.gteq(baa));
|
||||
assertEquals(f, baa.lt(aaa));
|
||||
assertEquals(f, baa.lteq(aaa));
|
||||
assertEquals(t, baa.gt(aaa));
|
||||
assertEquals(t, baa.gteq(aaa));
|
||||
assertEquals(t, aaa.lteq(aaa));
|
||||
assertEquals(t, aaa.gteq(aaa));
|
||||
|
||||
// different case
|
||||
assertEquals(t, Aaa.eq(Aaa));
|
||||
assertEquals(t, Aaa.lt(aaa));
|
||||
assertEquals(t, Aaa.lteq(aaa));
|
||||
assertEquals(f, Aaa.gt(aaa));
|
||||
assertEquals(f, Aaa.gteq(aaa));
|
||||
assertEquals(f, aaa.lt(Aaa));
|
||||
assertEquals(f, aaa.lteq(Aaa));
|
||||
assertEquals(t, aaa.gt(Aaa));
|
||||
assertEquals(t, aaa.gteq(Aaa));
|
||||
assertEquals(t, Aaa.lteq(Aaa));
|
||||
assertEquals(t, Aaa.gteq(Aaa));
|
||||
|
||||
// second letter differs
|
||||
assertEquals(t, aaa.eq(aaa));
|
||||
assertEquals(t, aaa.lt(aba));
|
||||
assertEquals(t, aaa.lteq(aba));
|
||||
assertEquals(f, aaa.gt(aba));
|
||||
assertEquals(f, aaa.gteq(aba));
|
||||
assertEquals(f, aba.lt(aaa));
|
||||
assertEquals(f, aba.lteq(aaa));
|
||||
assertEquals(t, aba.gt(aaa));
|
||||
assertEquals(t, aba.gteq(aaa));
|
||||
assertEquals(t, aaa.lteq(aaa));
|
||||
assertEquals(t, aaa.gteq(aaa));
|
||||
|
||||
// longer
|
||||
assertEquals(t, aaa.eq(aaa));
|
||||
assertEquals(t, aaa.lt(aaaa));
|
||||
assertEquals(t, aaa.lteq(aaaa));
|
||||
assertEquals(f, aaa.gt(aaaa));
|
||||
assertEquals(f, aaa.gteq(aaaa));
|
||||
assertEquals(f, aaaa.lt(aaa));
|
||||
assertEquals(f, aaaa.lteq(aaa));
|
||||
assertEquals(t, aaaa.gt(aaa));
|
||||
assertEquals(t, aaaa.gteq(aaa));
|
||||
assertEquals(t, aaa.lteq(aaa));
|
||||
assertEquals(t, aaa.gteq(aaa));
|
||||
}
|
||||
}
|
||||
188
test/junit/org/luaj/vm2/WeakTableTest.java
Normal file
188
test/junit/org/luaj/vm2/WeakTableTest.java
Normal file
@@ -0,0 +1,188 @@
|
||||
/*******************************************************************************
|
||||
* 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;
|
||||
import java.util.Random;
|
||||
|
||||
public class WeakTableTest extends TableTest {
|
||||
|
||||
protected LuaTable new_Table() { return new WeakTable(false, true); }
|
||||
protected LuaTable new_Table(int n,int m) { return new WeakTable(false, true); }
|
||||
|
||||
public static class WeakKeyTableTest extends TableTest {
|
||||
protected LuaTable new_Table() { return new WeakTable(true, false); }
|
||||
protected LuaTable new_Table(int n,int m) { return new WeakTable(true, false); }
|
||||
}
|
||||
|
||||
public static class WeakKeyValueTableTest extends TableTest {
|
||||
protected LuaTable new_Table() { return new WeakTable(true, true); }
|
||||
protected LuaTable new_Table(int n,int m) { return new WeakTable(true, true); }
|
||||
}
|
||||
|
||||
|
||||
public void testWeakValuesTable() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
Object obj = new Object();
|
||||
LuaTable tableValue = new LuaTable();
|
||||
LuaString stringValue = LuaString.valueOf("this is a test");
|
||||
|
||||
t.set("table", tableValue);
|
||||
t.set("userdata", LuaValue.userdataOf(obj, null));
|
||||
t.set("string", stringValue);
|
||||
t.set("string2", LuaString.valueOf("another string"));
|
||||
assertTrue("table must have at least 4 elements", t.hashKeys.length > 4);
|
||||
|
||||
// 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());
|
||||
|
||||
// nothing should be collected, since we have strong references here
|
||||
System.gc();
|
||||
|
||||
// check that elements are still there
|
||||
assertEquals(tableValue, t.get("table"));
|
||||
assertEquals(stringValue, t.get("string"));
|
||||
assertEquals(obj, t.get("userdata").checkuserdata());
|
||||
|
||||
// drop our strong references
|
||||
obj = null;
|
||||
tableValue = null;
|
||||
stringValue = null;
|
||||
|
||||
// Garbage collection should cause weak entries to be dropped.
|
||||
System.gc();
|
||||
|
||||
// check that they are dropped
|
||||
assertEquals(LuaValue.NIL, t.get("table"));
|
||||
assertEquals(LuaValue.NIL, t.get("userdata"));
|
||||
assertFalse("strings should not be in weak references", t.get("string").isnil());
|
||||
}
|
||||
|
||||
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 toSting() {
|
||||
return "mydata-"+value;
|
||||
}
|
||||
}
|
||||
|
||||
public void testWeakKeysTable() {
|
||||
LuaTable t = new WeakTable(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
|
||||
System.gc();
|
||||
assertEquals( null, origkey.get() );
|
||||
assertEquals( LuaValue.NIL, t.get(key) );
|
||||
|
||||
// value should also be gone after gc after access!
|
||||
System.gc();
|
||||
assertEquals( null, origkey.get() );
|
||||
assertEquals( null, origval.get() );
|
||||
}
|
||||
|
||||
public void testWeakKeysValuesTable() {
|
||||
LuaTable t = new WeakTable(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
|
||||
System.gc();
|
||||
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;
|
||||
System.gc();
|
||||
assertEquals( null, origval2.get() );
|
||||
assertEquals( null, origkey3.get() );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user