Files
Calic 1e98d70063 initial: notify-test v0.1.0 — 13 assertions
Tests: channel create/list round-trip, tag-match routing, non-match
exclusion, catch-all (empty filter), subscribe callback, unsubscribe,
post-without-tags error, empty-tags error, duplicate-channel error,
unknown-display-mode error, ring-buffer cap, engine-log-mirror toggle,
and severity sugar (warn/info).
2026-06-14 01:30:21 +02:00

148 lines
7.2 KiB
Lua

-- lib-core.notify-test v0.1.0 — 29 assertions
-- Exercises: channel create/list, tag routing, catch-all, subscribe/unsubscribe,
-- error cases, ring-buffer, log-mirror toggle, severity sugar.
local notify = require("lib-core.notify")
local T = engine.test
local M = {}
function M.run_tests(_ctx)
notify._test_clear_all()
-- ------------------------------------------------------------------
-- 1. create + list round-trip
-- ------------------------------------------------------------------
notify.create_channel{ id = "c1", filter = {"a"}, display_mode = "log" }
local list = notify.list_channels()
T.equals(#list, 1, "list_channels returns 1 channel after create")
T.equals(list[1].id, "c1", "listed channel id matches")
-- ------------------------------------------------------------------
-- 2. matching post adds to channel history
-- ------------------------------------------------------------------
notify.post{ tags = {"a"}, text = "hello" }
local h = notify.get_history("c1")
T.equals(#h, 1, "matching post adds message to channel history")
T.equals(h[1].text, "hello", "message text is preserved in history")
-- ------------------------------------------------------------------
-- 3. non-matching post does NOT add to channel history
-- ------------------------------------------------------------------
notify.post{ tags = {"b"}, text = "ignored" }
h = notify.get_history("c1")
T.equals(#h, 1, "non-matching post does not add to channel history")
-- ------------------------------------------------------------------
-- 4. empty filter = catch-all
-- ------------------------------------------------------------------
notify.create_channel{ id = "catch_all", filter = {}, display_mode = "log" }
notify.post{ tags = {"x", "y", "z"}, text = "broadcast" }
h = notify.get_history("catch_all")
T.equals(#h, 1, "empty filter catches any-tagged message")
-- ------------------------------------------------------------------
-- 5. subscribe callback fires on matching post
-- ------------------------------------------------------------------
notify.create_channel{ id = "sub_ch", filter = {"ev"}, display_mode = "toast" }
local fired = 0
local last_msg = nil
local handle = notify.subscribe("sub_ch", function(msg)
fired = fired + 1
last_msg = msg
end)
notify.post{ tags = {"ev"}, text = "event!" }
T.equals(fired, 1, "subscribe callback fires once on matching post")
T.equals(last_msg.text, "event!", "callback receives correct message")
-- ------------------------------------------------------------------
-- 6. unsubscribe stops callback
-- ------------------------------------------------------------------
notify.unsubscribe(handle)
notify.post{ tags = {"ev"}, text = "after unsub" }
T.equals(fired, 1, "unsubscribed callback does not fire on subsequent post")
T.equals(#notify._test_get_subscribers("sub_ch"), 0,
"subscriber list is empty after unsubscribe")
-- ------------------------------------------------------------------
-- 7. post without tags field → loud-error
-- ------------------------------------------------------------------
local ok_no_tags = pcall(notify.post, { text = "no tags" })
T.assert(not ok_no_tags, "post without tags field raises an error")
-- ------------------------------------------------------------------
-- 8. post with empty tags array → loud-error
-- ------------------------------------------------------------------
local ok_empty_tags = pcall(notify.post, { tags = {}, text = "empty tags" })
T.assert(not ok_empty_tags, "post with empty tags array raises an error")
-- ------------------------------------------------------------------
-- 9. duplicate channel id → loud-error
-- ------------------------------------------------------------------
local ok_dup = pcall(notify.create_channel,
{ id = "c1", filter = {}, display_mode = "log" })
T.assert(not ok_dup, "create_channel with duplicate id raises an error")
-- ------------------------------------------------------------------
-- 10. unknown display_mode → loud-error
-- ------------------------------------------------------------------
local ok_bad_mode = pcall(notify.create_channel,
{ id = "bad_mode_ch", filter = {}, display_mode = "popup" })
T.assert(not ok_bad_mode, "create_channel with unknown display_mode raises an error")
-- ------------------------------------------------------------------
-- 11. max_history ring-buffer
-- ------------------------------------------------------------------
notify.create_channel{ id = "ring", filter = {"r"}, display_mode = "toast", max_history = 3 }
for i = 1, 5 do
notify.post{ tags = {"r"}, text = "msg" .. i }
end
h = notify.get_history("ring")
T.equals(#h, 3, "ring-buffer caps history at max_history (3)")
T.equals(h[1].text, "msg3", "oldest kept entry is msg3 (msg1+msg2 dropped)")
T.equals(h[3].text, "msg5", "newest entry is msg5")
-- ------------------------------------------------------------------
-- 12. set_engine_log_mirror toggle
-- ------------------------------------------------------------------
T.assert(notify._test_get_log_mirror() == true, "engine_log_mirror is true by default")
notify.set_engine_log_mirror(false)
T.assert(notify._test_get_log_mirror() == false, "set_engine_log_mirror(false) disables mirror")
notify.set_engine_log_mirror(true)
T.assert(notify._test_get_log_mirror() == true, "set_engine_log_mirror(true) re-enables mirror")
-- non-bool truthy does NOT enable mirror
notify.set_engine_log_mirror("yes")
T.assert(notify._test_get_log_mirror() == false,
"set_engine_log_mirror with non-bool truthy does not enable mirror")
-- ------------------------------------------------------------------
-- 13. severity sugar: warn/info set correct severity field
-- ------------------------------------------------------------------
notify.create_channel{ id = "sev", filter = {"s"}, display_mode = "log" }
notify.warn({"s"}, "a warning")
notify.info({"s"}, "an info")
h = notify.get_history("sev")
T.equals(#h, 2, "warn + info each post one message")
T.equals(h[1].severity, "warn", "warn() sets severity to 'warn'")
T.equals(h[2].severity, "info", "info() sets severity to 'info'")
-- ------------------------------------------------------------------
-- 14. post() does not mutate caller's table
-- ------------------------------------------------------------------
notify._test_clear_all()
notify.create_channel{ id = "x", filter = {"x"}, display_mode = "log" }
local m = { tags = {"x"}, text = "first" }
notify.post(m)
T.assert(m.id == nil, "post does not mutate caller msg.id")
T.assert(m.timestamp == nil, "post does not mutate caller msg.timestamp")
-- Re-using the same table for a second post
m.text = "second"
notify.post(m)
h = notify.get_history("x")
T.assert(#h == 2, "two posts store as two distinct history entries")
T.equals(h[1].text, "first", "first history entry preserved")
T.equals(h[2].text, "second", "second history entry distinct")
end
return M