1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

fix & bustitute

This commit is contained in:
Lars Mueller 2025-05-30 18:40:34 +02:00
parent 0f5aae8b98
commit 0b8edb8019
6 changed files with 99 additions and 44 deletions

View file

@ -0,0 +1,64 @@
-- A simple substitute for a busted-like unit test interface
local bustitute = {}
local test_env = setmetatable({}, {__index = _G})
test_env.assert = setmetatable({}, {__call = function(_, ...)
return assert(...)
end})
function test_env.assert.equals(expected, got)
if expected ~= got then
error("expected " .. dump(expected) .. ", got " .. dump(got))
end
end
local function same(a, b)
if a == b then
return true
end
if type(a) ~= "table" or type(b) ~= "table" then
return false
end
for k, v in pairs(a) do
if not same(b[k], v) then
return false
end
end
for k, v in pairs(b) do
if a[k] == nil then -- if a[k] is present, we already compared them above
return false
end
end
return true
end
function test_env.assert.same(expected, got)
if not same(expected, got) then
error("expected " .. dump(expected) .. ", got " .. dump(got))
end
end
local full_test_name = {}
function test_env.describe(name, func)
table.insert(full_test_name, name)
func()
table.remove(full_test_name)
end
function test_env.it(name, func)
table.insert(full_test_name, name)
unittests.register(table.concat(full_test_name, " "), func, {})
table.remove(full_test_name)
end
function bustitute.register(name)
local modpath = core.get_modpath(core.get_current_modname())
local chunk = assert(loadfile(modpath .. "/" .. name .. ".lua"))
setfenv(chunk, test_env)
test_env.describe(name, chunk)
end
return bustitute

View file

@ -74,34 +74,35 @@ function unittests.run_one(idx, counters, out_callback, player, pos)
end
local tbegin = core.get_us_time()
local function done(status, err)
local function done(err)
local tend = core.get_us_time()
local ms_taken = (tend - tbegin) / 1000
if not status then
if err then
core.log("error", err)
end
printf("[%s] %s - %dms", status and "PASS" or "FAIL", def.name, ms_taken)
if seed and not status then
printf("[%s] %s - %dms", err and "FAIL" or "PASS", def.name, ms_taken)
if seed and err then
printf("Random was seeded to %d", seed)
end
counters.time = counters.time + ms_taken
counters.total = counters.total + 1
if status then
counters.passed = counters.passed + 1
end
counters.passed = counters.passed + (err and 0 or 1)
end
if def.async then
core.log("info", "[unittest] running " .. def.name .. " (async)")
def.func(function(err)
done(err == nil, err)
done(err)
out_callback(true)
end, player, pos)
else
core.log("info", "[unittest] running " .. def.name)
local status, err = pcall(def.func, player, pos)
done(status, err)
local err
xpcall(function() return def.func(player, pos) end, function(e)
err = e .. "\n" .. debug.traceback()
end)
done(err)
out_callback(true)
end
@ -201,7 +202,9 @@ dofile(modpath .. "/inventory.lua")
dofile(modpath .. "/load_time.lua")
dofile(modpath .. "/on_shutdown.lua")
dofile(modpath .. "/color.lua")
dofile(modpath .. "/matrix4.lua")
local bustitute = dofile(modpath .. "/bustitute.lua")
bustitute.register("matrix4")
--------------

View file

@ -1,16 +1,8 @@
local function describe(_, func)
func()
end
local function it(section_name, func)
print("Running test: " .. section_name)
func()
end
local assert = require("luassert")
local function assert_close(a, b)
assert(a:equals(b, 1e-4))
local function assert_close(expected, got)
local tolerance = 1e-4
if not expected:equals(got, tolerance) then
error("expected " .. tostring(expected) .. " +- " .. tolerance .. " got " .. tostring(got))
end
end
local mat1 = Matrix4.new(
@ -54,6 +46,7 @@ describe("getters & setters", function()
assert.same({3, 7, 11, 15}, {mat:get_column(3)})
mat:set_column(3, 1, 2, 3, 4)
assert.same({1, 2, 3, 4}, {mat:get_column(3)})
assert.same({3, 7, 11, 15}, {mat1:get_column(3)})
end)
end)
@ -149,7 +142,7 @@ local function random_matrix4()
end
it("determinant", function()
assert.equal(42, Matrix4.scale(vector.new(2, 3, 7)):determinant())
assert.equals(42, Matrix4.scale(vector.new(2, 3, 7)):determinant())
end)
describe("inversion", function()
@ -205,8 +198,8 @@ describe("affine transform constructors", function()
end)
it("rotation", function()
assert_close(Matrix4.new(
0, -1, 0, 0,
1, 0, 0, 0,
0, 1, 0, 0,
-1, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
), Matrix4.rotation(Rotation.z(math.pi / 2)))
@ -238,12 +231,9 @@ describe("affine transform methods", function()
assert.equals(t, trs:get_translation())
end)
it("get rotation & scale", function()
print(trs)
local rotation, scale = trs:get_rs()
print(rotation, scale)
print(r)
assert(r:angle_to(rotation) < 1e-4)
assert(s:distance(scale) < 1e-4)
assert(r:angle_to(rotation) < 1e-3)
assert(s:distance(scale) < 1e-3)
end)
it("set translation", function()
local mat = trs:copy()

View file

@ -78,7 +78,7 @@ int LuaMatrix4::l_rotation(lua_State *L)
{
const core::quaternion &rotation = LuaRotation::check(L, 1);
core::matrix4 &matrix = create(L);
rotation.getMatrix_transposed(matrix);
rotation.getMatrix(matrix);
return 1;
}
@ -297,7 +297,7 @@ int LuaMatrix4::l_get_translation(lua_State *L)
int LuaMatrix4::l_get_rs(lua_State *L)
{
// TODO ? should check that it is, in fact, a rotation matrix;
// TODO maybe check that it is, in fact, a rotation matrix;
// not a fake rotation (axis flip) or a shear matrix
auto matrix = check(L, 1);
v3f scale = matrix.getScale();

View file

@ -62,9 +62,9 @@ template<float v3f::* C>
int LuaRotation::l_fixed_axis_angle(lua_State *L)
{
f32 angle = readFiniteParam<f32>(L, 1);
v3f axis;
axis.*C = 1.0f;
create(L, core::quaternion().fromAngleAxis(angle, axis));
v3f euler_angles;
euler_angles.*C = angle;
create(L, core::quaternion(euler_angles));
return 1;
}

View file

@ -97,19 +97,17 @@ SECTION("matrix-quaternion roundtrip") {
}
SECTION("matrix-quaternion roundtrip") {
v3f rad(0, 0, irr::core::PI / 2);
// test_euler_angles_rad([](v3f rad) {
quaternion q;
q.set(rad);
test_euler_angles_rad([](v3f rad) {
quaternion q(rad);
matrix4 mat;
q.getMatrix(mat);
quaternion q2(mat);
// q2.makeInverse();
matrix4 mat2;
q2.getMatrix(mat2);
CHECK(matrix_equals(mat, mat2));
// CHECK(q.angleTo(q2) < 1e-4);
// });
// FIXME why does this fail?
// CHECK(q.angleTo(q2) < 1e-2);
});
}
SECTION("matrix-euler roundtrip") {