-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Root Cause
Three related behavioral branches in the interactive/live-mode code have no direct test coverage, meaning regressions in user-visible output could go undetected:
1. last_resume_time ignored in running-time display (report.py)
Both render_live_sessions and _render_active_section compute the "Running" / "Running Time" column as:
running = _format_duration(s.last_resume_time or s.start_time) if s.start_time else "—"No test supplies a SessionSummary with both start_time and last_resume_time set to different values and then asserts that the displayed duration is measured from last_resume_time. A regression that dropped the last_resume_time branch would silently show the wrong elapsed time for resumed sessions.
2. _FileChangeHandler.dispatch debounce logic (cli.py)
_FileChangeHandler rate-limits change events to one per 2 seconds. The class has no unit test:
- The happy path (first
dispatchcall sets the event) is untested. - The debounce (rapid second call within 2 s is suppressed) is untested.
_stop_observer(None)(the no-op guard) is also never directly tested.
3. _read_config_model non-string model value (parser.py)
The code guards return model if isinstance(model, str) else None, but there is no test where config.json contains {"model": 42} or {"model": null}. The False branch of the isinstance check is dead from a test perspective.
Expected Behaviour
render_live_sessions: whenlast_resume_timeis set and is more recent thanstart_time, the displayed running time is measured fromlast_resume_time._render_active_section(full summary): same guarantee._FileChangeHandler.dispatch: first call within a cold window setschange_event; second call within 2 s is suppressed (event already set,_last_triggernot reset past the debounce window); calling with a gap > 2 s fires again._stop_observer(None): returns silently without raising._read_config_model: returnsNonewhenmodelis present but is not astr(e.g.42,[],null).
Spec
tests/copilot_usage/test_report.py — add to TestRenderLiveSessions and TestRenderFullSummary:
# test: render_live_sessions — session with last_resume_time more recent than start_time
# displays duration from last_resume_time (not start_time)
# test: _render_active_section — same guarantee for the full-summary active sectiontests/copilot_usage/test_cli.py — add:
# test: _FileChangeHandler.dispatch sets change_event on first call
# test: _FileChangeHandler.dispatch suppresses second call within 2 s (debounce)
# test: _FileChangeHandler.dispatch fires again after > 2 s gap
# test: _stop_observer(None) returns without raisingtests/copilot_usage/test_parser.py — add to TestConfigModelReading:
# test: config.json with {"model": 42} → model is None
# test: config.json with {"model": null} → model is None
# test: config.json with {"model": []} → model is NoneGenerated by Test Suite Analysis · ◷