Skip to content

Commit

Permalink
More Lua test porting
Browse files Browse the repository at this point in the history
Mostly relatively boring, some things to note here:

 - Our UTF-8 spec tests only covers the Lua 5.3 tests. We don't support
   5.4's lax mode yet.

 - I've ported some coroutine tests but am keeping our original ones
   around for now, as they're slightly more advanced (we also test
   suspending), but probably could de-duplicate in the future.

 - Lots of tests I'm very unsure about here (especially in varargs and
   locals). I suspect some of these were for very specific cases in the
   VM which no longer make any sense.
  • Loading branch information
SquidDev committed Oct 31, 2023
1 parent 35e9ec0 commit 90be182
Show file tree
Hide file tree
Showing 19 changed files with 1,059 additions and 478 deletions.
8 changes: 4 additions & 4 deletions src/main/java/org/squiddev/cobalt/lib/Utf8Lib.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ private static Varargs codepoint(LuaState state, Varargs args) throws LuaError {
int i = posRelative(args.arg(2).optInteger(1), length);
int j = posRelative(args.arg(3).optInteger(i), length);

if (i < 1) throw ErrorFactory.argError(2, "out of range");
if (j > length) throw ErrorFactory.argError(3, "out of range");
if (i < 1) throw ErrorFactory.argError(2, "out of bounds");
if (j > length) throw ErrorFactory.argError(3, "out of bounds");
if (i > j) return NONE;

IntBuffer off = new IntBuffer();
Expand Down Expand Up @@ -115,7 +115,7 @@ private static Varargs len(LuaState state, Varargs args) throws LuaError {
IntBuffer offset = new IntBuffer();
while (i <= j) {
long codepoint = decodeUtf8(s, i, offset);
if (codepoint < 0) return varargsOf(Constants.FALSE, valueOf(i + 1));
if (codepoint < 0) return varargsOf(NIL, valueOf(i + 1));

n++;
i += offset.value;
Expand All @@ -131,7 +131,7 @@ private static LuaValue offset(LuaState state, LuaValue arg1, LuaValue arg2, Lua
int length = s.length();
int position = (n >= 0) ? 1 : length + 1;
position = posRelative(arg3.optInteger(position), length) - 1;
if (position < 0 || position > length) throw ErrorFactory.argError(3, "position out of range");
if (position < 0 || position > length) throw ErrorFactory.argError(3, "position out of bounds");

if (n == 0) {
while (position > 0 && isCont(s, position)) position--;
Expand Down
2 changes: 0 additions & 2 deletions src/test/java/org/squiddev/cobalt/AssertTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ public void main(String name) throws IOException, CompileException, LuaError, In
"nextvar",
"pm",
"sort",
"vararg",
"verybig",
})
public void lua51(String name) throws Exception {
Expand All @@ -112,7 +111,6 @@ public void lua51(String name) throws Exception {
"db",
"nextvar",
"tpack",
"utf8",
})
public void lua53(String name) throws Exception {
ScriptHelper helpers = new ScriptHelper("/assert/lua5.3/");
Expand Down
25 changes: 21 additions & 4 deletions src/test/java/org/squiddev/cobalt/LuaSpecTest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.squiddev.cobalt;

import org.junit.jupiter.api.*;
import org.opentest4j.TestAbortedException;
import org.squiddev.cobalt.compiler.CompileException;
import org.squiddev.cobalt.compiler.LoadState;
import org.squiddev.cobalt.debug.DebugHelpers;
Expand All @@ -19,17 +18,21 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertThrows;

public class LuaSpecTest {
private static final Path ROOT = Path.of("src", "test", "resources", "spec");
private static final Pattern TAG = Pattern.compile(":([^ ]+)");
private final LuaState state;
private final LuaTable env;

private List<DynamicNode> nodes;

private static String stripTags(String name) {
return name.replaceAll(" +:[^ ]+", "");
return TAG.matcher(name).replaceAll("");
}

public LuaSpecTest() throws IOException, LuaError, CompileException {
Expand All @@ -40,6 +43,9 @@ public LuaSpecTest() throws IOException, LuaError, CompileException {
Bit32Lib.add(state, env);
TestLib.add(env);

// Set the "arg" global as we've have some tests which need it.
env.rawset("arg", new LuaTable());

try (InputStream is = new BufferedInputStream(Files.newInputStream(ROOT.resolve("_prelude.lua")))) {
var expect = LoadState.load(state, is, "@_prelude.lua", env);
LuaThread.runMain(state, expect);
Expand Down Expand Up @@ -101,8 +107,19 @@ public LuaSpecTest() throws IOException, LuaError, CompileException {
}).create());
}

private static boolean checkTags(String name) {
var matcher = TAG.matcher(name);
while (matcher.find()) {
var tag = matcher.group(1);
if (tag.equals("cobalt") || tag.startsWith("lua")) continue;
if (tag.equals("!cobalt")) return false;
throw new IllegalStateException("Unknown tag " + tag);
}
return true;
}

private static DynamicNode filterNode(String name, DynamicNode node) {
return name.contains(":!cobalt") ? makePending(node) : node;
return checkTags(name) ? node : makePending(node);
}

private static DynamicNode makePending(DynamicNode node) {
Expand All @@ -117,7 +134,7 @@ private static DynamicNode makePending(DynamicNode node) {
test.getDisplayName(),
test.getTestSourceUri().orElse(null),
() -> {
throw new TestAbortedException("Not run on Cobalt");
assertThrows(Throwable.class, test.getExecutable(), "Test is marked :!cobalt, but passes on Cobalt.");
}
);
} else {
Expand Down
32 changes: 0 additions & 32 deletions src/test/resources/assert/lua5.1/closure.lua
Original file line number Diff line number Diff line change
Expand Up @@ -160,24 +160,6 @@ local running, main_thread = coroutine.running()
assert(running ~= nil and main_thread)


-- tests for global environment

local function foo (a)
setfenv(0, a)
coroutine.yield(getfenv())
assert(getfenv(0) == a)
assert(getfenv(1) == _G)
assert(getfenv(loadstring"") == a)
return getfenv()
end

f = coroutine.wrap(foo)
local a = {}
assert(f(a) == _G)
local a,b = pcall(f)
assert(a and b == _G)


-- tests for multiple yield/resume arguments

local function eqtab (t1, t2)
Expand Down Expand Up @@ -406,18 +388,4 @@ _X = coroutine.wrap(function ()

_X()


-- coroutine environments
co = coroutine.create(function ()
coroutine.yield(getfenv(0))
return loadstring("return a")()
end)

a = {a = 15}
debug.setfenv(co, a)
assert(debug.getfenv(co) == a)
assert(select(2, coroutine.resume(co)) == a)
assert(select(2, coroutine.resume(co)) == a.a)


print'OK'
50 changes: 1 addition & 49 deletions src/test/resources/assert/lua5.1/locals.lua
Original file line number Diff line number Diff line change
@@ -1,20 +1,5 @@
print('testing local variables plus some extra stuff')

do
local i = 10
do local i = 100; assert(i==100) end
do local i = 1000; assert(i==1000) end
assert(i == 10)
if i ~= 10 then
local i = 20
else
local i = 30
assert(i == 30)
end
end



f = nil

local f
Expand Down Expand Up @@ -50,39 +35,6 @@ assert(x == 1)
f(2)
assert(type(f) == 'function')


-- testing globals ;-)
do
local f = {}
local _G = _G
for i=1,10 do f[i] = function (x) A=A+1; return A, _G.getfenv(x) end end
A=10; assert(f[1]() == 11)
for i=1,10 do assert(setfenv(f[i], {A=i}) == f[i]) end
assert(f[3]() == 4 and A == 11)
local a,b = f[8](1)
assert(b.A == 9)
a,b = f[8](0)
assert(b.A == 11) -- `real' global
local g
local function f () assert(setfenv(2, {a='10'}) == g) end
g = function () f(); _G.assert(_G.getfenv(1).a == '10') end
g(); assert(getfenv(g).a == '10')
end

-- test for global table of loaded chunks
local function foo (s)
return loadstring(s)
end

assert(getfenv(foo("")) == _G)
local a = {loadstring = loadstring}
setfenv(foo, a)
assert(getfenv(foo("")) == _G)
setfenv(0, a) -- change global environment
assert(getfenv(foo("")) == a)
setfenv(0, _G)


-- testing limits for special instructions

local a
Expand All @@ -109,7 +61,7 @@ print'+'
if rawget(_G, "querytab") then
-- testing clearing of dead elements from tables
collectgarbage("stop") -- stop GC
local a = {[{}] = 4, [3] = 0, alo = 1,
local a = {[{}] = 4, [3] = 0, alo = 1,
a1234567890123456789012345678901234567890 = 10}

local t = querytab(a)
Expand Down
126 changes: 0 additions & 126 deletions src/test/resources/assert/lua5.1/vararg.lua

This file was deleted.

32 changes: 0 additions & 32 deletions src/test/resources/assert/lua5.3/db.lua
Original file line number Diff line number Diff line change
Expand Up @@ -818,36 +818,4 @@ local f = assert(load(string.dump(load(prog), true)))

-- assert(f() == 13)

do -- tests for 'source' in binary dumps
local prog = [[
return function (x)
return function (y)
return x + y
end
end
]]
local name = string.rep("x", 1000)
local p = assert(load(prog, name))
-- load 'p' as a binary chunk with debug information
local c = string.dump(p)
assert(#c > 1000 and #c < 2000) -- no repetition of 'source' in dump
local f = assert(load(c))
local g = f()
local h = g(3)
assert(h(5) == 8)
assert(debug.getinfo(f).source == name and -- all functions have 'source'
debug.getinfo(g).source == name and
debug.getinfo(h).source == name)
-- again, without debug info
local c = string.dump(p, true)
assert(#c < 500) -- no 'source' in dump
local f = assert(load(c))
local g = f()
local h = g(30)
assert(h(50) == 80)
assert(debug.getinfo(f).source == '=?' and -- no function has 'source'
debug.getinfo(g).source == '=?' and
debug.getinfo(h).source == '=?')
end

print"OK"
Loading

0 comments on commit 90be182

Please sign in to comment.