Skip to content

Commit 6639e94

Browse files
committed
Add first pass of unit tests for the local persona loader.
1 parent 5fd3508 commit 6639e94

File tree

1 file changed

+77
-0
lines changed

1 file changed

+77
-0
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""
2+
Test the local persona manager.
3+
"""
4+
5+
import pytest
6+
import tempfile
7+
from pathlib import Path
8+
9+
from jupyter_ai.personas.base_persona import BasePersona, PersonaDefaults
10+
from jupyter_ai.personas.persona_manager import LocalPersonaLoader
11+
12+
13+
@pytest.fixture
14+
def tmp_persona_dir():
15+
"""Create a temporary directory for testing LocalPersonaLoader with guaranteed cleanup."""
16+
with tempfile.TemporaryDirectory() as temp_dir:
17+
yield Path(temp_dir)
18+
19+
20+
class TestLocalPersonaLoader:
21+
"""Test cases for LocalPersonaLoader class."""
22+
23+
def test_empty_directory_returns_empty_list(self, tmp_persona_dir):
24+
"""Test that an empty directory returns an empty list of persona classes."""
25+
loader = LocalPersonaLoader(root_dir=str(tmp_persona_dir))
26+
result = loader.load_persona_classes()
27+
assert result == []
28+
29+
def test_non_persona_file_returns_empty_list(self, tmp_persona_dir):
30+
"""Test that a Python file without persona classes returns an empty list."""
31+
# Create a file that doesn't contain "persona" in the name
32+
non_persona_file = tmp_persona_dir / "no_personas.py"
33+
non_persona_file.write_text("pass")
34+
35+
loader = LocalPersonaLoader(root_dir=str(tmp_persona_dir))
36+
result = loader.load_persona_classes()
37+
assert result == []
38+
39+
def test_simple_persona_file_returns_persona_class(self, tmp_persona_dir):
40+
"""Test that a file with a BasePersona subclass returns that class."""
41+
# Create a simple persona file
42+
persona_file = tmp_persona_dir / "simple_personas.py"
43+
persona_content = '''
44+
from jupyter_ai.personas.base_persona import BasePersona
45+
46+
class TestPersona(BasePersona):
47+
id = "test_persona"
48+
name = "Test Persona"
49+
description = "A simple test persona"
50+
51+
def process_message(self, message):
52+
pass
53+
'''
54+
persona_file.write_text(persona_content)
55+
56+
loader = LocalPersonaLoader(root_dir=str(tmp_persona_dir))
57+
result = loader.load_persona_classes()
58+
59+
assert len(result) == 1
60+
assert result[0].__name__ == "TestPersona"
61+
assert issubclass(result[0], BasePersona)
62+
63+
def test_bad_persona_file_logs_exception_returns_empty_list(self, tmp_persona_dir, caplog):
64+
"""Test that a file with syntax errors logs an exception and returns empty list."""
65+
# Create a file with invalid Python code
66+
bad_persona_file = tmp_persona_dir / "bad_persona.py"
67+
bad_persona_file.write_text("1/0")
68+
69+
loader = LocalPersonaLoader(root_dir=str(tmp_persona_dir))
70+
result = loader.load_persona_classes()
71+
72+
assert result == []
73+
# Check that an error was logged
74+
assert any("Unable to load persona classes from" in record.message
75+
for record in caplog.records if record.levelname in ["ERROR", "EXCEPTION"])
76+
77+

0 commit comments

Comments
 (0)