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' --===== 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("addSystems() correctly sorts systems", function() local sdb = SystemDb(nil) local str = "" local c = ecs.System("c", function(db, dt, params) str = str .. "c" end) local a = ecs.System("a", function(db, dt, params) str = str .. "a" end) local b = ecs.System("b", function(db, dt, params) str = str .. "b" end) b:addDependency(a) c:addDependency(b) sdb:addSystems({c, a, b}, nil) sdb:update(0) assert(str == "abc") end) test("addSystems() fails on dependency loop", function() local a = ecs.System("a", nil) local b = ecs.System("b", nil) local c = ecs.System("c", nil) a:addDependency(c) b:addDependency(a) c:addDependency(b) sdb = SystemDb(nil) local success = pcall(sdb,addSystems, sdb, {c, a, b}, nil) assert(success == false) end) test("addSystems() correctly inserts additional systems", function() local str = "" local sdb = SystemDb(nil) local c = ecs.System("c", function(db, dt, params) str = str .. "c" end) local a = ecs.System("a", function(db, dt, params) str = str .. "a" end) local b = ecs.System("b", function(db, dt, params) str = str .. "b" end) b:addDependency(a) c:addDependency(b) sdb:addSystems({c, a, b}, nil) local d = ecs.System("d", function(db, dt, params) str = str .. "d" end) local e = ecs.System("e", function(db, dt, params) str = str .. "e" end) d:addDependency(c) e:addDependency(d) sdb:addSystems({e, d}, nil) sdb:update(0) assert(str == "abcde") end) test("addSystems() correctly handles dangling dependencies", function() local str = "" local sdb = SystemDb(nil) local c = ecs.System("c", function(db, dt, params) str = str .. "c" end) local a = ecs.System("a", function(db, dt, params) str = str .. "a" end) local b = ecs.System("b", function(db, dt, params) str = str .. "b" end) b:addDependency(a) c:addDependency(b) local d = ecs.System("d", function(db, dt, params) str = str .. "d" end) local e = ecs.System("e", function(db, dt, params) str = str .. "e" end) d:addDependency(c) e:addDependency(d) sdb:addSystems({e, d}, nil) local success = pcall(sdb.update, sdb, nil) assert(success == false) sdb:addSystems({c, a, b}, nil) sdb:update(0) assert(str == "abcde") end) test("removeSystem() correctly handles things", function() local sdb = SystemDb(nil) local num = 1 local two = ecs.System("x2", function(db, dt, p) num = num*2 end) local three = ecs.System("x3", function(db, dt, p) num = num*3 end) local five = ecs.System("x5", function(db, dt, p) num = num*5 end) sdb:addSystems({two, three, five}, nil) sdb:update(0) assert(num == 30) num = 1 sdb:removeSystems({three}) sdb:update(1) assert(num == 10) end) print(string.format("ran %d tests, %d failed", testCount, failCount))