Plot live drive activity every three minutes (#91)
- Change default collection cadence from 5 minutes to 3 minutes (CADENCE_DEFAULT_S=180, systemd OnUnitInactiveSec=3min, runit CADENCE=180) - Update freshness threshold to 450s (2×180 + AccuracySec + 60) - Add _query_live_graph_data(): queries raw samples from the last 3 hours and computes interval byte deltas with actual timestamps - Add LiveActivityGraph widget: vertical bar chart of interval volumes with read/write toggle (w key), arrow key inspection, and click support - Wire live graph into TUI layout (full-width row between daily graph and drive health), refresh cycle, and CSS grid - Replace t theme binding with t today/live binding; theme selection via preferences file - Add w binding for read/write toggle on live graph - Update action legend, help screen, and grid layout for new live-activity row - Add 20 tests covering cadence constants, live query, widget rendering, toggle, and TUI integration - Update all cadence documentation (README, ADR 0003, acceptance criteria LC-2, fenris-redesign constants table, CHANGELOG)
This commit is contained in:
+18
-11
@@ -171,8 +171,8 @@ class TestKeyBindings:
|
||||
assert "m" in binding_keys
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_t_cycles_through_themes(self, tmp_path):
|
||||
"""Pressing t cycles through the three presets."""
|
||||
async def test_t_goes_to_today(self, tmp_path):
|
||||
"""Pressing t returns to today's live view (issue #91)."""
|
||||
from fenris.tui import FenrisTuiApp
|
||||
|
||||
config_home = _make_prefs_dir(tmp_path)
|
||||
@@ -182,12 +182,17 @@ class TestKeyBindings:
|
||||
# Start at amber
|
||||
assert app.theme == "fenris-amber"
|
||||
|
||||
# Press t to cycle
|
||||
# Enter drill mode on the graph
|
||||
graph = app.query_one("#usage-history")
|
||||
graph.view_mode = "hourly"
|
||||
graph.drill_day = "2026-09-30"
|
||||
|
||||
# Press t to go back to today
|
||||
await pilot.press("t")
|
||||
await pilot.pause()
|
||||
|
||||
# Should be nord or high_contrast now
|
||||
assert app.theme in ("fenris-nord", "fenris-high-contrast")
|
||||
# Should be back in daily mode
|
||||
assert graph.view_mode == "daily"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_m_toggles_reduced_motion(self, tmp_path):
|
||||
@@ -226,21 +231,23 @@ class TestPersistence:
|
||||
async def test_theme_survives_restart(self, tmp_path):
|
||||
"""Theme preference persists across TUI restart."""
|
||||
from fenris.tui import FenrisTuiApp
|
||||
from fenris.preferences import save_preferences
|
||||
|
||||
config_home = _make_prefs_dir(tmp_path)
|
||||
with patch.dict(os.environ, {"XDG_CONFIG_HOME": str(config_home)}):
|
||||
# First run: change theme
|
||||
# First run: change theme via preferences API
|
||||
app1 = FenrisTuiApp(store_path=tmp_path / "nonexistent.db")
|
||||
async with app1.run_test() as pilot:
|
||||
await pilot.press("t")
|
||||
await pilot.pause()
|
||||
theme_after_t = app1.theme
|
||||
assert theme_after_t != "fenris-amber"
|
||||
save_preferences(theme="nord", reduced_motion=False)
|
||||
app1._current_theme_name = "nord"
|
||||
app1.theme = "fenris-nord"
|
||||
theme_after = app1.theme
|
||||
assert theme_after == "fenris-nord"
|
||||
|
||||
# Second run: theme should persist
|
||||
app2 = FenrisTuiApp(store_path=tmp_path / "nonexistent.db")
|
||||
async with app2.run_test() as pilot:
|
||||
assert app2.theme == theme_after_t
|
||||
assert app2.theme == theme_after
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_reduced_motion_survives_restart(self, tmp_path):
|
||||
|
||||
Reference in New Issue
Block a user