aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/superpowers/plans/2026-09-17-weather-widget.md6
-rw-r--r--lib/weather.lua6
-rw-r--r--test/test_weather.lua15
3 files changed, 25 insertions, 2 deletions
diff --git a/docs/superpowers/plans/2026-09-17-weather-widget.md b/docs/superpowers/plans/2026-09-17-weather-widget.md
index 853e08c..a7c9ef3 100644
--- a/docs/superpowers/plans/2026-09-17-weather-widget.md
+++ b/docs/superpowers/plans/2026-09-17-weather-widget.md
@@ -174,8 +174,12 @@ M.ICON = {
-- face for the conditions that have both.
function M.icon(id, now, sunrise, sunset)
if type(id) ~= 'number' then return M.ICON.unknown end
+ -- `now` is guarded alongside sunrise and sunset, not just them: comparing a
+ -- nil now against a number raises, and a raise here is a blank dashboard.
+ -- Missing any of the three means the sun is unknown, so the day face is
+ -- drawn, which is what is_day() falls back to as well.
local day = true
- if sunrise and sunset then day = (now >= sunrise and now <= sunset) end
+ if now and sunrise and sunset then day = (now >= sunrise and now <= sunset) end
local function pick(d, n) return day and d or n end
if id <= 232 then return pick(M.ICON.thunder_day, M.ICON.thunder_night)
diff --git a/lib/weather.lua b/lib/weather.lua
index 4eab3ac..0b4b1b7 100644
--- a/lib/weather.lua
+++ b/lib/weather.lua
@@ -41,8 +41,12 @@ M.ICON = {
-- face for the conditions that have both.
function M.icon(id, now, sunrise, sunset)
if type(id) ~= 'number' then return M.ICON.unknown end
+ -- `now` is guarded alongside sunrise and sunset, not just them: comparing a
+ -- nil now against a number raises, and a raise here is a blank dashboard.
+ -- Missing any of the three means the sun is unknown, so the day face is
+ -- drawn, which is what is_day() falls back to as well.
local day = true
- if sunrise and sunset then day = (now >= sunrise and now <= sunset) end
+ if now and sunrise and sunset then day = (now >= sunrise and now <= sunset) end
local function pick(d, n) return day and d or n end
if id <= 232 then return pick(M.ICON.thunder_day, M.ICON.thunder_night)
diff --git a/test/test_weather.lua b/test/test_weather.lua
index 87e787a..f61fa22 100644
--- a/test/test_weather.lua
+++ b/test/test_weather.lua
@@ -62,4 +62,19 @@ assert(icon(804, DAY) == weather.ICON.overcast, 'id 804 is overcast')
assert(icon(999, DAY) == weather.ICON.unknown, 'unknown id gets the error glyph')
assert(weather.icon(nil, DAY, 1500, 1900) == weather.ICON.unknown, 'nil id')
+-- Nothing may raise. A missing timestamp with a known sun, or a known
+-- timestamp with no sun, both have to return a glyph rather than an error,
+-- because an error here is a blank dashboard with no message.
+assert(weather.icon(800, nil, 1500, 1900) == weather.ICON.clear_day,
+ 'a nil now must not raise, and falls back to the day face')
+assert(weather.icon(800, DAY, nil, nil) == weather.ICON.clear_day,
+ 'no sun times must not raise')
+
+-- The codepoint VALUES are deliberately not asserted. A test comparing
+-- M.ICON.snow against a literal would only prove the same escape was typed
+-- twice; whether E31A actually draws a snow cloud in the target font is not
+-- something an assertion can see. That check is the glyph sheet rendered in
+-- the plan's Step 5, and it is how a wrong-but-present codepoint was caught
+-- before this file existed.
+
print('test_weather: all assertions passed')