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:
parent
0f5aae8b98
commit
0b8edb8019
6 changed files with 99 additions and 44 deletions
64
games/devtest/mods/unittests/bustitute.lua
Normal file
64
games/devtest/mods/unittests/bustitute.lua
Normal 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
|
|
@ -74,34 +74,35 @@ function unittests.run_one(idx, counters, out_callback, player, pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
local tbegin = core.get_us_time()
|
local tbegin = core.get_us_time()
|
||||||
local function done(status, err)
|
local function done(err)
|
||||||
local tend = core.get_us_time()
|
local tend = core.get_us_time()
|
||||||
local ms_taken = (tend - tbegin) / 1000
|
local ms_taken = (tend - tbegin) / 1000
|
||||||
|
|
||||||
if not status then
|
if err then
|
||||||
core.log("error", err)
|
core.log("error", err)
|
||||||
end
|
end
|
||||||
printf("[%s] %s - %dms", status and "PASS" or "FAIL", def.name, ms_taken)
|
printf("[%s] %s - %dms", err and "FAIL" or "PASS", def.name, ms_taken)
|
||||||
if seed and not status then
|
if seed and err then
|
||||||
printf("Random was seeded to %d", seed)
|
printf("Random was seeded to %d", seed)
|
||||||
end
|
end
|
||||||
counters.time = counters.time + ms_taken
|
counters.time = counters.time + ms_taken
|
||||||
counters.total = counters.total + 1
|
counters.total = counters.total + 1
|
||||||
if status then
|
counters.passed = counters.passed + (err and 0 or 1)
|
||||||
counters.passed = counters.passed + 1
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if def.async then
|
if def.async then
|
||||||
core.log("info", "[unittest] running " .. def.name .. " (async)")
|
core.log("info", "[unittest] running " .. def.name .. " (async)")
|
||||||
def.func(function(err)
|
def.func(function(err)
|
||||||
done(err == nil, err)
|
done(err)
|
||||||
out_callback(true)
|
out_callback(true)
|
||||||
end, player, pos)
|
end, player, pos)
|
||||||
else
|
else
|
||||||
core.log("info", "[unittest] running " .. def.name)
|
core.log("info", "[unittest] running " .. def.name)
|
||||||
local status, err = pcall(def.func, player, pos)
|
local err
|
||||||
done(status, err)
|
xpcall(function() return def.func(player, pos) end, function(e)
|
||||||
|
err = e .. "\n" .. debug.traceback()
|
||||||
|
end)
|
||||||
|
done(err)
|
||||||
out_callback(true)
|
out_callback(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -201,7 +202,9 @@ dofile(modpath .. "/inventory.lua")
|
||||||
dofile(modpath .. "/load_time.lua")
|
dofile(modpath .. "/load_time.lua")
|
||||||
dofile(modpath .. "/on_shutdown.lua")
|
dofile(modpath .. "/on_shutdown.lua")
|
||||||
dofile(modpath .. "/color.lua")
|
dofile(modpath .. "/color.lua")
|
||||||
dofile(modpath .. "/matrix4.lua")
|
|
||||||
|
local bustitute = dofile(modpath .. "/bustitute.lua")
|
||||||
|
bustitute.register("matrix4")
|
||||||
|
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,8 @@
|
||||||
local function describe(_, func)
|
local function assert_close(expected, got)
|
||||||
func()
|
local tolerance = 1e-4
|
||||||
end
|
if not expected:equals(got, tolerance) then
|
||||||
|
error("expected " .. tostring(expected) .. " +- " .. tolerance .. " got " .. tostring(got))
|
||||||
local function it(section_name, func)
|
end
|
||||||
print("Running test: " .. section_name)
|
|
||||||
func()
|
|
||||||
end
|
|
||||||
|
|
||||||
local assert = require("luassert")
|
|
||||||
|
|
||||||
local function assert_close(a, b)
|
|
||||||
assert(a:equals(b, 1e-4))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local mat1 = Matrix4.new(
|
local mat1 = Matrix4.new(
|
||||||
|
@ -54,6 +46,7 @@ describe("getters & setters", function()
|
||||||
assert.same({3, 7, 11, 15}, {mat:get_column(3)})
|
assert.same({3, 7, 11, 15}, {mat:get_column(3)})
|
||||||
mat:set_column(3, 1, 2, 3, 4)
|
mat:set_column(3, 1, 2, 3, 4)
|
||||||
assert.same({1, 2, 3, 4}, {mat:get_column(3)})
|
assert.same({1, 2, 3, 4}, {mat:get_column(3)})
|
||||||
|
assert.same({3, 7, 11, 15}, {mat1:get_column(3)})
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -149,7 +142,7 @@ local function random_matrix4()
|
||||||
end
|
end
|
||||||
|
|
||||||
it("determinant", function()
|
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)
|
end)
|
||||||
|
|
||||||
describe("inversion", function()
|
describe("inversion", function()
|
||||||
|
@ -205,8 +198,8 @@ describe("affine transform constructors", function()
|
||||||
end)
|
end)
|
||||||
it("rotation", function()
|
it("rotation", function()
|
||||||
assert_close(Matrix4.new(
|
assert_close(Matrix4.new(
|
||||||
0, -1, 0, 0,
|
0, 1, 0, 0,
|
||||||
1, 0, 0, 0,
|
-1, 0, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, 0, 1
|
0, 0, 0, 1
|
||||||
), Matrix4.rotation(Rotation.z(math.pi / 2)))
|
), Matrix4.rotation(Rotation.z(math.pi / 2)))
|
||||||
|
@ -238,12 +231,9 @@ describe("affine transform methods", function()
|
||||||
assert.equals(t, trs:get_translation())
|
assert.equals(t, trs:get_translation())
|
||||||
end)
|
end)
|
||||||
it("get rotation & scale", function()
|
it("get rotation & scale", function()
|
||||||
print(trs)
|
|
||||||
local rotation, scale = trs:get_rs()
|
local rotation, scale = trs:get_rs()
|
||||||
print(rotation, scale)
|
assert(r:angle_to(rotation) < 1e-3)
|
||||||
print(r)
|
assert(s:distance(scale) < 1e-3)
|
||||||
assert(r:angle_to(rotation) < 1e-4)
|
|
||||||
assert(s:distance(scale) < 1e-4)
|
|
||||||
end)
|
end)
|
||||||
it("set translation", function()
|
it("set translation", function()
|
||||||
local mat = trs:copy()
|
local mat = trs:copy()
|
||||||
|
|
|
@ -78,7 +78,7 @@ int LuaMatrix4::l_rotation(lua_State *L)
|
||||||
{
|
{
|
||||||
const core::quaternion &rotation = LuaRotation::check(L, 1);
|
const core::quaternion &rotation = LuaRotation::check(L, 1);
|
||||||
core::matrix4 &matrix = create(L);
|
core::matrix4 &matrix = create(L);
|
||||||
rotation.getMatrix_transposed(matrix);
|
rotation.getMatrix(matrix);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +297,7 @@ int LuaMatrix4::l_get_translation(lua_State *L)
|
||||||
|
|
||||||
int LuaMatrix4::l_get_rs(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
|
// not a fake rotation (axis flip) or a shear matrix
|
||||||
auto matrix = check(L, 1);
|
auto matrix = check(L, 1);
|
||||||
v3f scale = matrix.getScale();
|
v3f scale = matrix.getScale();
|
||||||
|
|
|
@ -62,9 +62,9 @@ template<float v3f::* C>
|
||||||
int LuaRotation::l_fixed_axis_angle(lua_State *L)
|
int LuaRotation::l_fixed_axis_angle(lua_State *L)
|
||||||
{
|
{
|
||||||
f32 angle = readFiniteParam<f32>(L, 1);
|
f32 angle = readFiniteParam<f32>(L, 1);
|
||||||
v3f axis;
|
v3f euler_angles;
|
||||||
axis.*C = 1.0f;
|
euler_angles.*C = angle;
|
||||||
create(L, core::quaternion().fromAngleAxis(angle, axis));
|
create(L, core::quaternion(euler_angles));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -97,19 +97,17 @@ SECTION("matrix-quaternion roundtrip") {
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("matrix-quaternion roundtrip") {
|
SECTION("matrix-quaternion roundtrip") {
|
||||||
v3f rad(0, 0, irr::core::PI / 2);
|
test_euler_angles_rad([](v3f rad) {
|
||||||
// test_euler_angles_rad([](v3f rad) {
|
quaternion q(rad);
|
||||||
quaternion q;
|
|
||||||
q.set(rad);
|
|
||||||
matrix4 mat;
|
matrix4 mat;
|
||||||
q.getMatrix(mat);
|
q.getMatrix(mat);
|
||||||
quaternion q2(mat);
|
quaternion q2(mat);
|
||||||
// q2.makeInverse();
|
|
||||||
matrix4 mat2;
|
matrix4 mat2;
|
||||||
q2.getMatrix(mat2);
|
q2.getMatrix(mat2);
|
||||||
CHECK(matrix_equals(mat, 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") {
|
SECTION("matrix-euler roundtrip") {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue