PlanOpticon

planopticon / tests / test_companion.py
Blame History Raw 163 lines
1
"""Tests for the CompanionREPL (without launching the loop)."""
2
3
from unittest.mock import patch
4
5
from video_processor.cli.companion import CompanionREPL
6
7
8
class TestImport:
9
def test_import(self):
10
from video_processor.cli import companion # noqa: F401
11
12
assert hasattr(companion, "CompanionREPL")
13
14
15
class TestConstructor:
16
def test_defaults(self):
17
repl = CompanionREPL()
18
assert repl.kg is None
19
assert repl.query_engine is None
20
assert repl.agent is None
21
assert repl.provider_manager is None
22
23
def test_explicit_args(self):
24
repl = CompanionREPL(
25
kb_paths=["/tmp/fake.db"],
26
provider="openai",
27
chat_model="gpt-4",
28
)
29
assert repl._kb_paths == ["/tmp/fake.db"]
30
assert repl._provider_name == "openai"
31
assert repl._chat_model == "gpt-4"
32
33
34
class TestAutoDiscovery:
35
@patch(
36
"video_processor.integrators.graph_discovery.find_nearest_graph",
37
return_value=None,
38
)
39
def test_no_graph_found(self, mock_find):
40
repl = CompanionREPL()
41
repl._discover()
42
assert repl.query_engine is None
43
assert repl.kg is None
44
mock_find.assert_called_once()
45
46
47
class TestHandleHelp:
48
def test_handle_help(self):
49
repl = CompanionREPL()
50
output = repl.handle_input("/help")
51
assert "Available commands" in output
52
assert "/status" in output
53
assert "/skills" in output
54
assert "/entities" in output
55
assert "/quit" in output
56
57
58
class TestHandleStatus:
59
def test_handle_status_no_kg(self):
60
repl = CompanionREPL()
61
output = repl.handle_input("/status")
62
assert "Workspace status" in output
63
assert "not loaded" in output
64
65
66
class TestHandleSkills:
67
def test_handle_skills(self):
68
repl = CompanionREPL()
69
output = repl.handle_input("/skills")
70
# Either lists skills or says none registered
71
assert "skills" in output.lower() or "No skills" in output
72
73
74
class TestHandleQuit:
75
def test_quit(self):
76
repl = CompanionREPL()
77
assert repl.handle_input("/quit") == "__QUIT__"
78
79
def test_exit(self):
80
repl = CompanionREPL()
81
assert repl.handle_input("/exit") == "__QUIT__"
82
83
def test_bare_quit(self):
84
repl = CompanionREPL()
85
assert repl.handle_input("quit") == "__QUIT__"
86
87
def test_bare_exit(self):
88
repl = CompanionREPL()
89
assert repl.handle_input("exit") == "__QUIT__"
90
91
def test_bare_bye(self):
92
repl = CompanionREPL()
93
assert repl.handle_input("bye") == "__QUIT__"
94
95
def test_bare_q(self):
96
repl = CompanionREPL()
97
assert repl.handle_input("q") == "__QUIT__"
98
99
100
class TestHandleUnknownSlash:
101
def test_unknown_command(self):
102
repl = CompanionREPL()
103
output = repl.handle_input("/foobar")
104
assert "Unknown command" in output
105
assert "/help" in output
106
107
108
class TestHandleChatNoProvider:
109
def test_chat_no_provider(self):
110
repl = CompanionREPL()
111
output = repl.handle_input("What is this project about?")
112
assert "LLM provider" in output or "API" in output
113
# Should not crash
114
115
116
class TestHandleEntitiesNoKG:
117
def test_entities_no_kg(self):
118
repl = CompanionREPL()
119
output = repl.handle_input("/entities")
120
assert "No knowledge graph loaded" in output
121
122
def test_search_no_kg(self):
123
repl = CompanionREPL()
124
output = repl.handle_input("/search python")
125
assert "No knowledge graph loaded" in output
126
127
def test_neighbors_no_kg(self):
128
repl = CompanionREPL()
129
output = repl.handle_input("/neighbors Alice")
130
assert "No knowledge graph loaded" in output
131
132
133
class TestProviderCommand:
134
def test_provider_list(self):
135
repl = CompanionREPL()
136
output = repl.handle_input("/provider")
137
assert "Available providers" in output
138
assert "openai" in output
139
assert "anthropic" in output
140
141
def test_provider_switch(self):
142
repl = CompanionREPL()
143
output = repl.handle_input("/provider openai")
144
# Will fail to init without key, but shouldn't crash
145
assert "openai" in output.lower()
146
147
def test_model_show(self):
148
repl = CompanionREPL()
149
output = repl.handle_input("/model")
150
assert "Current model" in output
151
152
def test_model_switch(self):
153
repl = CompanionREPL()
154
output = repl.handle_input("/model gpt-4o")
155
# Will fail without provider, but shouldn't crash
156
assert "gpt-4o" in output
157
158
def test_help_includes_provider(self):
159
repl = CompanionREPL()
160
output = repl.handle_input("/help")
161
assert "/provider" in output
162
assert "/model" in output
163

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button