| Age | Commit message (Collapse) | Author | Files | Lines |
|
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>
|
|
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
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>
|
|
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>
|
|
NaN is a number, so the type guard admits it, and every comparison
against NaN is false, so neither clamp catches it and the function
returns NaN.
Left unguarded on purpose. No caller can produce it: parse() matches
%d+ for the sun times and `now` is os.time(). If one ever did, Cairo
ignores a NaN coordinate, so the arc would lose its dot rather than the
dashboard going blank. A ponytail: comment names the ceiling and where
the guard would go.
Found while probing the committed code, not by the tests, which do not
cover NaN.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Two comments, no behaviour change.
`force - 1` reads as an off-by-one until you know the scale starts at 0
while ipairs starts at 1, so the loop index is already force + 1. Said
plainly now, along with why the fall-through returns 12.
compass() has no caller: the card draws arrow(). It is kept because it
shares arrow()'s binning exactly, so testing both pins that shared logic
from two angles, and switching the card to "S 9 km/h" becomes a one-word
change. Without this note the next reader finds an unused function and
has to reconstruct the reasoning.
Raised by code review as the only two points worth acting on; no
Critical or Important issues were found.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
|
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>
|
|
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|