]> git.lizzy.rs Git - minetest.git/commitdiff
Add unittests for entity lifecycle and callbacks
authorsfan5 <sfan5@live.de>
Tue, 14 Jun 2022 10:40:17 +0000 (12:40 +0200)
committersfan5 <sfan5@live.de>
Wed, 15 Jun 2022 15:20:07 +0000 (17:20 +0200)
games/devtest/mods/unittests/entity.lua [new file with mode: 0644]
games/devtest/mods/unittests/init.lua

diff --git a/games/devtest/mods/unittests/entity.lua b/games/devtest/mods/unittests/entity.lua
new file mode 100644 (file)
index 0000000..68635ca
--- /dev/null
@@ -0,0 +1,132 @@
+local log = {}
+
+local function insert_log(...)
+       log[#log+1] = string.format(...)
+end
+
+local function objref_str(self, ref)
+       if ref and ref:is_player() then
+               return "player"
+       end
+       return self.object == ref and "self" or tostring(ref)
+end
+
+core.register_entity("unittests:callbacks", {
+       initial_properties = {
+               hp_max = 5,
+               visual = "upright_sprite",
+               textures = { "unittests_stick.png" },
+               static_save = false,
+       },
+
+       on_activate = function(self, staticdata, dtime_s)
+               self.object:set_armor_groups({test = 100})
+               assert(self.object:get_hp() == self.initial_properties.hp_max)
+               insert_log("on_activate(%d)", #staticdata)
+       end,
+       on_deactivate = function(self, removal)
+               insert_log("on_deactivate(%s)", tostring(removal))
+       end,
+       on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
+               insert_log("on_punch(%s, %.1f, %d)", objref_str(self, puncher),
+                       time_from_last_punch, damage)
+       end,
+       on_death = function(self, killer)
+               assert(self.object:get_hp() == 0)
+               insert_log("on_death(%s)", objref_str(self, killer))
+       end,
+       on_rightclick = function(self, clicker)
+               insert_log("on_rightclick(%s)", objref_str(self, clicker))
+       end,
+       on_attach_child = function(self, child)
+               insert_log("on_attach_child(%s)", objref_str(self, child))
+       end,
+       on_detach_child = function(self, child)
+               insert_log("on_detach_child(%s)", objref_str(self, child))
+       end,
+       on_detach = function(self, parent)
+               insert_log("on_detach(%s)", objref_str(self, parent))
+       end,
+       get_staticdata = function(self)
+               assert(false)
+       end,
+})
+
+--
+
+local function check_log(expect)
+       if #expect ~= #log then
+               error("Log mismatch: " .. core.write_json(log))
+       end
+       for i, s in ipairs(expect) do
+               if log[i] ~= s then
+                       error("Log mismatch at " .. i .. ": " .. core.write_json(log))
+               end
+       end
+       log = {} -- clear it for next time
+end
+
+local function test_entity_lifecycle(_, pos)
+       log = {}
+
+       -- with binary in staticdata
+       local obj = core.add_entity(pos, "unittests:callbacks", "abc\000def")
+       check_log({"on_activate(7)"})
+
+       obj:set_hp(0)
+       check_log({"on_death(nil)", "on_deactivate(true)"})
+
+       -- objectref must be invalid now
+       assert(obj:get_velocity() == nil)
+end
+unittests.register("test_entity_lifecycle", test_entity_lifecycle, {map=true})
+
+local function test_entity_interact(_, pos)
+       log = {}
+
+       local obj = core.add_entity(pos, "unittests:callbacks")
+       check_log({"on_activate(0)"})
+
+       -- rightclick
+       obj:right_click(obj)
+       check_log({"on_rightclick(self)"})
+
+       -- useless punch
+       obj:punch(obj, 0.5, {})
+       check_log({"on_punch(self, 0.5, 0)"})
+
+       -- fatal punch
+       obj:punch(obj, 1.9, {
+               full_punch_interval = 1.0,
+               damage_groups = { test = 10 },
+       })
+       check_log({
+               -- does 10 damage even though we only have 5 hp
+               "on_punch(self, 1.9, 10)",
+               "on_death(self)",
+               "on_deactivate(true)"
+       })
+end
+unittests.register("test_entity_interact", test_entity_interact, {map=true})
+
+local function test_entity_attach(player, pos)
+       log = {}
+
+       local obj = core.add_entity(pos, "unittests:callbacks")
+       check_log({"on_activate(0)"})
+
+       -- attach player to entity
+       player:set_attach(obj)
+       check_log({"on_attach_child(player)"})
+       player:set_detach()
+       check_log({"on_detach_child(player)"})
+
+       -- attach entity to player
+       obj:set_attach(player)
+       check_log({})
+       obj:set_detach()
+       check_log({"on_detach(player)"})
+
+       obj:remove()
+end
+unittests.register("test_entity_attach", test_entity_attach, {player=true, map=true})
index 0608f2dd21ed18a91bd146d07d0cef7c7e047492..96651a8787380c1279c7f77c5e1019c663ce29e6 100644 (file)
@@ -112,7 +112,7 @@ local function wait_for_map(player, callback)
                if core.get_node_or_nil(player:get_pos()) ~= nil then
                        callback()
                else
-                       minetest.after(0, check)
+                       core.after(0, check)
                end
        end
        check()
@@ -170,12 +170,13 @@ end
 
 --------------
 
-local modpath = minetest.get_modpath("unittests")
+local modpath = core.get_modpath("unittests")
 dofile(modpath .. "/misc.lua")
 dofile(modpath .. "/player.lua")
 dofile(modpath .. "/crafting.lua")
 dofile(modpath .. "/itemdescription.lua")
 dofile(modpath .. "/async_env.lua")
+dofile(modpath .. "/entity.lua")
 
 --------------
 
@@ -184,7 +185,7 @@ if core.settings:get_bool("devtest_unittests_autostart", false) then
                coroutine.wrap(unittests.run_all)()
        end)
 else
-       minetest.register_chatcommand("unittests", {
+       core.register_chatcommand("unittests", {
                privs = {basic_privs=true},
                description = "Runs devtest unittests (may modify player or map state)",
                func = function(name, param)