Files
Bolt-Pet/tests/test_history_and_hotkey.py
themajesticmagician 80bef6f524 Upload
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-23 06:25:41 -06:00

93 lines
3.1 KiB
Python

"""Conversation scrollback + push-to-talk hotkey parsing."""
import sys
from pathlib import Path
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from bolt_pet import history as history_mod
from bolt_pet.hotkey import GlobalHotkey, HotkeyError, to_pynput_spec
# ── history ─────────────────────────────────────────────────────────────────
def test_keeps_entries_in_order():
log = history_mod.ConversationHistory(limit=10)
log.add(history_mod.USER, "what's the weather")
log.add(history_mod.PET, "sunny and 72")
assert [e.text for e in log.entries()] == ["what's the weather", "sunny and 72"]
def test_drops_the_oldest_past_the_limit():
log = history_mod.ConversationHistory(limit=2)
for i in range(5):
log.add(history_mod.PET, f"line {i}")
assert [e.text for e in log.entries()] == ["line 3", "line 4"]
def test_blank_entries_are_ignored():
log = history_mod.ConversationHistory()
assert log.add(history_mod.PET, " ") is None
assert len(log) == 0
def test_last_can_filter_by_role():
log = history_mod.ConversationHistory()
log.add(history_mod.USER, "hello")
log.add(history_mod.PET, "hi there")
log.add(history_mod.USER, "still there?")
assert log.last().text == "still there?"
assert log.last(history_mod.PET).text == "hi there"
def test_as_text_is_copyable_transcript():
log = history_mod.ConversationHistory()
log.add(history_mod.USER, "ping")
log.add(history_mod.PET, "pong")
assert log.as_text() == "You: ping\nBolt: pong"
def test_timestamps_are_rendered_when_present():
log = history_mod.ConversationHistory()
log.add(history_mod.PET, "pong", timestamp=1710000000.0)
assert log.as_text(clock=lambda t: "12:00:00") == "[12:00:00] Bolt: pong"
def test_clear_empties_the_log():
log = history_mod.ConversationHistory()
log.add(history_mod.PET, "pong")
log.clear()
assert len(log) == 0
# ── hotkey ──────────────────────────────────────────────────────────────────
def test_translates_a_readable_spec_to_pynput_syntax():
assert to_pynput_spec("ctrl+alt+space") == "<ctrl>+<alt>+<space>"
assert to_pynput_spec("ctrl+shift+b") == "<ctrl>+<shift>+b"
def test_accepts_the_names_people_actually_type():
assert to_pynput_spec("Control+Option+Space") == "<ctrl>+<alt>+<space>"
assert to_pynput_spec("super+k") == "<cmd>+k"
def test_empty_spec_is_an_error_at_parse_time():
with pytest.raises(HotkeyError):
to_pynput_spec("")
def test_disabled_hotkey_starts_cleanly_and_reports_nothing():
hotkey = GlobalHotkey("", lambda: None)
assert hotkey.start() is None
assert hotkey.running is False
def test_invalid_hotkey_reports_instead_of_raising():
hotkey = GlobalHotkey("+++", lambda: None)
problem = hotkey.start()
assert problem and "invalid" in problem
assert hotkey.running is False