Files

144 lines
7.7 KiB
Lua

-- lib-core.notify-display-test v0.1.0 — 10 assertions
-- Exercises: attach_mode (log/toast/detail), validation, toast lifecycle,
-- widget factories, detail overwrite, detach cleanup, widget-channel tracking.
local notify = require("lib-core.notify")
local panel = require("lib-core.panel")
local display = require("lib-core.notify-display")
local T = engine.test
local M = {}
-- Helper: create a fresh set of test channels and reset all state
local function setup()
notify._test_clear_all()
-- panel has no _test_clear_all; unregister any widgets we might have registered
pcall(panel.unregister, "game-log")
pcall(panel.unregister, "detail-panel")
pcall(panel.unregister, "log-a")
pcall(panel.unregister, "log-b")
display._test_reset()
end
function M.run_tests(_ctx)
-- ==================================================================
-- 1. attach_mode("log") succeeds with valid panel_widget_id
-- ==================================================================
setup()
notify.create_channel{ id = "log-ch1", filter = {"event"}, display_mode = "log" }
local ok_log = pcall(display.attach_mode, "log", { panel_widget_id = "game-log" })
T.assert(ok_log, "attach_mode('log', {panel_widget_id='game-log'}) succeeds")
-- ==================================================================
-- 2. attach_mode("toast") with invalid position → loud-error
-- ==================================================================
setup()
local ok_bad_pos = pcall(display.attach_mode, "toast", { position = "invalid" })
T.assert(not ok_bad_pos, "attach_mode('toast') with invalid position raises an error")
-- ==================================================================
-- 3. attach_mode("detail") with valid panel_widget_id succeeds
-- ==================================================================
setup()
notify.create_channel{ id = "det-ch", filter = {"detail-ev"}, display_mode = "detail" }
local ok_detail = pcall(display.attach_mode, "detail", { panel_widget_id = "detail-panel" })
T.assert(ok_detail, "attach_mode('detail', {panel_widget_id='detail-panel'}) succeeds")
-- ==================================================================
-- 4. attach toast → post → _test_get_active_toasts returns 1 entry
-- ==================================================================
setup()
notify.create_channel{ id = "toast-ch", filter = {"hud"}, display_mode = "toast" }
display.attach_mode("toast", { position = "top-right", default_ttl = 10.0 })
notify.post{ tags = {"hud"}, text = "alert!" }
local toasts = display._test_get_active_toasts()
T.equals(#toasts, 1, "post to toast-channel produces 1 active toast")
T.equals(toasts[1].msg.text, "alert!", "toast message text is correct")
-- ==================================================================
-- 5. update(dt) past TTL → toast removed
-- ==================================================================
-- Test 5: TTL expiry via engine.time monkey-patch.
-- INTENTIONALLY no setup() call — depends on the toast posted in test 4
-- (active_toasts is preserved across tests when setup is skipped).
-- Reuse state from test 4; toasts[1].spawn_time is 0 (engine.time absent in test)
-- Force-expire by calling update with a dt larger than the spawn_time offset.
-- spawn_time = 0, ttl = 10.0; now = 0 → not expired.
-- We monkey-patch engine.time to return a future timestamp.
local saved_engine_time = engine.time
engine.time = { now = function() return 100.0 end }
display.update(0)
engine.time = saved_engine_time
toasts = display._test_get_active_toasts()
T.equals(#toasts, 0, "update() past TTL removes expired toasts")
-- ==================================================================
-- 6. create_log_widget returns table with render / handle_input / title
-- ==================================================================
local log_widget = display.create_log_widget({ widget_id = "game-log", title = "Events" })
T.assert(type(log_widget) == "table", "create_log_widget returns a table")
T.assert(type(log_widget.render) == "function","log widget_def has render function")
T.assert(type(log_widget.handle_input) == "function",
"log widget_def has handle_input function")
T.equals(log_widget.title, "Events", "log widget title is set from opts")
-- ==================================================================
-- 7. create_detail_widget + post → _test_get_last_detail returns msg
-- ==================================================================
setup()
notify.create_channel{ id = "dw-ch", filter = {"detail-ev"}, display_mode = "detail" }
local det_widget = display.create_detail_widget({ widget_id = "detail-panel", title = "Info" })
T.assert(type(det_widget) == "table", "create_detail_widget returns a table")
T.assert(type(det_widget.render) == "function","detail widget_def has render function")
-- Register widget first so that panel.open inside the subscribe callback succeeds
panel.register("detail-panel", det_widget)
display.attach_mode("detail", { panel_widget_id = "detail-panel" })
notify.post{ tags = {"detail-ev"}, text = "important!" }
local last = display._test_get_last_detail()
T.assert(last ~= nil, "_test_get_last_detail is set after detail post")
T.equals(last.text, "important!", "detail message text is correct")
T.assert(panel.is_open(), "panel is open after detail message auto-open")
-- ==================================================================
-- 8. Two log-channels mapped to same panel_widget_id → 2 entries tracked
-- ==================================================================
setup()
notify.create_channel{ id = "log-a", filter = {"ev-a"}, display_mode = "log" }
notify.create_channel{ id = "log-b", filter = {"ev-b"}, display_mode = "log" }
display.attach_mode("log", { panel_widget_id = "game-log" })
local tracked = display._test_get_widget_channels("game-log")
T.equals(#tracked, 2, "two log-channels both tracked under same panel_widget_id")
-- ==================================================================
-- 9. detach_mode("toast") removes toast-channel subscriptions
-- ==================================================================
setup()
notify.create_channel{ id = "toast-a", filter = {"t"}, display_mode = "toast" }
display.attach_mode("toast", {})
local count_before = display._test_subscriber_count()
display.detach_mode("toast")
local count_after = display._test_subscriber_count()
T.assert(count_before > count_after,
"detach_mode('toast') reduces subscriber count")
T.equals(count_after, 0, "subscriber count is 0 after detach_mode('toast')")
-- ==================================================================
-- 10. Detail overwrite: post msg-A then msg-B → last_detail == B
-- ==================================================================
setup()
notify.create_channel{ id = "ow-ch", filter = {"ow"}, display_mode = "detail" }
local ow_widget = display.create_detail_widget({ widget_id = "detail-panel", title = "D" })
panel.register("detail-panel", ow_widget)
display.attach_mode("detail", { panel_widget_id = "detail-panel" })
notify.post{ tags = {"ow"}, text = "A" }
notify.post{ tags = {"ow"}, text = "B" }
local overwritten = display._test_get_last_detail()
T.equals(overwritten.text, "B",
"second detail post overwrites first (_test_get_last_detail.text == 'B')")
end
return M