Co-authored-by: Kimi Agent <kimi@timmy.local> Co-committed-by: Kimi Agent <kimi@timmy.local>
114 lines
3.7 KiB
Python
114 lines
3.7 KiB
Python
"""Tests for timmy.focus — deep focus mode state management."""
|
|
|
|
import json
|
|
|
|
import pytest
|
|
|
|
|
|
@pytest.fixture
|
|
def focus_mgr(tmp_path):
|
|
"""Create a FocusManager with a temporary state directory."""
|
|
from timmy.focus import FocusManager
|
|
|
|
return FocusManager(state_dir=tmp_path)
|
|
|
|
|
|
class TestFocusManager:
|
|
"""Unit tests for FocusManager."""
|
|
|
|
def test_default_state_is_broad(self, focus_mgr):
|
|
assert focus_mgr.get_mode() == "broad"
|
|
assert focus_mgr.get_topic() is None
|
|
assert not focus_mgr.is_focused()
|
|
|
|
def test_set_topic_activates_deep_focus(self, focus_mgr):
|
|
focus_mgr.set_topic("three-phase loop")
|
|
assert focus_mgr.get_topic() == "three-phase loop"
|
|
assert focus_mgr.get_mode() == "deep"
|
|
assert focus_mgr.is_focused()
|
|
|
|
def test_clear_returns_to_broad(self, focus_mgr):
|
|
focus_mgr.set_topic("bitcoin strategy")
|
|
focus_mgr.clear()
|
|
assert focus_mgr.get_topic() is None
|
|
assert focus_mgr.get_mode() == "broad"
|
|
assert not focus_mgr.is_focused()
|
|
|
|
def test_topic_strips_whitespace(self, focus_mgr):
|
|
focus_mgr.set_topic(" padded topic ")
|
|
assert focus_mgr.get_topic() == "padded topic"
|
|
|
|
def test_focus_context_when_focused(self, focus_mgr):
|
|
focus_mgr.set_topic("memory architecture")
|
|
ctx = focus_mgr.get_focus_context()
|
|
assert "DEEP FOCUS MODE" in ctx
|
|
assert "memory architecture" in ctx
|
|
|
|
def test_focus_context_when_broad(self, focus_mgr):
|
|
assert focus_mgr.get_focus_context() == ""
|
|
|
|
def test_persistence_across_instances(self, tmp_path):
|
|
from timmy.focus import FocusManager
|
|
|
|
mgr1 = FocusManager(state_dir=tmp_path)
|
|
mgr1.set_topic("persistent problem")
|
|
|
|
# New instance should load persisted state
|
|
mgr2 = FocusManager(state_dir=tmp_path)
|
|
assert mgr2.get_topic() == "persistent problem"
|
|
assert mgr2.is_focused()
|
|
|
|
def test_clear_persists(self, tmp_path):
|
|
from timmy.focus import FocusManager
|
|
|
|
mgr1 = FocusManager(state_dir=tmp_path)
|
|
mgr1.set_topic("will be cleared")
|
|
mgr1.clear()
|
|
|
|
mgr2 = FocusManager(state_dir=tmp_path)
|
|
assert not mgr2.is_focused()
|
|
assert mgr2.get_topic() is None
|
|
|
|
def test_state_file_is_valid_json(self, tmp_path, focus_mgr):
|
|
focus_mgr.set_topic("json check")
|
|
state_file = tmp_path / "focus.json"
|
|
assert state_file.exists()
|
|
data = json.loads(state_file.read_text())
|
|
assert data["topic"] == "json check"
|
|
assert data["mode"] == "deep"
|
|
|
|
def test_missing_state_file_is_fine(self, tmp_path):
|
|
"""FocusManager gracefully handles missing state file."""
|
|
from timmy.focus import FocusManager
|
|
|
|
mgr = FocusManager(state_dir=tmp_path / "nonexistent")
|
|
assert not mgr.is_focused()
|
|
|
|
|
|
class TestPrependFocusContext:
|
|
"""Tests for the session-level focus injection helper."""
|
|
|
|
def test_no_injection_when_unfocused(self, tmp_path, monkeypatch):
|
|
from timmy.focus import FocusManager
|
|
|
|
mgr = FocusManager(state_dir=tmp_path)
|
|
monkeypatch.setattr("timmy.focus.focus_manager", mgr)
|
|
|
|
from timmy.session import _prepend_focus_context
|
|
|
|
assert _prepend_focus_context("hello") == "hello"
|
|
|
|
def test_injection_when_focused(self, tmp_path, monkeypatch):
|
|
from timmy.focus import FocusManager
|
|
|
|
mgr = FocusManager(state_dir=tmp_path)
|
|
mgr.set_topic("test topic")
|
|
monkeypatch.setattr("timmy.focus.focus_manager", mgr)
|
|
|
|
from timmy.session import _prepend_focus_context
|
|
|
|
result = _prepend_focus_context("hello")
|
|
assert "DEEP FOCUS MODE" in result
|
|
assert "test topic" in result
|
|
assert result.endswith("hello")
|