initial: composition-test v0.1.0 — 14 assertions

Phase-A.1 test-lib for lib-core.composition. Covers define_template,
create, list_by_template, list_by_tag, destroy, list_templates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Axel Meyer
2026-06-09 13:28:55 +00:00
commit 05094c5e24
5 changed files with 183 additions and 0 deletions

111
init.lua Normal file
View File

@@ -0,0 +1,111 @@
-- lib-core.composition-test — Phase A.1
-- 14 assertions: 4 define_template + 4 create + 3 list_by_* + 2 destroy + 1 list_templates.
-- Pattern follows P.2.4 Test-Module-Pattern; TAP output via engine.test.*
local composition = require("lib-core.composition")
local T = engine.test
local M = {}
function M.run_tests(ctx)
-- ----------------------------------------------------------------
-- define_template (4)
-- ----------------------------------------------------------------
-- Happy path: define + retrieve via list_templates
composition.define_template{
id = "sign",
properties = {
sprite_path = "sprites/sign.png",
text = "default text",
position = {x = 0, y = 0},
},
tags = {"renderable"},
}
local templates_after_define = composition.list_templates()
local found_sign = false
for _, id in ipairs(templates_after_define) do
if id == "sign" then found_sign = true; break end
end
T.assert(found_sign, "define_template 'sign' registers in list_templates")
-- Loud-error on missing id
local ok_missing = pcall(composition.define_template, { properties = {} })
T.assert(not ok_missing, "define_template loud-errors on missing id")
-- Loud-error on duplicate id (sign already defined above)
local ok_dup = pcall(composition.define_template, { id = "sign", properties = {} })
T.assert(not ok_dup, "define_template loud-errors on duplicate id")
-- Loud-error on deferred slots-block (Phase D)
local ok_slots = pcall(composition.define_template, {
id = "sword",
slots = { blade = {} },
})
T.assert(not ok_slots, "define_template loud-errors on 'slots' block (Phase D trigger)")
-- ----------------------------------------------------------------
-- create (4)
-- ----------------------------------------------------------------
-- Happy path: create returns a non-nil entity that carries template
-- properties + per-instance overrides
local sign1 = composition.create{
template = "sign",
properties = {
position = {x = 144, y = 200},
text = "Hello",
},
}
T.assert(sign1 ~= nil, "create returns a non-nil entity handle")
T.equals(sign1:get_property("text"), "Hello",
"create override sets text-property")
T.equals(sign1:get_property("position.x"), 144,
"create flattens nested position into position.x")
-- Template-default-property survives when override doesn't touch it
T.equals(sign1:get_property("sprite_path"), "sprites/sign.png",
"create preserves template default for sprite_path")
-- ----------------------------------------------------------------
-- list_by_template + list_by_tag (3)
-- ----------------------------------------------------------------
-- Single instance
local by_tpl = composition.list_by_template("sign")
T.assert(#by_tpl == 1, "list_by_template returns 1 entity after 1 create")
-- Tag-Index
local by_tag = composition.list_by_tag("renderable")
T.assert(#by_tag == 1, "list_by_tag returns 1 entity for 'renderable'")
-- Unknown template / tag → empty
local empty_tpl = composition.list_by_template("nonexistent")
T.assert(#empty_tpl == 0, "list_by_template empty for unknown template")
-- ----------------------------------------------------------------
-- destroy (2)
-- ----------------------------------------------------------------
-- Create a second instance, then destroy it, indexes shrink
local sign2 = composition.create{
template = "sign",
properties = { position = {x = 50, y = 50}, text = "T2" },
}
T.assert(#composition.list_by_template("sign") == 2,
"list_by_template grows to 2 after second create")
composition.destroy(sign2)
T.assert(#composition.list_by_template("sign") == 1,
"destroy shrinks template-index back to 1")
-- ----------------------------------------------------------------
-- list_templates (1)
-- ----------------------------------------------------------------
-- list_templates is non-empty after define
T.assert(#composition.list_templates() >= 1,
"list_templates returns at least 1 entry after define_template")
end
return M