From a2ae7aae8357c8c2684d85fd58b0c5a0563ebab9 Mon Sep 17 00:00:00 2001 From: sanine-a Date: Tue, 9 May 2023 11:31:17 -0500 Subject: refactor: split ecs systems into multiple files --- honey/ecs/ecs.test.lua | 280 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 honey/ecs/ecs.test.lua (limited to 'honey/ecs/ecs.test.lua') diff --git a/honey/ecs/ecs.test.lua b/honey/ecs/ecs.test.lua new file mode 100644 index 0000000..74e27dc --- /dev/null +++ b/honey/ecs/ecs.test.lua @@ -0,0 +1,280 @@ +local testCount = 0 +local failCount = 0 + +local function test(msg, f) + testCount = testCount + 1 + local success, error = xpcall(f, debug.traceback) + if success then + print(msg .. "\t\t[OK]") + else + failCount = failCount + 1 + print(msg .. "\t\t[FAIL]") + print(error) + end +end + + +local ecs = require 'ecs' + + +--===== Component tests =====-- + +local Component = ecs.Component + +test("factories work as expected", function() + local factory = Component.newFactory("health", { percent=100 }) + local comp1 = factory() + assert(comp1.__type == "health", "bad component type for comp1") + assert(comp1.percent == 100, "bat percent for comp1") + + local comp2 = factory{ percent=50 } + assert(comp2.__type == "health", "bad component type for comp2") + assert(comp2.percent == 50, "bad percent for comp2") + + local success = pcall(function() + comp2.dne = 5 + end) + assert(not success, "incorrectly succeeded in setting comp2.dne") + + local success = pcall(function() + local comp3 = factory{ percent = 44, something = 2 } + end) + assert(not success, "incorrectly succeeded in creating comp3") +end) + + +test("components serialize as expected", function() + local position = Component.newFactory("position", { x=0, y=0, z=0 }) + local comp = position{x=10, y=15, z=10} + local str = tostring(comp) + local tbl = (loadstring("return " .. str))() + assert(tbl.__type == "position", "bad type") + assert(tbl.x == 10, "bad x") + assert(tbl.y == 15, "bad y") + assert(tbl.z == 10, "bad z") +end) + + +test("components serialize successfully with subcomponents", function() + local position = Component.newFactory("position", { x=0, y=0, z=0 }) + local player = Component.newFactory("player", { name="", position={} }) + + local p = player{ name="hannah", position=position{x=10, y=9, z=8} } + local tbl = (loadstring("return " .. tostring(p)))() + assert(tbl.__type == "player") + assert(tbl.name == "hannah") + assert(tbl.position.__type == "position") + assert(tbl.position.x == 10) + assert(tbl.position.y == 9) + assert(tbl.position.z == 8) +end) + + +--===== EntityDb tests =====-- + +local EntityDb = ecs.EntityDb + + +test("EntityDb.createEntity() always returns a new id", function() + local db = EntityDb() + + local ids = {} + for i=1,100 do + local id = db:createEntity() + assert(ids[id] == nil, "id was already returned!") + ids[id] = true + end +end) + + +test("EntityDb.queryComponent() gets all entities with a given component", function() + local db = EntityDb() + + local ids = {} + for i=1,100 do + local id = db:createEntity() + if i%2==0 then + ids[id] = 5*i + db:addComponent(id, "number", 5*i) + end + end + + local query = db:queryComponent("number") + local count = 0 + for id, number in pairs(query) do + count = count + 1 + assert(number == ids[id]) + end + assert(count == 50) +end) + + +test("EntityDb.queryEntity() gets all components associated with an entity", function() + local db = EntityDb() + + local entity + for i=1,100 do + local id = db:createEntity() + if i%2 == 0 then db:addComponent(id, "number", 2) end + if i%3 == 0 then db:addComponent(id, "string", "hello") end + if i%5 == 0 then db:addComponent(id, "number2", 4) end + if i%7 == 0 then db:addComponent(id, "string2", "world") end + if i == 30 then entity=id end + end + + local query = db:queryEntity(entity) + assert(query.number == 2) + assert(query.string == "hello") + assert(query.number2 == 4) + assert(query.string2 == nil) +end) + + +test("EntityDb.removeComponent() removes components correctly", function() + local db = EntityDb() + + local id = db:createEntity() + db:addComponent(id, "number", 2) + db:addComponent(id, "string", "hello") + db:addComponent(id, "number2", 4) + db:addComponent(id, "string2", "world") + + local query = db:queryEntity(id) + assert(query.number == 2) + assert(query.string == "hello") + assert(query.number2 == 4) + assert(query.string2 == "world") + + db:removeComponent(id, "string2") + query = db:queryEntity(id) + assert(query.number == 2) + assert(query.string == "hello") + assert(query.number2 == 4) + assert(query.string2 == nil) + + db:removeComponent(id, "number2") + query = db:queryEntity(id) + assert(query.number == 2) + assert(query.string == "hello") + assert(query.number2 == nil) + assert(query.string2 == nil) + + db:removeComponent(id, "string") + query = db:queryEntity(id) + assert(query.number == 2) + assert(query.string == nil) + assert(query.number2 == nil) + assert(query.string2 == nil) + + db:removeComponent(id, "number") + query = db:queryEntity(id) + assert(query.number == nil) + assert(query.string == nil) + assert(query.number2 == nil) + assert(query.string2 == nil) +end) + + +test("EntityDb.removeComponent() deletes component table when empty", function() + local db = EntityDb() + local id1 = db:createEntity() + local id2 = db:createEntity() + db:addComponent(id1, "number", 2) + db:addComponent(id2, "number", 3) + + assert(db.components.number ~= nil) + db:removeComponent(id1, "number") + assert(db.components.number ~= nil) + db:removeComponent(id2, "number") + assert(db.components.number == nil) +end) + + +test("EntityDb.removeComponent() does nothing if the component is not present", function() + local db = EntityDb() + local id1 = db:createEntity() + local id2 = db:createEntity() + db:addComponent(id1, "number", 2) + db:addComponent(id2, "number", 3) + + assert(db.components.number ~= nil) + db:removeComponent(id1, "number") + assert(db.components.number ~= nil) + db:removeComponent(id1, "number") + assert(db.components.number ~= nil) + + db:removeComponent(id2, "number") + assert(db.components.number == nil) + +end) + + +test("EntityDb.deleteEntity() correctly removes an entity", function() + local db = EntityDb() + local id1 = db:createEntity() + local id2 = db:createEntity() + db:addComponent(id1, "number", 2) + db:addComponent(id2, "number", 3) + + local query = db:queryComponent("number") + assert(query[id1] and query[id2]) + db:deleteEntity(id1) + query = db:queryComponent("number") + assert(query[id1] == nil) + assert(query[id2] ~= nil) + + assert(false == pcall(function() + local query = db:queryEntity(id1) + end)) +end) + + +--===== SystemDb tests =====-- + +local SystemDb = ecs.SystemDb + +test("addSystem() correctly sorts systems", function() + local sdb = SystemDb(nil) + local str = "" + sdb:addSystem(function () return { + update=function(self, dt) str = str .. "c" end, + priority = 3, + } end) + sdb:addSystem{ + update=function(self, dt) str = "a" end, + priority = 1, + } + sdb:addSystem{ + update=function(self, dt) str = str .. "b" end, + priority = 2, + } + sdb:update(0) + assert(str == "abc") +end) + + +test("removeSystem() correctly handles things", function() + local sdb = SystemDb(nil) + local str = "" + sdb:addSystem(function () return { + update=function(self, dt) str = str .. "c" end, + priority = 3, + } end) + sdb:addSystem{ + update=function(self, dt) str = "a" end, + priority = 1, + } + local id = sdb:addSystem{ + update=function(self, dt) str = str .. "b" end, + priority = 2, + } + sdb:update(0) + assert(str == "abc") + + sdb:removeSystem(id) + sdb:update(1) + assert(str == "ac") +end) + + +print(string.format("ran %d tests, %d failed", testCount, failCount)) -- cgit v1.2.1