Upload
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user