Cleanup Tests with JUnit5 and move to different modules
This commit is contained in:
@@ -14,4 +14,12 @@
|
||||
<name>luaj-core</name>
|
||||
<description>Core code for LuaJ</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
115
luaj-core/src/test/java/org/luaj/vm2/BufferedStreamTest.java
Normal file
115
luaj-core/src/test/java/org/luaj/vm2/BufferedStreamTest.java
Normal file
@@ -0,0 +1,115 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2014 Luaj.org. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.luaj.vm2.Globals.BufferedStream;
|
||||
|
||||
class BufferedStreamTest {
|
||||
|
||||
private BufferedStream NewBufferedStream(int buflen, String contents) {
|
||||
return new BufferedStream(buflen, new ByteArrayInputStream(contents.getBytes()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadEmptyStream() throws java.io.IOException {
|
||||
BufferedStream bs = NewBufferedStream(4, "");
|
||||
assertEquals(-1, bs.read());
|
||||
assertEquals(-1, bs.read(new byte[10]));
|
||||
assertEquals(-1, bs.read(new byte[10], 0, 10));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadByte() throws java.io.IOException {
|
||||
BufferedStream bs = NewBufferedStream(2, "abc");
|
||||
assertEquals('a', bs.read());
|
||||
assertEquals('b', bs.read());
|
||||
assertEquals('c', bs.read());
|
||||
assertEquals(-1, bs.read());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadByteArray() throws java.io.IOException {
|
||||
byte[] array = new byte[3];
|
||||
BufferedStream bs = NewBufferedStream(4, "abcdef");
|
||||
assertEquals(3, bs.read(array));
|
||||
assertEquals("abc", new String(array));
|
||||
assertEquals(1, bs.read(array));
|
||||
assertEquals("d", new String(array, 0, 1));
|
||||
assertEquals(2, bs.read(array));
|
||||
assertEquals("ef", new String(array, 0, 2));
|
||||
assertEquals(-1, bs.read());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadByteArrayOffsetLength() throws java.io.IOException {
|
||||
byte[] array = new byte[10];
|
||||
BufferedStream bs = NewBufferedStream(8, "abcdefghijklmn");
|
||||
assertEquals(4, bs.read(array, 0, 4));
|
||||
assertEquals("abcd", new String(array, 0, 4));
|
||||
assertEquals(4, bs.read(array, 2, 8));
|
||||
assertEquals("efgh", new String(array, 2, 4));
|
||||
assertEquals(6, bs.read(array, 0, 10));
|
||||
assertEquals("ijklmn", new String(array, 0, 6));
|
||||
assertEquals(-1, bs.read());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMarkOffsetBeginningOfStream() throws java.io.IOException {
|
||||
byte[] array = new byte[4];
|
||||
BufferedStream bs = NewBufferedStream(8, "abcdefghijkl");
|
||||
assertEquals(true, bs.markSupported());
|
||||
bs.mark(4);
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("abcd", new String(array));
|
||||
bs.reset();
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("abcd", new String(array));
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("efgh", new String(array));
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("ijkl", new String(array));
|
||||
assertEquals(-1, bs.read());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMarkOffsetMiddleOfStream() throws java.io.IOException {
|
||||
byte[] array = new byte[4];
|
||||
BufferedStream bs = NewBufferedStream(8, "abcdefghijkl");
|
||||
assertEquals(true, bs.markSupported());
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("abcd", new String(array));
|
||||
bs.mark(4);
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("efgh", new String(array));
|
||||
bs.reset();
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("efgh", new String(array));
|
||||
assertEquals(4, bs.read(array));
|
||||
assertEquals("ijkl", new String(array));
|
||||
assertEquals(-1, bs.read());
|
||||
}
|
||||
}
|
||||
135
luaj-core/src/test/java/org/luaj/vm2/LuaOperationsTest.java
Normal file
135
luaj-core/src/test/java/org/luaj/vm2/LuaOperationsTest.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*******************************************************************************
|
||||
* 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 static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.luaj.vm2.TypeTest.MyData;
|
||||
import org.luaj.vm2.lib.ZeroArgFunction;
|
||||
|
||||
class LuaOperationsTest {
|
||||
|
||||
private final int sampleint = 77;
|
||||
private final long samplelong = 123400000000L;
|
||||
private final double sampledouble = 55.25;
|
||||
private final String samplestringstring = "abcdef";
|
||||
private final String samplestringint = String.valueOf(sampleint);
|
||||
private final String samplestringlong = String.valueOf(samplelong);
|
||||
private final String samplestringdouble = String.valueOf(sampledouble);
|
||||
private final Object sampleobject = new Object();
|
||||
private final MyData sampledata = new MyData();
|
||||
|
||||
private final LuaValue somenil = LuaValue.NIL;
|
||||
private final LuaValue sometrue = LuaValue.TRUE;
|
||||
private final LuaValue somefalse = LuaValue.FALSE;
|
||||
private final LuaValue zero = LuaValue.ZERO;
|
||||
private final LuaValue intint = LuaValue.valueOf(sampleint);
|
||||
private final LuaValue longdouble = LuaValue.valueOf(samplelong);
|
||||
private final LuaValue doubledouble = LuaValue.valueOf(sampledouble);
|
||||
private final LuaValue stringstring = LuaValue.valueOf(samplestringstring);
|
||||
private final LuaValue stringint = LuaValue.valueOf(samplestringint);
|
||||
private final LuaValue stringlong = LuaValue.valueOf(samplestringlong);
|
||||
private final LuaValue stringdouble = LuaValue.valueOf(samplestringdouble);
|
||||
private final LuaTable table = LuaValue
|
||||
.listOf(new LuaValue[] { LuaValue.valueOf("aaa"), LuaValue.valueOf("bbb") });
|
||||
private final LuaValue somefunc = new ZeroArgFunction() {
|
||||
@Override
|
||||
public LuaValue call() { return NONE; }
|
||||
};
|
||||
private final LuaThread thread = new LuaThread(new Globals(), somefunc);
|
||||
private final Prototype proto = new Prototype(1);
|
||||
private final LuaClosure someclosure = new LuaClosure(proto, table);
|
||||
private final LuaUserdata userdataobj = LuaValue.userdataOf(sampleobject);
|
||||
private final LuaUserdata userdatacls = LuaValue.userdataOf(sampledata);
|
||||
|
||||
private void throwsLuaError(String methodName, Object obj) {
|
||||
try {
|
||||
LuaValue.class.getMethod(methodName).invoke(obj);
|
||||
fail("failed to throw LuaError as required");
|
||||
} catch (InvocationTargetException e) {
|
||||
if (!(e.getTargetException() instanceof LuaError))
|
||||
fail("not a LuaError: " + e.getTargetException());
|
||||
return; // pass
|
||||
} catch (Exception e) {
|
||||
fail("bad exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
private void throwsLuaError(String methodName, Object obj, Object arg) {
|
||||
try {
|
||||
LuaValue.class.getMethod(methodName, LuaValue.class).invoke(obj, arg);
|
||||
fail("failed to throw LuaError as required");
|
||||
} catch (InvocationTargetException e) {
|
||||
if (!(e.getTargetException() instanceof LuaError))
|
||||
fail("not a LuaError: " + e.getTargetException());
|
||||
return; // pass
|
||||
} catch (Exception e) {
|
||||
fail("bad exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
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);
|
||||
}
|
||||
|
||||
@Test
|
||||
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);
|
||||
}
|
||||
}
|
||||
372
luaj-core/src/test/java/org/luaj/vm2/MetatableTest.java
Normal file
372
luaj-core/src/test/java/org/luaj/vm2/MetatableTest.java
Normal file
@@ -0,0 +1,372 @@
|
||||
/*******************************************************************************
|
||||
* 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 static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
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;
|
||||
|
||||
class MetatableTest {
|
||||
|
||||
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() {
|
||||
@Override
|
||||
public LuaValue call() { return NONE; }
|
||||
};
|
||||
private final LuaThread thread = new LuaThread(new Globals(), function);
|
||||
private final LuaClosure closure = new LuaClosure(new Prototype(), new LuaTable());
|
||||
private final LuaUserdata userdata = LuaValue.userdataOf(sampleobject);
|
||||
private final LuaUserdata userdatamt = LuaValue.userdataOf(sampledata, table);
|
||||
|
||||
@BeforeEach
|
||||
protected void setUp() throws Exception {
|
||||
// needed for metatable ops to work on strings
|
||||
new StringLib();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
protected void tearDown() throws Exception {
|
||||
LuaBoolean.s_metatable = null;
|
||||
LuaFunction.s_metatable = null;
|
||||
LuaNil.s_metatable = null;
|
||||
LuaNumber.s_metatable = null;
|
||||
// LuaString.s_metatable = null;
|
||||
LuaThread.s_metatable = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
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());
|
||||
}
|
||||
|
||||
@Test
|
||||
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());
|
||||
}
|
||||
|
||||
@Test
|
||||
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() {
|
||||
@Override
|
||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||
return LuaValue.valueOf(arg1.typename() + "[" + arg2.tojstring() + "]=xyz");
|
||||
}
|
||||
|
||||
});
|
||||
assertEquals("table[1]=xyz", table.get(1).tojstring());
|
||||
assertEquals("userdata[1]=xyz", userdata.get(1).tojstring());
|
||||
assertEquals("nil[1]=xyz", LuaValue.NIL.get(1).tojstring());
|
||||
assertEquals("boolean[1]=xyz", LuaValue.TRUE.get(1).tojstring());
|
||||
assertEquals("number[1]=xyz", LuaValue.ONE.get(1).tojstring());
|
||||
// assertEquals( "string[1]=xyz", string.get(1).tojstring() );
|
||||
assertEquals("function[1]=xyz", function.get(1).tojstring());
|
||||
assertEquals("thread[1]=xyz", thread.get(1).tojstring());
|
||||
}
|
||||
|
||||
@Test
|
||||
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() {
|
||||
@Override
|
||||
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), });
|
||||
}
|
||||
|
||||
@Test
|
||||
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);
|
||||
}
|
||||
}
|
||||
368
luaj-core/src/test/java/org/luaj/vm2/StringTest.java
Normal file
368
luaj-core/src/test/java/org/luaj/vm2/StringTest.java
Normal file
@@ -0,0 +1,368 @@
|
||||
package org.luaj.vm2;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class StringTest {
|
||||
|
||||
@Test
|
||||
void testToInputStream() throws IOException {
|
||||
LuaString str = LuaString.valueOf("Hello");
|
||||
|
||||
InputStream is = str.toInputStream();
|
||||
|
||||
assertEquals('H', is.read());
|
||||
assertEquals('e', is.read());
|
||||
assertEquals(2, is.skip(2));
|
||||
assertEquals('o', is.read());
|
||||
assertEquals(-1, is.read());
|
||||
|
||||
assertTrue(is.markSupported());
|
||||
|
||||
is.reset();
|
||||
|
||||
assertEquals('H', is.read());
|
||||
is.mark(4);
|
||||
|
||||
assertEquals('e', is.read());
|
||||
is.reset();
|
||||
assertEquals('e', is.read());
|
||||
|
||||
LuaString substr = str.substring(1, 4);
|
||||
assertEquals(3, substr.length());
|
||||
|
||||
is.close();
|
||||
is = substr.toInputStream();
|
||||
|
||||
assertEquals('e', is.read());
|
||||
assertEquals('l', is.read());
|
||||
assertEquals('l', is.read());
|
||||
assertEquals(-1, is.read());
|
||||
|
||||
is = substr.toInputStream();
|
||||
is.reset();
|
||||
|
||||
assertEquals('e', is.read());
|
||||
}
|
||||
|
||||
private static final String userFriendly(String s) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0, n = s.length(); i < n; i++) {
|
||||
int c = s.charAt(i);
|
||||
if (c < ' ' || c >= 0x80) {
|
||||
sb.append("\\u" + Integer.toHexString(0x10000+c).substring(1));
|
||||
} else {
|
||||
sb.append((char) c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUtf820482051() throws UnsupportedEncodingException {
|
||||
int i = 2048;
|
||||
char[] c = { (char) (i+0), (char) (i+1), (char) (i+2), (char) (i+3) };
|
||||
String before = new String(c) + " " + i + "-" + (i+4);
|
||||
LuaString ls = LuaString.valueOf(before);
|
||||
String after = ls.tojstring();
|
||||
assertEquals(userFriendly(before), userFriendly(after));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUtf8() {
|
||||
for (int i = 4; i < 0xffff; i += 4) {
|
||||
char[] c = { (char) (i+0), (char) (i+1), (char) (i+2), (char) (i+3) };
|
||||
String before = new String(c) + " " + i + "-" + (i+4);
|
||||
LuaString ls = LuaString.valueOf(before);
|
||||
String after = ls.tojstring();
|
||||
assertEquals(userFriendly(before), userFriendly(after));
|
||||
}
|
||||
char[] c = { (char) (1), (char) (2), (char) (3) };
|
||||
String before = new String(c) + " 1-3";
|
||||
LuaString ls = LuaString.valueOf(before);
|
||||
String after = ls.tojstring();
|
||||
assertEquals(userFriendly(before), userFriendly(after));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSpotCheckUtf8() throws UnsupportedEncodingException {
|
||||
byte[] bytes = { (byte) 194, (byte) 160, (byte) 194, (byte) 161, (byte) 194, (byte) 162, (byte) 194, (byte) 163,
|
||||
(byte) 194, (byte) 164 };
|
||||
String expected = new String(bytes, "UTF8");
|
||||
String actual = LuaString.valueOf(bytes).tojstring();
|
||||
char[] d = actual.toCharArray();
|
||||
assertEquals(160, d[0]);
|
||||
assertEquals(161, d[1]);
|
||||
assertEquals(162, d[2]);
|
||||
assertEquals(163, d[3]);
|
||||
assertEquals(164, d[4]);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNullTerminated() {
|
||||
char[] c = { 'a', 'b', 'c', '\0', 'd', 'e', 'f' };
|
||||
String before = new String(c);
|
||||
LuaString ls = LuaString.valueOf(before);
|
||||
String after = ls.tojstring();
|
||||
assertEquals(userFriendly("abc\0def"), userFriendly(after));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRecentStringsCacheDifferentHashcodes() {
|
||||
final byte[] abc = { 'a', 'b', 'c' };
|
||||
final byte[] xyz = { 'x', 'y', 'z' };
|
||||
final LuaString abc1 = LuaString.valueOf(abc);
|
||||
final LuaString xyz1 = LuaString.valueOf(xyz);
|
||||
final LuaString abc2 = LuaString.valueOf(abc);
|
||||
final LuaString xyz2 = LuaString.valueOf(xyz);
|
||||
final int mod = LuaString.RECENT_STRINGS_CACHE_SIZE;
|
||||
assertTrue(abc1.hashCode()%mod != xyz1.hashCode()%mod);
|
||||
assertSame(abc1, abc2);
|
||||
assertSame(xyz1, xyz2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRecentStringsCacheHashCollisionCacheHit() {
|
||||
final byte[] abc = { 'a', 'b', 'c' };
|
||||
final byte[] lyz = { 'l', 'y', 'z' }; // chosen to have hash collision with 'abc'
|
||||
final LuaString abc1 = LuaString.valueOf(abc);
|
||||
final LuaString abc2 = LuaString.valueOf(abc); // in cache: 'abc'
|
||||
final LuaString lyz1 = LuaString.valueOf(lyz);
|
||||
final LuaString lyz2 = LuaString.valueOf(lyz); // in cache: 'lyz'
|
||||
final int mod = LuaString.RECENT_STRINGS_CACHE_SIZE;
|
||||
assertEquals(abc1.hashCode()%mod, lyz1.hashCode()%mod);
|
||||
assertNotSame(abc1, lyz1);
|
||||
assertFalse(abc1.equals(lyz1));
|
||||
assertSame(abc1, abc2);
|
||||
assertSame(lyz1, lyz2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRecentStringsCacheHashCollisionCacheMiss() {
|
||||
final byte[] abc = { 'a', 'b', 'c' };
|
||||
final byte[] lyz = { 'l', 'y', 'z' }; // chosen to have hash collision with 'abc'
|
||||
final LuaString abc1 = LuaString.valueOf(abc);
|
||||
final LuaString lyz1 = LuaString.valueOf(lyz); // in cache: 'abc'
|
||||
final LuaString abc2 = LuaString.valueOf(abc); // in cache: 'lyz'
|
||||
final LuaString lyz2 = LuaString.valueOf(lyz); // in cache: 'abc'
|
||||
final int mod = LuaString.RECENT_STRINGS_CACHE_SIZE;
|
||||
assertEquals(abc1.hashCode()%mod, lyz1.hashCode()%mod);
|
||||
assertNotSame(abc1, lyz1);
|
||||
assertFalse(abc1.equals(lyz1));
|
||||
assertNotSame(abc1, abc2);
|
||||
assertNotSame(lyz1, lyz2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRecentStringsLongStrings() {
|
||||
byte[] abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes();
|
||||
assertTrue(abc.length > LuaString.RECENT_STRINGS_MAX_LENGTH);
|
||||
LuaString abc1 = LuaString.valueOf(abc);
|
||||
LuaString abc2 = LuaString.valueOf(abc);
|
||||
assertNotSame(abc1, abc2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRecentStringsUsingJavaStrings() {
|
||||
final String abc = "abc";
|
||||
final String lyz = "lyz"; // chosen to have hash collision with 'abc'
|
||||
final String xyz = "xyz";
|
||||
|
||||
final LuaString abc1 = LuaString.valueOf(abc);
|
||||
final LuaString abc2 = LuaString.valueOf(abc);
|
||||
final LuaString lyz1 = LuaString.valueOf(lyz);
|
||||
final LuaString lyz2 = LuaString.valueOf(lyz);
|
||||
final LuaString xyz1 = LuaString.valueOf(xyz);
|
||||
final LuaString xyz2 = LuaString.valueOf(xyz);
|
||||
final int mod = LuaString.RECENT_STRINGS_CACHE_SIZE;
|
||||
assertEquals(abc1.hashCode()%mod, lyz1.hashCode()%mod);
|
||||
assertFalse(abc1.hashCode()%mod == xyz1.hashCode()%mod);
|
||||
assertSame(abc1, abc2);
|
||||
assertSame(lyz1, lyz2);
|
||||
assertSame(xyz1, xyz2);
|
||||
|
||||
final LuaString abc3 = LuaString.valueOf(abc);
|
||||
final LuaString lyz3 = LuaString.valueOf(lyz);
|
||||
final LuaString xyz3 = LuaString.valueOf(xyz);
|
||||
|
||||
final LuaString abc4 = LuaString.valueOf(abc);
|
||||
final LuaString lyz4 = LuaString.valueOf(lyz);
|
||||
final LuaString xyz4 = LuaString.valueOf(xyz);
|
||||
assertNotSame(abc3, abc4); // because of hash collision
|
||||
assertNotSame(lyz3, lyz4); // because of hash collision
|
||||
assertSame(xyz3, xyz4); // because hashes do not collide
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLongSubstringGetsOldBacking() {
|
||||
LuaString src = LuaString.valueOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
LuaString sub1 = src.substring(10, 40);
|
||||
assertSame(src.m_bytes, sub1.m_bytes);
|
||||
assertEquals(sub1.m_offset, 10);
|
||||
assertEquals(sub1.m_length, 30);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testShortSubstringGetsNewBacking() {
|
||||
LuaString src = LuaString.valueOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
LuaString sub1 = src.substring(10, 20);
|
||||
LuaString sub2 = src.substring(10, 20);
|
||||
assertEquals(sub1.m_offset, 0);
|
||||
assertEquals(sub1.m_length, 10);
|
||||
assertSame(sub1, sub2);
|
||||
assertFalse(src.m_bytes == sub1.m_bytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testShortSubstringOfVeryLongStringGetsNewBacking() {
|
||||
LuaString src = LuaString.valueOf("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
LuaString sub1 = src.substring(10, 50);
|
||||
LuaString sub2 = src.substring(10, 50);
|
||||
assertEquals(sub1.m_offset, 0);
|
||||
assertEquals(sub1.m_length, 40);
|
||||
assertFalse(sub1 == sub2);
|
||||
assertFalse(src.m_bytes == sub1.m_bytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIndexOfByteInSubstring() {
|
||||
LuaString str = LuaString.valueOf("abcdef:ghi");
|
||||
LuaString sub = str.substring(2, 10);
|
||||
assertEquals(10, str.m_length);
|
||||
assertEquals(8, sub.m_length);
|
||||
assertEquals(0, str.m_offset);
|
||||
assertEquals(2, sub.m_offset);
|
||||
|
||||
assertEquals(6, str.indexOf((byte) ':', 0));
|
||||
assertEquals(6, str.indexOf((byte) ':', 2));
|
||||
assertEquals(6, str.indexOf((byte) ':', 6));
|
||||
assertEquals(-1, str.indexOf((byte) ':', 7));
|
||||
assertEquals(-1, str.indexOf((byte) ':', 9));
|
||||
assertEquals(9, str.indexOf((byte) 'i', 0));
|
||||
assertEquals(9, str.indexOf((byte) 'i', 2));
|
||||
assertEquals(9, str.indexOf((byte) 'i', 9));
|
||||
assertEquals(-1, str.indexOf((byte) 'z', 0));
|
||||
assertEquals(-1, str.indexOf((byte) 'z', 2));
|
||||
assertEquals(-1, str.indexOf((byte) 'z', 9));
|
||||
|
||||
assertEquals(4, sub.indexOf((byte) ':', 0));
|
||||
assertEquals(4, sub.indexOf((byte) ':', 2));
|
||||
assertEquals(4, sub.indexOf((byte) ':', 4));
|
||||
assertEquals(-1, sub.indexOf((byte) ':', 5));
|
||||
assertEquals(-1, sub.indexOf((byte) ':', 7));
|
||||
assertEquals(7, sub.indexOf((byte) 'i', 0));
|
||||
assertEquals(7, sub.indexOf((byte) 'i', 2));
|
||||
assertEquals(7, sub.indexOf((byte) 'i', 7));
|
||||
assertEquals(-1, sub.indexOf((byte) 'z', 0));
|
||||
assertEquals(-1, sub.indexOf((byte) 'z', 2));
|
||||
assertEquals(-1, sub.indexOf((byte) 'z', 7));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIndexOfPatternInSubstring() {
|
||||
LuaString str = LuaString.valueOf("abcdef:ghi");
|
||||
LuaString sub = str.substring(2, 10);
|
||||
assertEquals(10, str.m_length);
|
||||
assertEquals(8, sub.m_length);
|
||||
assertEquals(0, str.m_offset);
|
||||
assertEquals(2, sub.m_offset);
|
||||
|
||||
LuaString pat = LuaString.valueOf(":");
|
||||
LuaString i = LuaString.valueOf("i");
|
||||
LuaString xyz = LuaString.valueOf("xyz");
|
||||
|
||||
assertEquals(6, str.indexOf(pat, 0));
|
||||
assertEquals(6, str.indexOf(pat, 2));
|
||||
assertEquals(6, str.indexOf(pat, 6));
|
||||
assertEquals(-1, str.indexOf(pat, 7));
|
||||
assertEquals(-1, str.indexOf(pat, 9));
|
||||
assertEquals(9, str.indexOf(i, 0));
|
||||
assertEquals(9, str.indexOf(i, 2));
|
||||
assertEquals(9, str.indexOf(i, 9));
|
||||
assertEquals(-1, str.indexOf(xyz, 0));
|
||||
assertEquals(-1, str.indexOf(xyz, 2));
|
||||
assertEquals(-1, str.indexOf(xyz, 9));
|
||||
|
||||
assertEquals(4, sub.indexOf(pat, 0));
|
||||
assertEquals(4, sub.indexOf(pat, 2));
|
||||
assertEquals(4, sub.indexOf(pat, 4));
|
||||
assertEquals(-1, sub.indexOf(pat, 5));
|
||||
assertEquals(-1, sub.indexOf(pat, 7));
|
||||
assertEquals(7, sub.indexOf(i, 0));
|
||||
assertEquals(7, sub.indexOf(i, 2));
|
||||
assertEquals(7, sub.indexOf(i, 7));
|
||||
assertEquals(-1, sub.indexOf(xyz, 0));
|
||||
assertEquals(-1, sub.indexOf(xyz, 2));
|
||||
assertEquals(-1, sub.indexOf(xyz, 7));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLastIndexOfPatternInSubstring() {
|
||||
LuaString str = LuaString.valueOf("abcdef:ghi");
|
||||
LuaString sub = str.substring(2, 10);
|
||||
assertEquals(10, str.m_length);
|
||||
assertEquals(8, sub.m_length);
|
||||
assertEquals(0, str.m_offset);
|
||||
assertEquals(2, sub.m_offset);
|
||||
|
||||
LuaString pat = LuaString.valueOf(":");
|
||||
LuaString i = LuaString.valueOf("i");
|
||||
LuaString xyz = LuaString.valueOf("xyz");
|
||||
|
||||
assertEquals(6, str.lastIndexOf(pat));
|
||||
assertEquals(9, str.lastIndexOf(i));
|
||||
assertEquals(-1, str.lastIndexOf(xyz));
|
||||
|
||||
assertEquals(4, sub.lastIndexOf(pat));
|
||||
assertEquals(7, sub.lastIndexOf(i));
|
||||
assertEquals(-1, sub.lastIndexOf(xyz));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIndexOfAnyInSubstring() {
|
||||
LuaString str = LuaString.valueOf("abcdef:ghi");
|
||||
LuaString sub = str.substring(2, 10);
|
||||
assertEquals(10, str.m_length);
|
||||
assertEquals(8, sub.m_length);
|
||||
assertEquals(0, str.m_offset);
|
||||
assertEquals(2, sub.m_offset);
|
||||
|
||||
LuaString ghi = LuaString.valueOf("ghi");
|
||||
LuaString ihg = LuaString.valueOf("ihg");
|
||||
LuaString ijk = LuaString.valueOf("ijk");
|
||||
LuaString kji = LuaString.valueOf("kji");
|
||||
LuaString xyz = LuaString.valueOf("xyz");
|
||||
LuaString ABCdEFGHIJKL = LuaString.valueOf("ABCdEFGHIJKL");
|
||||
LuaString EFGHIJKL = ABCdEFGHIJKL.substring(4, 12);
|
||||
LuaString CdEFGHIJ = ABCdEFGHIJKL.substring(2, 10);
|
||||
assertEquals(4, EFGHIJKL.m_offset);
|
||||
assertEquals(2, CdEFGHIJ.m_offset);
|
||||
|
||||
assertEquals(7, str.indexOfAny(ghi));
|
||||
assertEquals(7, str.indexOfAny(ihg));
|
||||
assertEquals(9, str.indexOfAny(ijk));
|
||||
assertEquals(9, str.indexOfAny(kji));
|
||||
assertEquals(-1, str.indexOfAny(xyz));
|
||||
assertEquals(3, str.indexOfAny(CdEFGHIJ));
|
||||
assertEquals(-1, str.indexOfAny(EFGHIJKL));
|
||||
|
||||
assertEquals(5, sub.indexOfAny(ghi));
|
||||
assertEquals(5, sub.indexOfAny(ihg));
|
||||
assertEquals(7, sub.indexOfAny(ijk));
|
||||
assertEquals(7, sub.indexOfAny(kji));
|
||||
assertEquals(-1, sub.indexOfAny(xyz));
|
||||
assertEquals(1, sub.indexOfAny(CdEFGHIJ));
|
||||
assertEquals(-1, sub.indexOfAny(EFGHIJKL));
|
||||
}
|
||||
}
|
||||
325
luaj-core/src/test/java/org/luaj/vm2/TableHashTest.java
Normal file
325
luaj-core/src/test/java/org/luaj/vm2/TableHashTest.java
Normal file
@@ -0,0 +1,325 @@
|
||||
/*******************************************************************************
|
||||
* 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 static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.luaj.vm2.lib.TwoArgFunction;
|
||||
|
||||
/**
|
||||
* Tests for tables used as lists.
|
||||
*/
|
||||
public class TableHashTest {
|
||||
|
||||
protected LuaTable new_Table() {
|
||||
return new LuaTable();
|
||||
}
|
||||
|
||||
protected LuaTable new_Table(int n, int m) {
|
||||
return new LuaTable(n, m);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSetRemove() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
assertEquals(0, t.getHashLength());
|
||||
assertEquals(0, t.length());
|
||||
assertEquals(0, t.keyCount());
|
||||
|
||||
String[] keys = { "abc", "def", "ghi", "jkl", "mno", "pqr", "stu", "wxy", "z01", "cd", "ef", "g", "hi", "jk",
|
||||
"lm", "no", "pq", "rs", };
|
||||
int[] capacities = { 0, 2, 2, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 32, 32, 32 };
|
||||
for (int i = 0; i < keys.length; ++i) {
|
||||
assertEquals(capacities[i], t.getHashLength());
|
||||
String si = "Test Value! " + i;
|
||||
t.set(keys[i], si);
|
||||
assertEquals(0, t.length());
|
||||
assertEquals(i+1, t.keyCount());
|
||||
}
|
||||
assertEquals(capacities[keys.length], t.getHashLength());
|
||||
for (int i = 0; i < keys.length; ++i) {
|
||||
LuaValue vi = LuaString.valueOf("Test Value! " + i);
|
||||
assertEquals(vi, t.get(keys[i]));
|
||||
assertEquals(vi, t.get(LuaString.valueOf(keys[i])));
|
||||
assertEquals(vi, t.rawget(keys[i]));
|
||||
assertEquals(vi, t.rawget(keys[i]));
|
||||
}
|
||||
|
||||
// replace with new values
|
||||
for (int i = 0; i < keys.length; ++i) {
|
||||
t.set(keys[i], LuaString.valueOf("Replacement Value! " + i));
|
||||
assertEquals(0, t.length());
|
||||
assertEquals(keys.length, t.keyCount());
|
||||
assertEquals(capacities[keys.length], t.getHashLength());
|
||||
}
|
||||
for (int i = 0; i < keys.length; ++i) {
|
||||
LuaValue vi = LuaString.valueOf("Replacement Value! " + i);
|
||||
assertEquals(vi, t.get(keys[i]));
|
||||
}
|
||||
|
||||
// remove
|
||||
for (int i = 0; i < keys.length; ++i) {
|
||||
t.set(keys[i], LuaValue.NIL);
|
||||
assertEquals(0, t.length());
|
||||
assertEquals(keys.length-i-1, t.keyCount());
|
||||
if (i < keys.length-1)
|
||||
assertEquals(capacities[keys.length], t.getHashLength());
|
||||
else
|
||||
assertTrue(0 <= t.getHashLength());
|
||||
}
|
||||
for (int i = 0; i < keys.length; ++i) {
|
||||
assertEquals(LuaValue.NIL, t.get(keys[i]));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIndexMetatag() {
|
||||
LuaTable t = new_Table();
|
||||
LuaTable mt = new_Table();
|
||||
LuaTable fb = new_Table();
|
||||
|
||||
// set basic values
|
||||
t.set("ppp", "abc");
|
||||
t.set(123, "def");
|
||||
mt.set(LuaValue.INDEX, fb);
|
||||
fb.set("qqq", "ghi");
|
||||
fb.set(456, "jkl");
|
||||
|
||||
// check before setting metatable
|
||||
assertEquals("abc", t.get("ppp").tojstring());
|
||||
assertEquals("def", t.get(123).tojstring());
|
||||
assertEquals("nil", t.get("qqq").tojstring());
|
||||
assertEquals("nil", t.get(456).tojstring());
|
||||
assertEquals("nil", fb.get("ppp").tojstring());
|
||||
assertEquals("nil", fb.get(123).tojstring());
|
||||
assertEquals("ghi", fb.get("qqq").tojstring());
|
||||
assertEquals("jkl", fb.get(456).tojstring());
|
||||
assertEquals("nil", mt.get("ppp").tojstring());
|
||||
assertEquals("nil", mt.get(123).tojstring());
|
||||
assertEquals("nil", mt.get("qqq").tojstring());
|
||||
assertEquals("nil", mt.get(456).tojstring());
|
||||
|
||||
// check before setting metatable
|
||||
t.setmetatable(mt);
|
||||
assertEquals(mt, t.getmetatable());
|
||||
assertEquals("abc", t.get("ppp").tojstring());
|
||||
assertEquals("def", t.get(123).tojstring());
|
||||
assertEquals("ghi", t.get("qqq").tojstring());
|
||||
assertEquals("jkl", t.get(456).tojstring());
|
||||
assertEquals("nil", fb.get("ppp").tojstring());
|
||||
assertEquals("nil", fb.get(123).tojstring());
|
||||
assertEquals("ghi", fb.get("qqq").tojstring());
|
||||
assertEquals("jkl", fb.get(456).tojstring());
|
||||
assertEquals("nil", mt.get("ppp").tojstring());
|
||||
assertEquals("nil", mt.get(123).tojstring());
|
||||
assertEquals("nil", mt.get("qqq").tojstring());
|
||||
assertEquals("nil", mt.get(456).tojstring());
|
||||
|
||||
// set metatable to metatable without values
|
||||
t.setmetatable(fb);
|
||||
assertEquals("abc", t.get("ppp").tojstring());
|
||||
assertEquals("def", t.get(123).tojstring());
|
||||
assertEquals("nil", t.get("qqq").tojstring());
|
||||
assertEquals("nil", t.get(456).tojstring());
|
||||
|
||||
// set metatable to null
|
||||
t.setmetatable(null);
|
||||
assertEquals("abc", t.get("ppp").tojstring());
|
||||
assertEquals("def", t.get(123).tojstring());
|
||||
assertEquals("nil", t.get("qqq").tojstring());
|
||||
assertEquals("nil", t.get(456).tojstring());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testIndexFunction() {
|
||||
final LuaTable t = new_Table();
|
||||
final LuaTable mt = new_Table();
|
||||
|
||||
final TwoArgFunction fb = new TwoArgFunction() {
|
||||
@Override
|
||||
public LuaValue call(LuaValue tbl, LuaValue key) {
|
||||
assertEquals(tbl, t);
|
||||
return valueOf("from mt: " + key);
|
||||
}
|
||||
};
|
||||
|
||||
// set basic values
|
||||
t.set("ppp", "abc");
|
||||
t.set(123, "def");
|
||||
mt.set(LuaValue.INDEX, fb);
|
||||
|
||||
// check before setting metatable
|
||||
assertEquals("abc", t.get("ppp").tojstring());
|
||||
assertEquals("def", t.get(123).tojstring());
|
||||
assertEquals("nil", t.get("qqq").tojstring());
|
||||
assertEquals("nil", t.get(456).tojstring());
|
||||
|
||||
// check before setting metatable
|
||||
t.setmetatable(mt);
|
||||
assertEquals(mt, t.getmetatable());
|
||||
assertEquals("abc", t.get("ppp").tojstring());
|
||||
assertEquals("def", t.get(123).tojstring());
|
||||
assertEquals("from mt: qqq", t.get("qqq").tojstring());
|
||||
assertEquals("from mt: 456", t.get(456).tojstring());
|
||||
|
||||
// use raw set
|
||||
t.rawset("qqq", "alt-qqq");
|
||||
t.rawset(456, "alt-456");
|
||||
assertEquals("abc", t.get("ppp").tojstring());
|
||||
assertEquals("def", t.get(123).tojstring());
|
||||
assertEquals("alt-qqq", t.get("qqq").tojstring());
|
||||
assertEquals("alt-456", t.get(456).tojstring());
|
||||
|
||||
// remove using raw set
|
||||
t.rawset("qqq", LuaValue.NIL);
|
||||
t.rawset(456, LuaValue.NIL);
|
||||
assertEquals("abc", t.get("ppp").tojstring());
|
||||
assertEquals("def", t.get(123).tojstring());
|
||||
assertEquals("from mt: qqq", t.get("qqq").tojstring());
|
||||
assertEquals("from mt: 456", t.get(456).tojstring());
|
||||
|
||||
// set metatable to null
|
||||
t.setmetatable(null);
|
||||
assertEquals("abc", t.get("ppp").tojstring());
|
||||
assertEquals("def", t.get(123).tojstring());
|
||||
assertEquals("nil", t.get("qqq").tojstring());
|
||||
assertEquals("nil", t.get(456).tojstring());
|
||||
}
|
||||
|
||||
@Test
|
||||
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")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoopWithRemoval() {
|
||||
final LuaTable t = new_Table();
|
||||
|
||||
t.set(LuaValue.valueOf(1), LuaValue.valueOf("1"));
|
||||
t.set(LuaValue.valueOf(3), LuaValue.valueOf("3"));
|
||||
t.set(LuaValue.valueOf(8), LuaValue.valueOf("4"));
|
||||
t.set(LuaValue.valueOf(17), LuaValue.valueOf("5"));
|
||||
t.set(LuaValue.valueOf(26), LuaValue.valueOf("6"));
|
||||
t.set(LuaValue.valueOf(35), LuaValue.valueOf("7"));
|
||||
t.set(LuaValue.valueOf(42), LuaValue.valueOf("8"));
|
||||
t.set(LuaValue.valueOf(60), LuaValue.valueOf("10"));
|
||||
t.set(LuaValue.valueOf(63), LuaValue.valueOf("11"));
|
||||
|
||||
Varargs entry = t.next(LuaValue.NIL);
|
||||
while ( !entry.isnil(1) ) {
|
||||
LuaValue k = entry.arg1();
|
||||
LuaValue v = entry.arg(2);
|
||||
if ((k.toint() & 1) == 0) {
|
||||
t.set(k, LuaValue.NIL);
|
||||
}
|
||||
entry = t.next(k);
|
||||
}
|
||||
|
||||
int numEntries = 0;
|
||||
entry = t.next(LuaValue.NIL);
|
||||
while ( !entry.isnil(1) ) {
|
||||
LuaValue k = entry.arg1();
|
||||
// Only odd keys should remain
|
||||
assertTrue((k.toint() & 1) == 1);
|
||||
numEntries++;
|
||||
entry = t.next(k);
|
||||
}
|
||||
assertEquals(5, numEntries);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLoopWithRemovalAndSet() {
|
||||
final LuaTable t = new_Table();
|
||||
|
||||
t.set(LuaValue.valueOf(1), LuaValue.valueOf("1"));
|
||||
t.set(LuaValue.valueOf(3), LuaValue.valueOf("3"));
|
||||
t.set(LuaValue.valueOf(8), LuaValue.valueOf("4"));
|
||||
t.set(LuaValue.valueOf(17), LuaValue.valueOf("5"));
|
||||
t.set(LuaValue.valueOf(26), LuaValue.valueOf("6"));
|
||||
t.set(LuaValue.valueOf(35), LuaValue.valueOf("7"));
|
||||
t.set(LuaValue.valueOf(42), LuaValue.valueOf("8"));
|
||||
t.set(LuaValue.valueOf(60), LuaValue.valueOf("10"));
|
||||
t.set(LuaValue.valueOf(63), LuaValue.valueOf("11"));
|
||||
|
||||
Varargs entry = t.next(LuaValue.NIL);
|
||||
Varargs entry2 = entry;
|
||||
while ( !entry.isnil(1) ) {
|
||||
LuaValue k = entry.arg1();
|
||||
LuaValue v = entry.arg(2);
|
||||
if ((k.toint() & 1) == 0) {
|
||||
t.set(k, LuaValue.NIL);
|
||||
} else {
|
||||
t.set(k, v.tonumber());
|
||||
entry2 = t.next(entry2.arg1());
|
||||
}
|
||||
entry = t.next(k);
|
||||
}
|
||||
|
||||
int numEntries = 0;
|
||||
entry = t.next(LuaValue.NIL);
|
||||
while ( !entry.isnil(1) ) {
|
||||
LuaValue k = entry.arg1();
|
||||
// Only odd keys should remain
|
||||
assertTrue((k.toint() & 1) == 1);
|
||||
assertTrue(entry.arg(2).type() == LuaValue.TNUMBER);
|
||||
numEntries++;
|
||||
entry = t.next(k);
|
||||
}
|
||||
assertEquals(5, numEntries);
|
||||
}
|
||||
}
|
||||
437
luaj-core/src/test/java/org/luaj/vm2/TableTest.java
Normal file
437
luaj-core/src/test/java/org/luaj/vm2/TableTest.java
Normal file
@@ -0,0 +1,437 @@
|
||||
/*******************************************************************************
|
||||
* 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 static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotSame;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class TableTest {
|
||||
|
||||
protected LuaTable new_Table() {
|
||||
return new LuaTable();
|
||||
}
|
||||
|
||||
protected LuaTable new_Table(int n, int m) {
|
||||
return new LuaTable(n, m);
|
||||
}
|
||||
|
||||
private int keyCount(LuaTable t) {
|
||||
return keys(t).length;
|
||||
}
|
||||
|
||||
private LuaValue[] keys(LuaTable t) {
|
||||
ArrayList<LuaValue> l = new ArrayList<LuaValue>();
|
||||
LuaValue k = LuaValue.NIL;
|
||||
while ( true ) {
|
||||
Varargs n = t.next(k);
|
||||
if ((k = n.arg1()).isnil())
|
||||
break;
|
||||
l.add(k);
|
||||
}
|
||||
return l.toArray(new LuaValue[t.length()]);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInOrderIntegerKeyInsertion() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for (int i = 1; i <= 32; ++i) {
|
||||
t.set(i, LuaValue.valueOf("Test Value! " + i));
|
||||
}
|
||||
|
||||
// Ensure all keys are still there.
|
||||
for (int i = 1; i <= 32; ++i) {
|
||||
assertEquals("Test Value! " + i, t.get(i).tojstring());
|
||||
}
|
||||
|
||||
// Ensure capacities make sense
|
||||
assertEquals(0, t.getHashLength());
|
||||
|
||||
assertTrue(t.getArrayLength() >= 32);
|
||||
assertTrue(t.getArrayLength() <= 64);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRekeyCount() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
// NOTE: This order of insertion is important.
|
||||
t.set(3, LuaInteger.valueOf(3));
|
||||
t.set(1, LuaInteger.valueOf(1));
|
||||
t.set(5, LuaInteger.valueOf(5));
|
||||
t.set(4, LuaInteger.valueOf(4));
|
||||
t.set(6, LuaInteger.valueOf(6));
|
||||
t.set(2, LuaInteger.valueOf(2));
|
||||
|
||||
for (int i = 1; i < 6; ++i) {
|
||||
assertEquals(LuaInteger.valueOf(i), t.get(i));
|
||||
}
|
||||
|
||||
assertTrue(t.getArrayLength() >= 3);
|
||||
assertTrue(t.getArrayLength() <= 12);
|
||||
assertTrue(t.getHashLength() <= 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOutOfOrderIntegerKeyInsertion() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for (int i = 32; i > 0; --i) {
|
||||
t.set(i, LuaValue.valueOf("Test Value! " + i));
|
||||
}
|
||||
|
||||
// Ensure all keys are still there.
|
||||
for (int i = 1; i <= 32; ++i) {
|
||||
assertEquals("Test Value! " + i, t.get(i).tojstring());
|
||||
}
|
||||
|
||||
// Ensure capacities make sense
|
||||
assertEquals(32, t.getArrayLength());
|
||||
assertEquals(0, t.getHashLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStringAndIntegerKeys() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
LuaString str = LuaValue.valueOf(String.valueOf(i));
|
||||
t.set(i, str);
|
||||
t.set(str, LuaInteger.valueOf(i));
|
||||
}
|
||||
|
||||
assertTrue(t.getArrayLength() >= 8); // 1, 2, ..., 9
|
||||
assertTrue(t.getArrayLength() <= 16);
|
||||
assertTrue(t.getHashLength() >= 11); // 0, "0", "1", ..., "9"
|
||||
assertTrue(t.getHashLength() <= 33);
|
||||
|
||||
LuaValue[] keys = keys(t);
|
||||
|
||||
int intKeys = 0;
|
||||
int stringKeys = 0;
|
||||
|
||||
assertEquals(20, keys.length);
|
||||
for (int i = 0; i < keys.length; ++i) {
|
||||
LuaValue k = keys[i];
|
||||
|
||||
if (k instanceof LuaInteger) {
|
||||
final int ik = k.toint();
|
||||
assertTrue(ik >= 0 && ik < 10);
|
||||
final int mask = 1<<ik;
|
||||
assertTrue((intKeys & mask) == 0);
|
||||
intKeys |= mask;
|
||||
} else if (k instanceof LuaString) {
|
||||
final int ik = Integer.parseInt(k.strvalue().tojstring());
|
||||
assertEquals(String.valueOf(ik), k.strvalue().tojstring());
|
||||
assertTrue(ik >= 0 && ik < 10);
|
||||
final int mask = 1<<ik;
|
||||
assertTrue((stringKeys & mask) == 0, "Key \"" + ik + "\" found more than once");
|
||||
stringKeys |= mask;
|
||||
} else {
|
||||
fail("Unexpected type of key found");
|
||||
}
|
||||
}
|
||||
|
||||
assertEquals(0x03FF, intKeys);
|
||||
assertEquals(0x03FF, stringKeys);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBadInitialCapacity() {
|
||||
LuaTable t = new_Table(0, 1);
|
||||
|
||||
t.set("test", LuaValue.valueOf("foo"));
|
||||
t.set("explode", LuaValue.valueOf("explode"));
|
||||
assertEquals(2, keyCount(t));
|
||||
}
|
||||
|
||||
@Test
|
||||
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));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemove1() {
|
||||
LuaTable t = new_Table(0, 1);
|
||||
|
||||
t.set("test", LuaValue.valueOf("foo"));
|
||||
t.set("explode", LuaValue.NIL);
|
||||
t.set(42, LuaValue.NIL);
|
||||
t.set(new_Table(), LuaValue.NIL);
|
||||
t.set("test", LuaValue.NIL);
|
||||
assertEquals(0, keyCount(t));
|
||||
|
||||
t.set(10, LuaInteger.valueOf(5));
|
||||
t.set(10, LuaValue.NIL);
|
||||
assertEquals(0, keyCount(t));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemove2() {
|
||||
LuaTable t = new_Table(0, 1);
|
||||
|
||||
t.set("test", LuaValue.valueOf("foo"));
|
||||
t.set("string", LuaInteger.valueOf(10));
|
||||
assertEquals(2, keyCount(t));
|
||||
|
||||
t.set("string", LuaValue.NIL);
|
||||
t.set("three", LuaValue.valueOf(3.14));
|
||||
assertEquals(2, keyCount(t));
|
||||
|
||||
t.set("test", LuaValue.NIL);
|
||||
assertEquals(1, keyCount(t));
|
||||
|
||||
t.set(10, LuaInteger.valueOf(5));
|
||||
assertEquals(2, keyCount(t));
|
||||
|
||||
t.set(10, LuaValue.NIL);
|
||||
assertEquals(1, keyCount(t));
|
||||
|
||||
t.set("three", LuaValue.NIL);
|
||||
assertEquals(0, keyCount(t));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testShrinkNonPowerOfTwoArray() {
|
||||
LuaTable t = new_Table(6, 2);
|
||||
|
||||
t.set(1, "one");
|
||||
t.set(2, "two");
|
||||
t.set(3, "three");
|
||||
t.set(4, "four");
|
||||
t.set(5, "five");
|
||||
t.set(6, "six");
|
||||
|
||||
t.set("aa", "aaa");
|
||||
t.set("bb", "bbb");
|
||||
|
||||
t.set(3, LuaValue.NIL);
|
||||
t.set(4, LuaValue.NIL);
|
||||
t.set(6, LuaValue.NIL);
|
||||
|
||||
t.set("cc", "ccc");
|
||||
t.set("dd", "ddd");
|
||||
|
||||
assertEquals(4, t.getArrayLength());
|
||||
assertTrue(t.getHashLength() < 10);
|
||||
assertEquals(5, t.hashEntries);
|
||||
assertEquals("one", t.get(1).tojstring());
|
||||
assertEquals("two", t.get(2).tojstring());
|
||||
assertEquals(LuaValue.NIL, t.get(3));
|
||||
assertEquals(LuaValue.NIL, t.get(4));
|
||||
assertEquals("five", t.get(5).tojstring());
|
||||
assertEquals(LuaValue.NIL, t.get(6));
|
||||
assertEquals("aaa", t.get("aa").tojstring());
|
||||
assertEquals("bbb", t.get("bb").tojstring());
|
||||
assertEquals("ccc", t.get("cc").tojstring());
|
||||
assertEquals("ddd", t.get("dd").tojstring());
|
||||
}
|
||||
|
||||
@Test
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testMixedKeysLuaLength() {
|
||||
LuaTable t = new_Table();
|
||||
|
||||
for (int i = 1; i <= 32; ++i) {
|
||||
t.set("str-" + i, LuaValue.valueOf("String Key Test Value! " + i));
|
||||
t.set(i, LuaValue.valueOf("Int Key Test Value! " + i));
|
||||
assertEquals(i, t.length());
|
||||
}
|
||||
}
|
||||
|
||||
private static final void compareLists(LuaTable t, Vector<LuaString> v) {
|
||||
int n = v.size();
|
||||
assertEquals(v.size(), t.length());
|
||||
for (int j = 0; j < n; j++) {
|
||||
LuaString vj = v.elementAt(j);
|
||||
String tj = t.get(j+1).tojstring();
|
||||
assertEquals(vj.tojstring(), tj);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInsertBeginningOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector<LuaString> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInsertEndOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector<LuaString> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInsertMiddleOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector<LuaString> 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<LuaString> v) {
|
||||
for (int i = 1; i <= 32; ++i) {
|
||||
LuaString test = LuaValue.valueOf("Test Value! " + i);
|
||||
t.insert(0, test);
|
||||
v.insertElementAt(test, v.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemoveBeginningOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector<LuaString> v = new Vector<>();
|
||||
prefillLists(t, v);
|
||||
for (int i = 1; i <= 32; ++i) {
|
||||
t.remove(1);
|
||||
v.removeElementAt(0);
|
||||
compareLists(t, v);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemoveEndOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector<LuaString> v = new Vector<>();
|
||||
prefillLists(t, v);
|
||||
for (int i = 1; i <= 32; ++i) {
|
||||
t.remove(0);
|
||||
v.removeElementAt(v.size()-1);
|
||||
compareLists(t, v);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemoveMiddleOfList() {
|
||||
LuaTable t = new_Table();
|
||||
Vector<LuaString> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemoveWhileIterating() {
|
||||
LuaTable t = LuaValue.tableOf(
|
||||
new LuaValue[] { LuaValue.valueOf("a"), LuaValue.valueOf("aa"), LuaValue.valueOf("b"),
|
||||
LuaValue.valueOf("bb"), LuaValue.valueOf("c"), LuaValue.valueOf("cc"), LuaValue.valueOf("d"),
|
||||
LuaValue.valueOf("dd"), LuaValue.valueOf("e"), LuaValue.valueOf("ee"), },
|
||||
new LuaValue[] { LuaValue.valueOf("11"), LuaValue.valueOf("22"), LuaValue.valueOf("33"),
|
||||
LuaValue.valueOf("44"), LuaValue.valueOf("55"), });
|
||||
// Find expected order after removal.
|
||||
List<String> expected = new ArrayList<>();
|
||||
Varargs n;
|
||||
int i;
|
||||
for (n = t.next(LuaValue.NIL), i = 0; !n.arg1().isnil(); n = t.next(n.arg1()), ++i) {
|
||||
if (i%2 == 0)
|
||||
expected.add(n.arg1() + "=" + n.arg(2));
|
||||
}
|
||||
// Remove every other key while iterating over the table.
|
||||
for (n = t.next(LuaValue.NIL), i = 0; !n.arg1().isnil(); n = t.next(n.arg1()), ++i) {
|
||||
if (i%2 != 0)
|
||||
t.set(n.arg1(), LuaValue.NIL);
|
||||
}
|
||||
// Iterate over remaining table, and form list of entries still in table.
|
||||
List<String> actual = new ArrayList<>();
|
||||
for (n = t.next(LuaValue.NIL); !n.arg1().isnil(); n = t.next(n.arg1())) {
|
||||
actual.add(n.arg1() + "=" + n.arg(2));
|
||||
}
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
}
|
||||
1293
luaj-core/src/test/java/org/luaj/vm2/TypeTest.java
Normal file
1293
luaj-core/src/test/java/org/luaj/vm2/TypeTest.java
Normal file
File diff suppressed because it is too large
Load Diff
1468
luaj-core/src/test/java/org/luaj/vm2/UnaryBinaryOperatorsTest.java
Normal file
1468
luaj-core/src/test/java/org/luaj/vm2/UnaryBinaryOperatorsTest.java
Normal file
File diff suppressed because it is too large
Load Diff
235
luaj-core/src/test/java/org/luaj/vm2/VarargsTest.java
Normal file
235
luaj-core/src/test/java/org/luaj/vm2/VarargsTest.java
Normal file
@@ -0,0 +1,235 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2012 Luaj.org. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
package org.luaj.vm2;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Tests of basic unary and binary operators on main value types.
|
||||
*/
|
||||
class VarargsTest {
|
||||
|
||||
static LuaValue A = LuaValue.valueOf("a");
|
||||
static LuaValue B = LuaValue.valueOf("b");
|
||||
static LuaValue C = LuaValue.valueOf("c");
|
||||
static LuaValue D = LuaValue.valueOf("d");
|
||||
static LuaValue E = LuaValue.valueOf("e");
|
||||
static LuaValue F = LuaValue.valueOf("f");
|
||||
static LuaValue G = LuaValue.valueOf("g");
|
||||
static LuaValue H = LuaValue.valueOf("h");
|
||||
static LuaValue Z = LuaValue.valueOf("z");
|
||||
static LuaValue NIL = LuaValue.NIL;
|
||||
static Varargs A_G = LuaValue.varargsOf(new LuaValue[] { A, B, C, D, E, F, G });
|
||||
static Varargs B_E = LuaValue.varargsOf(new LuaValue[] { B, C, D, E });
|
||||
static Varargs C_G = LuaValue.varargsOf(new LuaValue[] { C, D, E, F, G });
|
||||
static Varargs C_E = LuaValue.varargsOf(new LuaValue[] { C, D, E });
|
||||
static Varargs DE = LuaValue.varargsOf(new LuaValue[] { D, E });
|
||||
static Varargs E_G = LuaValue.varargsOf(new LuaValue[] { E, F, G });
|
||||
static Varargs FG = LuaValue.varargsOf(new LuaValue[] { F, G });
|
||||
static LuaValue[] Z_H_array = { Z, A, B, C, D, E, F, G, H };
|
||||
static Varargs A_G_alt = new Varargs.ArrayPartVarargs(Z_H_array, 1, 7);
|
||||
static Varargs B_E_alt = new Varargs.ArrayPartVarargs(Z_H_array, 2, 4);
|
||||
static Varargs C_G_alt = new Varargs.ArrayPartVarargs(Z_H_array, 3, 5);
|
||||
static Varargs C_E_alt = new Varargs.ArrayPartVarargs(Z_H_array, 3, 3);
|
||||
static Varargs C_E_alt2 = LuaValue.varargsOf(C, D, E);
|
||||
static Varargs DE_alt = new Varargs.PairVarargs(D, E);
|
||||
static Varargs DE_alt2 = LuaValue.varargsOf(D, E);
|
||||
static Varargs E_G_alt = new Varargs.ArrayPartVarargs(Z_H_array, 5, 3);
|
||||
static Varargs FG_alt = new Varargs.PairVarargs(F, G);
|
||||
static Varargs NONE = LuaValue.NONE;
|
||||
|
||||
private void expectEquals(Varargs x, Varargs y) {
|
||||
assertEquals(x.narg(), y.narg());
|
||||
assertEquals(x.arg1(), y.arg1());
|
||||
assertEquals(x.arg(0), y.arg(0));
|
||||
assertEquals(x.arg(-1), y.arg(-1));
|
||||
assertEquals(x.arg(2), y.arg(2));
|
||||
assertEquals(x.arg(3), y.arg(3));
|
||||
for (int i = 4; i < x.narg()+2; ++i)
|
||||
assertEquals(x.arg(i), y.arg(i));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSanity() {
|
||||
expectEquals(A_G, A_G);
|
||||
expectEquals(A_G_alt, A_G_alt);
|
||||
expectEquals(A_G, A_G_alt);
|
||||
expectEquals(B_E, B_E_alt);
|
||||
expectEquals(C_G, C_G_alt);
|
||||
expectEquals(C_E, C_E_alt);
|
||||
expectEquals(C_E, C_E_alt2);
|
||||
expectEquals(DE, DE_alt);
|
||||
expectEquals(DE, DE_alt2);
|
||||
expectEquals(E_G, E_G_alt);
|
||||
expectEquals(FG, FG_alt);
|
||||
expectEquals(FG_alt, FG_alt);
|
||||
expectEquals(A, A);
|
||||
expectEquals(NONE, NONE);
|
||||
expectEquals(NIL, NIL);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNegativeIndices() {
|
||||
expectNegSubargsError(A_G);
|
||||
expectNegSubargsError(A_G_alt);
|
||||
expectNegSubargsError(B_E);
|
||||
expectNegSubargsError(B_E_alt);
|
||||
expectNegSubargsError(C_G);
|
||||
expectNegSubargsError(C_G_alt);
|
||||
expectNegSubargsError(C_E);
|
||||
expectNegSubargsError(C_E_alt);
|
||||
expectNegSubargsError(C_E_alt2);
|
||||
expectNegSubargsError(DE);
|
||||
expectNegSubargsError(DE_alt);
|
||||
expectNegSubargsError(DE_alt2);
|
||||
expectNegSubargsError(E_G);
|
||||
expectNegSubargsError(FG);
|
||||
expectNegSubargsError(A);
|
||||
expectNegSubargsError(NONE);
|
||||
expectNegSubargsError(NIL);
|
||||
}
|
||||
|
||||
private void standardTestsA_G(Varargs a_g) {
|
||||
expectEquals(A_G, a_g);
|
||||
expectEquals(A_G, a_g.subargs(1));
|
||||
expectEquals(C_G, a_g.subargs(3).subargs(1));
|
||||
expectEquals(E_G, a_g.subargs(5));
|
||||
expectEquals(E_G, a_g.subargs(5).subargs(1));
|
||||
expectEquals(FG, a_g.subargs(6));
|
||||
expectEquals(FG, a_g.subargs(6).subargs(1));
|
||||
expectEquals(G, a_g.subargs(7));
|
||||
expectEquals(G, a_g.subargs(7).subargs(1));
|
||||
expectEquals(NONE, a_g.subargs(8));
|
||||
expectEquals(NONE, a_g.subargs(8).subargs(1));
|
||||
standardTestsC_G(A_G.subargs(3));
|
||||
}
|
||||
|
||||
private void standardTestsC_G(Varargs c_g) {
|
||||
expectEquals(C_G, c_g.subargs(1));
|
||||
expectEquals(E_G, c_g.subargs(3));
|
||||
expectEquals(E_G, c_g.subargs(3).subargs(1));
|
||||
expectEquals(FG, c_g.subargs(4));
|
||||
expectEquals(FG, c_g.subargs(4).subargs(1));
|
||||
expectEquals(G, c_g.subargs(5));
|
||||
expectEquals(G, c_g.subargs(5).subargs(1));
|
||||
expectEquals(NONE, c_g.subargs(6));
|
||||
expectEquals(NONE, c_g.subargs(6).subargs(1));
|
||||
standardTestsE_G(c_g.subargs(3));
|
||||
}
|
||||
|
||||
private void standardTestsE_G(Varargs e_g) {
|
||||
expectEquals(E_G, e_g.subargs(1));
|
||||
expectEquals(FG, e_g.subargs(2));
|
||||
expectEquals(FG, e_g.subargs(2).subargs(1));
|
||||
expectEquals(G, e_g.subargs(3));
|
||||
expectEquals(G, e_g.subargs(3).subargs(1));
|
||||
expectEquals(NONE, e_g.subargs(4));
|
||||
expectEquals(NONE, e_g.subargs(4).subargs(1));
|
||||
standardTestsFG(e_g.subargs(2));
|
||||
}
|
||||
|
||||
private void standardTestsFG(Varargs fg) {
|
||||
expectEquals(FG, fg.subargs(1));
|
||||
expectEquals(G, fg.subargs(2));
|
||||
expectEquals(G, fg.subargs(2).subargs(1));
|
||||
expectEquals(NONE, fg.subargs(3));
|
||||
expectEquals(NONE, fg.subargs(3).subargs(1));
|
||||
}
|
||||
|
||||
private void standardTestsNone(Varargs none) {
|
||||
expectEquals(NONE, none.subargs(1));
|
||||
expectEquals(NONE, none.subargs(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVarargsSubargs() {
|
||||
standardTestsA_G(A_G);
|
||||
standardTestsA_G(A_G_alt);
|
||||
standardTestsC_G(C_G);
|
||||
standardTestsC_G(C_G_alt);
|
||||
standardTestsE_G(E_G);
|
||||
standardTestsE_G(E_G_alt);
|
||||
standardTestsFG(FG);
|
||||
standardTestsFG(FG_alt);
|
||||
standardTestsNone(NONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testVarargsMore() {
|
||||
Varargs a_g;
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, }, LuaValue.varargsOf(new LuaValue[] { B, C, D, E, F, G }));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, B, }, LuaValue.varargsOf(new LuaValue[] { C, D, E, F, G }));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, B, C, }, LuaValue.varargsOf(new LuaValue[] { D, E, F, G }));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, B, C, D, }, LuaValue.varargsOf(E, F, G));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, B, C, D, E }, LuaValue.varargsOf(F, G));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = LuaValue.varargsOf(new LuaValue[] { A, B, C, D, E, F, }, G);
|
||||
standardTestsA_G(a_g);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPairVarargsMore() {
|
||||
Varargs a_g = new Varargs.PairVarargs(A, new Varargs.PairVarargs(B, new Varargs.PairVarargs(C,
|
||||
new Varargs.PairVarargs(D, new Varargs.PairVarargs(E, new Varargs.PairVarargs(F, G))))));
|
||||
standardTestsA_G(a_g);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testArrayPartMore() {
|
||||
Varargs a_g;
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 1, new Varargs.ArrayPartVarargs(Z_H_array, 2, 6));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 2, new Varargs.ArrayPartVarargs(Z_H_array, 3, 5));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 3, new Varargs.ArrayPartVarargs(Z_H_array, 4, 4));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 4, new Varargs.ArrayPartVarargs(Z_H_array, 5, 3));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 5, new Varargs.ArrayPartVarargs(Z_H_array, 6, 2));
|
||||
standardTestsA_G(a_g);
|
||||
a_g = new Varargs.ArrayPartVarargs(Z_H_array, 1, 6, new Varargs.ArrayPartVarargs(Z_H_array, 7, 1));
|
||||
standardTestsA_G(a_g);
|
||||
}
|
||||
|
||||
private void expectNegSubargsError(Varargs v) {
|
||||
String expected_msg = "bad argument #1: start must be > 0";
|
||||
try {
|
||||
v.subargs(0);
|
||||
fail("Failed to throw exception for index 0");
|
||||
} catch (LuaError e) {
|
||||
assertEquals(expected_msg, e.getMessage());
|
||||
}
|
||||
try {
|
||||
v.subargs(-1);
|
||||
fail("Failed to throw exception for index -1");
|
||||
} catch (LuaError e) {
|
||||
assertEquals(expected_msg, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
262
luaj-core/src/test/java/org/luaj/vm2/WeakTableTest.java
Normal file
262
luaj-core/src/test/java/org/luaj/vm2/WeakTableTest.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 static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class WeakTableTest {
|
||||
|
||||
@Test
|
||||
void testWeakValuesTable() {
|
||||
LuaTable t = WeakTable.make(false, true);
|
||||
|
||||
Object obj = new Object();
|
||||
LuaTable tableValue = new LuaTable();
|
||||
LuaString stringValue = LuaString.valueOf("this is a test");
|
||||
LuaTable tableValue2 = new LuaTable();
|
||||
|
||||
t.set("table", tableValue);
|
||||
t.set("userdata", LuaValue.userdataOf(obj, null));
|
||||
t.set("string", stringValue);
|
||||
t.set("string2", LuaValue.valueOf("another string"));
|
||||
t.set(1, tableValue2);
|
||||
assertTrue(t.getHashLength() >= 4, "table must have at least 4 elements");
|
||||
// TODO fix assert
|
||||
// assertTrue(t.getArrayLength() >= 1, "array part must have 1 element");
|
||||
|
||||
// check that table can be used to get elements
|
||||
assertEquals(tableValue, t.get("table"));
|
||||
assertEquals(stringValue, t.get("string"));
|
||||
assertEquals(obj, t.get("userdata").checkuserdata());
|
||||
assertEquals(tableValue2, t.get(1));
|
||||
|
||||
// nothing should be collected, since we have strong references here
|
||||
collectGarbage();
|
||||
|
||||
// check that elements are still there
|
||||
assertEquals(tableValue, t.get("table"));
|
||||
assertEquals(stringValue, t.get("string"));
|
||||
assertEquals(obj, t.get("userdata").checkuserdata());
|
||||
assertEquals(tableValue2, t.get(1));
|
||||
|
||||
// drop our strong references
|
||||
obj = null;
|
||||
tableValue = null;
|
||||
tableValue2 = null;
|
||||
stringValue = null;
|
||||
|
||||
// Garbage collection should cause weak entries to be dropped.
|
||||
collectGarbage();
|
||||
|
||||
// check that they are dropped
|
||||
assertEquals(LuaValue.NIL, t.get("table"));
|
||||
assertEquals(LuaValue.NIL, t.get("userdata"));
|
||||
assertEquals(LuaValue.NIL, t.get(1));
|
||||
assertFalse(t.get("string").isnil(), "strings should not be in weak references");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWeakKeysTable() {
|
||||
LuaTable t = WeakTable.make(true, false);
|
||||
|
||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
||||
|
||||
// set up the table
|
||||
t.set(key, val);
|
||||
assertEquals(val, t.get(key));
|
||||
System.gc();
|
||||
assertEquals(val, t.get(key));
|
||||
|
||||
// drop key and value references, replace them with new ones
|
||||
WeakReference<LuaValue> origkey = new WeakReference<>(key);
|
||||
WeakReference<LuaValue> 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(origkey.get()));
|
||||
assertEquals(origval.get(), t.get(key));
|
||||
|
||||
// value should not be reachable after gc
|
||||
collectGarbage();
|
||||
assertEquals(null, origkey.get());
|
||||
assertEquals(LuaValue.NIL, t.get(key));
|
||||
collectGarbage();
|
||||
assertEquals(null, origval.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testNext() {
|
||||
LuaTable t = WeakTable.make(true, true);
|
||||
|
||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
||||
LuaValue key2 = LuaValue.userdataOf(new MyData(333));
|
||||
LuaValue val2 = LuaValue.userdataOf(new MyData(444));
|
||||
LuaValue key3 = LuaValue.userdataOf(new MyData(555));
|
||||
LuaValue val3 = LuaValue.userdataOf(new MyData(666));
|
||||
|
||||
// set up the table
|
||||
t.set(key, val);
|
||||
t.set(key2, val2);
|
||||
t.set(key3, val3);
|
||||
|
||||
// forget one of the keys
|
||||
key2 = null;
|
||||
val2 = null;
|
||||
collectGarbage();
|
||||
|
||||
// table should have 2 entries
|
||||
int size = 0;
|
||||
for (LuaValue k = t.next(LuaValue.NIL).arg1(); !k.isnil(); k = t.next(k).arg1()) {
|
||||
size++;
|
||||
}
|
||||
assertEquals(2, size);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testWeakKeysValuesTable() {
|
||||
LuaTable t = WeakTable.make(true, true);
|
||||
|
||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
||||
LuaValue key2 = LuaValue.userdataOf(new MyData(333));
|
||||
LuaValue val2 = LuaValue.userdataOf(new MyData(444));
|
||||
LuaValue key3 = LuaValue.userdataOf(new MyData(555));
|
||||
LuaValue val3 = LuaValue.userdataOf(new MyData(666));
|
||||
|
||||
// set up the table
|
||||
t.set(key, val);
|
||||
t.set(key2, val2);
|
||||
t.set(key3, val3);
|
||||
assertEquals(val, t.get(key));
|
||||
assertEquals(val2, t.get(key2));
|
||||
assertEquals(val3, t.get(key3));
|
||||
System.gc();
|
||||
assertEquals(val, t.get(key));
|
||||
assertEquals(val2, t.get(key2));
|
||||
assertEquals(val3, t.get(key3));
|
||||
|
||||
// drop key and value references, replace them with new ones
|
||||
WeakReference<LuaValue> origkey = new WeakReference<>(key);
|
||||
WeakReference<LuaValue> origval = new WeakReference<>(val);
|
||||
WeakReference<LuaValue> origkey2 = new WeakReference<>(key2);
|
||||
WeakReference<LuaValue> origval2 = new WeakReference<>(val2);
|
||||
WeakReference<LuaValue> origkey3 = new WeakReference<>(key3);
|
||||
WeakReference<LuaValue> origval3 = new WeakReference<>(val3);
|
||||
key = LuaValue.userdataOf(new MyData(111));
|
||||
val = LuaValue.userdataOf(new MyData(222));
|
||||
key2 = LuaValue.userdataOf(new MyData(333));
|
||||
// don't drop val2, or key3
|
||||
val3 = LuaValue.userdataOf(new MyData(666));
|
||||
|
||||
// no values should be reachable after gc
|
||||
collectGarbage();
|
||||
assertEquals(null, origkey.get());
|
||||
assertEquals(null, origval.get());
|
||||
assertEquals(null, origkey2.get());
|
||||
assertEquals(null, origval3.get());
|
||||
assertEquals(LuaValue.NIL, t.get(key));
|
||||
assertEquals(LuaValue.NIL, t.get(key2));
|
||||
assertEquals(LuaValue.NIL, t.get(key3));
|
||||
|
||||
// all originals should be gone after gc, then access
|
||||
val2 = null;
|
||||
key3 = null;
|
||||
collectGarbage();
|
||||
assertEquals(null, origval2.get());
|
||||
assertEquals(null, origkey3.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReplace() {
|
||||
LuaTable t = WeakTable.make(true, true);
|
||||
|
||||
LuaValue key = LuaValue.userdataOf(new MyData(111));
|
||||
LuaValue val = LuaValue.userdataOf(new MyData(222));
|
||||
LuaValue key2 = LuaValue.userdataOf(new MyData(333));
|
||||
LuaValue val2 = LuaValue.userdataOf(new MyData(444));
|
||||
LuaValue key3 = LuaValue.userdataOf(new MyData(555));
|
||||
LuaValue val3 = LuaValue.userdataOf(new MyData(666));
|
||||
|
||||
// set up the table
|
||||
t.set(key, val);
|
||||
t.set(key2, val2);
|
||||
t.set(key3, val3);
|
||||
|
||||
LuaValue val4 = LuaValue.userdataOf(new MyData(777));
|
||||
t.set(key2, val4);
|
||||
|
||||
// table should have 3 entries
|
||||
int size = 0;
|
||||
for (LuaValue k = t.next(LuaValue.NIL).arg1(); !k.isnil() && size < 1000; k = t.next(k).arg1()) {
|
||||
size++;
|
||||
}
|
||||
assertEquals(3, size);
|
||||
}
|
||||
|
||||
public static class MyData {
|
||||
public final int value;
|
||||
|
||||
public MyData(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof MyData) && ((MyData) o).value == value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "mydata-" + value;
|
||||
}
|
||||
}
|
||||
|
||||
static void collectGarbage() {
|
||||
Runtime rt = Runtime.getRuntime();
|
||||
rt.gc();
|
||||
try {
|
||||
Thread.sleep(20);
|
||||
rt.gc();
|
||||
Thread.sleep(20);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
rt.gc();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user