test: add render-contract assertion

Adds a 9th assertion that drives widget.render(ctx) with a stub ctx
shaped per lib-core.panel's widget-lifecycle contract (bounds, theme
with packed-RGBA colours and font_size_body, is_focused) and verifies
the widget populates _render_rows correctly. Catches future drift
between this widget and the panel API.

engine.render.draw_text is registered but errors in test_mode (no
OpenGL context); the assertion stubs it for the duration of the
render call so the layout pass runs to completion without coupling
to the rendering backend.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Calic
2026-06-14 13:36:36 +02:00
parent 0154f54fde
commit b88842161c

View File

@@ -1,6 +1,7 @@
-- lib-core.crafting-display-test — v0.1.0
-- 8 assertions covering widget creation, action lifecycle, default-empty,
-- row visibility (is_known filter), per-row availability, and resolver overrides.
-- 9 assertions covering widget creation, action lifecycle, default-empty,
-- row visibility (is_known filter), per-row availability, resolver overrides,
-- and the panel widget-contract (render(ctx) populating _render_rows).
-- Pattern follows P.2.4 Test-Module-Pattern; TAP output via engine.test.*
local composition = require("lib-core.composition")
@@ -221,6 +222,45 @@ function M.run_tests(_ctx)
local summary8 = display._test_resolve_summary(widget8, recipe8)
T.assert(icon8 == "ICON_X" and label8 == "LABEL_X" and summary8 == "SUMMARY_X",
"8. resolver overrides (icon/label/summary) invoked after set_*_resolver")
-- ================================================================
-- §9: widget.render(ctx) with a panel-shaped ctx populates
-- widget._render_rows. Drives the panel widget contract:
-- render(ctx) where ctx = {bounds, theme, is_focused}. Catches
-- contract-drift between this lib and lib-core.panel.
-- ================================================================
local container9 = setup_container{}
crafting.define_recipe{
id = "render_r9",
inputs = { { template = "craft_display_test.rock", count = 1 } },
output = { template = "craft_display_test.rock_pick", count = 1 },
name = "Render Recipe",
}
local widget9 = display.create(container9, { title = "C", widget_id = "cw" })
local ctx9 = {
bounds = { x = 0, y = 0, w = 400, h = 300 },
theme = {
row_height = 28,
padding = 8,
text_color = 0xFFFFFFFF,
text_color_dim = 0x999999FF,
font_size_body = 14,
},
is_focused = false,
}
-- engine.render.draw_text is registered but errors in test_mode (no
-- OpenGL context); stub it for the duration of this render call so
-- the layout pass runs to completion.
local saved_draw_text = engine.render.draw_text
engine.render.draw_text = function() end
local render_ok, render_err = pcall(widget9.render, ctx9)
engine.render.draw_text = saved_draw_text
T.assert(render_ok
and widget9._render_rows ~= nil
and #widget9._render_rows == 1
and widget9._render_rows[1].recipe_id == "render_r9",
"9. widget.render(ctx) per panel widget contract populates _render_rows"
.. (render_ok and "" or (" (render errored: " .. tostring(render_err) .. ")")))
end
return M