aboutsummaryrefslogtreecommitdiffstats
path: root/test/test_weather.lua
AgeCommit message (Collapse)AuthorFilesLines
11 daysfix(weather): drop non-finite numbers at parse, add clock()Danilo M.1-2/+19
Parse now rejects inf and NaN fields, clock() wraps os.date so odd epochs read '--', age_str returns '--' for bad input, duration loses a redundant guard. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
11 daysfix(weather): non-finite numbers no longer raiseDanilo M.1-1/+12
deg, num, duration and moon_icon now return their missing-value placeholder for NaN, inf and out-of-range input instead of raising from %d or utf8.char. sun_t clamps NaN to 0 and age_str returns ? for a NaN age. Drops the dead -0 fold in deg and fixes a mislabelled assertion. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
11 daysfeat(weather): parse an Open-Meteo cache instead of OWM JSONDanilo M.1-197/+161
WMO codes to glyphs and words, moon phase, UV and AQI roles, and a parser for the tab-separated cache the fetcher will write. Groundwork for the Mirage-derived forecast cards. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-09-17fix: guard now, and clamp a negative age, in the staleness pairDanilo M.1-0/+11
is_stale and age_str were the only functions in the module doing arithmetic on an unchecked argument: a nil `now` raised, and a raise in this project is a blank dashboard with no message. Every caller passes os.time(), which cannot be nil, so this was unreachable, but it is the same bug already fixed once in icon() and the module header promises nothing raises. age_str also printed a negative age when the observation timestamp was in the future, which a clock skew can produce. "stale -17m" on the card reads as a broken widget, so the age now floors at zero and such a reading counts as fresh: weather from the future is not old. With this the whole module is raise-free, verified across every function against nil, string, table, boolean, NaN, negative and zero arguments in all three positions. Both cases were found by the Task 5 implementer, which was asked to probe beyond its given tests and reported them without changing the code. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17feat: add cache staleness classificationDanilo M.1-0/+14
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17fix: do not truncate a number in exponent formDanilo M.1-0/+12
The numeric patterns stopped at the 'e', so a temp of 1.8e1 parsed as 1.8 and the card would have drawn 2 degrees instead of 18. Wrong in the worst way available: silently, and still looking like weather. OWM has not been seen to emit exponent form, and sampling several cities near and below zero returned plain decimals throughout, so this was not reachable in practice. Fixed regardless, because two characters in a character class is cheaper than the reasoning required to be sure it stays unreachable, and unlike the NaN case noted in sun_t this one fails invisibly rather than leaving a mark. Tests now cover both a negative temperature, which is ordinary here for half the year, and the exponent form. Reverting the pattern fails them. Found by adversarial probing of the committed parser, not by the plan's own tests, which only exercise the fixture. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17feat: parse the cached OWM responseDanilo M.1-0/+43
Lua patterns instead of a JSON library: the current-weather response is flat and known, so six scalars do not justify a dependency. Every failure path (truncated write, empty file, garbage, an API error body, nil input) returns nil rather than raising, since a Lua error here is a blank dashboard. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17feat: add sun position along the daylight arcDanilo M.1-0/+26
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17feat: add wind conversion, Beaufort and compass tablesDanilo M.1-0/+50
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17fix: guard a nil timestamp in the icon lookupDanilo M.1-0/+15
icon(800, nil, 1500, 1900) compared nil against a number and raised, which in this project is a blank dashboard with no message. The module's own header promises nothing raises, and is_day() already guards the same case, so the inconsistency was the bug. Not reachable from the widget as written: it passes os.time(), and parse() refuses a response without sunrise and sunset, so no caller can currently produce the failing combination. Fixed anyway, because the contract is what future callers will rely on and the fix is one word. The test file also now says why the codepoint VALUES carry no assertion: comparing M.ICON.snow against a literal would only prove the escape was typed twice. Whether E31A draws a snow cloud is what the glyph sheet is for, and mutation testing confirms the assertions cannot see it. Found by code review. The same fix is applied to the plan, so Tasks 2-5 inherit the guarded version. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-17feat: add OWM condition id to icon mappingDanilo M.1-0/+65
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>