Files
Calic 58b6cc03d5 fix: add lib-core.panel to test manifest deps
The test init.lua requires lib-core.panel directly; the engine resolver
enforces explicit dependency declaration and does not traverse transitive
deps from inventory-list-display.
2026-06-13 23:28:59 +02:00

138 lines
6.1 KiB
Lua

-- lib-core.inventory-list-display-test — v0.1.0
-- 9 assertions covering widget creation, action lifecycle, resolver
-- overrides, and content ordering.
-- Pattern follows P.2.4 Test-Module-Pattern; TAP output via engine.test.*
local composition = require("lib-core.composition")
local inventory = require("lib-core.inventory-list")
local display = require("lib-core.inventory-list-display")
local T = engine.test
local M = {}
-- ----------------------------------------------------------------
-- Template definitions (shared across all assertions in this run)
-- All template IDs are unique to this test lib to avoid clashes.
-- ----------------------------------------------------------------
-- Container template: kind="list", no constraints.
composition.define_template{
id = "test_backpack",
properties = { position = {x = 0, y = 0} },
tags = {"renderable"},
container = { kind = "list" },
}
-- Item template: individual stack_mode + Atlas-UV properties for icon tests.
composition.define_template{
id = "test_item",
properties = {
stack_mode = "individual",
sprite_atlas = "tex.png",
sprite_uv = {x = 0, y = 0, w = 8, h = 8},
position = {x = 0, y = 0},
},
tags = {"renderable", "item"},
}
function M.run_tests(ctx)
local bp = composition.create{template = "test_backpack"}
-- ================================================================
-- 1. create returns widget_def with render + handle_input + title
-- ================================================================
local widget = display.create(bp, { title = "Backpack" })
T.assert(widget ~= nil, "create returns non-nil")
T.equals(type(widget.render), "function", "widget has render fn")
T.equals(type(widget.handle_input), "function", "widget has handle_input")
T.equals(widget.title, "Backpack", "title set from opts")
-- ================================================================
-- 2. create with non-container entity -> loud-error
-- test_item has no container block, so composition.get_container
-- returns nil, and display.create loud-errors.
-- ================================================================
local plain = composition.create{template = "test_item"}
local ok2 = pcall(display.create, plain)
T.assert(not ok2, "create(non_container) loud-errors")
-- ================================================================
-- 3. register_action + unregister_action round-trip (no error)
-- ================================================================
display.register_action(widget, "Drop", function(item, c) end)
display.register_action(widget, "Inspect", function(item, c) end)
display.unregister_action(widget, "Drop")
T.assert(true, "register/unregister round-trip completes without error")
-- ================================================================
-- 4. Duplicate action label -> loud-error
-- "Drop" was unregistered above; re-register then attempt duplicate.
-- ================================================================
display.register_action(widget, "Drop", function() end)
local ok4 = pcall(display.register_action, widget, "Drop", function() end)
T.assert(not ok4, "duplicate action label loud-errors")
-- ================================================================
-- 5. Non-function callback -> loud-error
-- ================================================================
local ok5 = pcall(display.register_action, widget, "X", "not_fn")
T.assert(not ok5, "non-function callback loud-errors")
-- ================================================================
-- 6. Default action-set is empty; unregister of unknown label is no-op
-- A fresh widget has no implicit actions. Unregistering a missing
-- label must not error (idempotent).
-- ================================================================
local widget2 = display.create(composition.create{template = "test_backpack"})
display.unregister_action(widget2, "Drop") -- no-op: not registered
T.assert(true, "default action-set empty; unregister of unknown label is no-op")
-- ================================================================
-- 7. Rows match inventory.contents order (_test_get_rows)
-- ================================================================
local item_a = composition.create{template = "test_item"}
local item_b = composition.create{template = "test_item"}
inventory.add(bp, item_a)
inventory.add(bp, item_b)
local rows = display._test_get_rows(widget)
T.assert(#rows == 2, "rows reflect inventory.contents count")
-- Verify ordering: item_a was added first, must appear first.
-- Compare by composition.reg_id (stable identity; entity userdata has no __eq).
local rid_a = item_a:get_property("composition.reg_id")
local rid_r1 = rows[1]:get_property("composition.reg_id")
T.assert(rid_a ~= nil and rid_r1 == rid_a,
"rows[1] matches item_a (insertion order preserved)")
-- ================================================================
-- 8. Default icon-resolver reads sprite_atlas + sprite_uv from properties
-- ================================================================
local icon = display._test_resolve_icon(widget, item_a)
T.assert(icon ~= nil, "default icon-resolver returns non-nil table")
T.equals(icon.atlas, "tex.png", "icon.atlas matches sprite_atlas property")
T.equals(icon.uv.x, 0, "icon.uv.x matches sprite_uv.x property")
-- ================================================================
-- 9. Custom icon-resolver invoked after set_icon_resolver
-- ================================================================
local custom_called = false
display.set_icon_resolver(widget, function(item)
custom_called = true
return {atlas = "custom.png", uv = {x = 1, y = 2, w = 3, h = 4}}
end)
local icon2 = display._test_resolve_icon(widget, item_a)
T.assert(custom_called, "custom icon-resolver was invoked after set_icon_resolver")
T.equals(icon2.atlas, "custom.png", "custom resolver returns custom atlas")
end
return M