95 lines
3.1 KiB
Python
95 lines
3.1 KiB
Python
"""Activity-selection transitions independent from Textual widgets."""
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
|
|
|
from fenris.activity_selection import ActivitySelection, IntervalIdentity
|
|
|
|
|
|
def _interval(n):
|
|
return IntervalIdentity(f"start-{n}", f"end-{n}")
|
|
|
|
|
|
def test_live_selection_starts_and_stays_on_newest_interval():
|
|
selection = ActivitySelection()
|
|
first = [_interval(1), _interval(2)]
|
|
|
|
selection.update_live(first)
|
|
assert selection.following_live
|
|
assert selection.selected_live_interval == first[-1]
|
|
|
|
second = first + [_interval(3)]
|
|
selection.update_live(second)
|
|
assert selection.selected_live_interval == second[-1]
|
|
|
|
|
|
def test_keyboard_and_mouse_inspection_pin_interval_identity():
|
|
intervals = [_interval(1), _interval(2), _interval(3)]
|
|
keyboard = ActivitySelection()
|
|
mouse = ActivitySelection()
|
|
|
|
keyboard.update_live(intervals)
|
|
keyboard.move_live(intervals, -1)
|
|
mouse.update_live(intervals)
|
|
mouse.inspect_live(intervals, intervals[1])
|
|
|
|
assert keyboard.selected_live_interval == mouse.selected_live_interval == intervals[1]
|
|
assert not keyboard.following_live
|
|
assert not mouse.following_live
|
|
|
|
refreshed = [_interval(2), _interval(3), _interval(4)]
|
|
keyboard.update_live(refreshed)
|
|
mouse.update_live(refreshed)
|
|
assert keyboard.selected_live_interval == mouse.selected_live_interval == intervals[1]
|
|
|
|
|
|
def test_expired_pin_explains_expiration_and_resumes_following():
|
|
selection = ActivitySelection()
|
|
intervals = [_interval(1), _interval(2), _interval(3)]
|
|
selection.update_live(intervals)
|
|
selection.inspect_live(intervals, intervals[0])
|
|
|
|
newest = _interval(4)
|
|
selection.update_live([_interval(2), _interval(3), newest])
|
|
|
|
assert selection.following_live
|
|
assert selection.selected_live_interval == newest
|
|
assert selection.live_interval_expired
|
|
|
|
|
|
def test_today_resets_expired_pin_and_read_write_toggle_keeps_identity():
|
|
selection = ActivitySelection()
|
|
intervals = [_interval(1), _interval(2)]
|
|
selection.update_live(intervals)
|
|
selection.inspect_live(intervals, intervals[0])
|
|
selection.update_live([intervals[1]])
|
|
newest = _interval(3)
|
|
selection.update_live([intervals[1], newest])
|
|
assert selection.live_interval_expired
|
|
|
|
selection.toggle_measure()
|
|
assert selection.measure == "read"
|
|
assert selection.selected_live_interval == newest
|
|
|
|
selection.select_history_date("2026-09-27")
|
|
selection.set_view("history")
|
|
selection.set_view("live")
|
|
assert selection.browse_date is None
|
|
assert selection.following_live
|
|
assert not selection.live_interval_expired
|
|
|
|
|
|
def test_live_identity_uses_both_interval_boundaries():
|
|
first = IntervalIdentity("2026-09-28T10:00:00Z", "2026-09-28T10:03:00Z")
|
|
changed_start = IntervalIdentity("2026-09-28T09:57:00Z", "2026-09-28T10:03:00Z")
|
|
selection = ActivitySelection()
|
|
selection.update_live([first])
|
|
selection.inspect_live([first], first)
|
|
|
|
selection.update_live([changed_start])
|
|
|
|
assert selection.following_live
|
|
assert selection.selected_live_interval == changed_start
|
|
assert selection.live_interval_expired
|