unittest summarizer
Browse files- .gitignore +3 -1
- poetry.lock +20 -1
- pyproject.toml +1 -0
- tests/test_summarizer.py +86 -0
.gitignore
CHANGED
@@ -2,4 +2,6 @@
|
|
2 |
__pycache__
|
3 |
.pytest_cache
|
4 |
.env*
|
5 |
-
!.env.example
|
|
|
|
|
|
2 |
__pycache__
|
3 |
.pytest_cache
|
4 |
.env*
|
5 |
+
!.env.example
|
6 |
+
|
7 |
+
my_chroma_db
|
poetry.lock
CHANGED
@@ -2239,6 +2239,25 @@ tomli = {version = ">=1", markers = "python_version < \"3.11\""}
|
|
2239 |
[package.extras]
|
2240 |
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
2241 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2242 |
[[package]]
|
2243 |
name = "python-dateutil"
|
2244 |
version = "2.9.0.post0"
|
@@ -3121,4 +3140,4 @@ type = ["pytest-mypy"]
|
|
3121 |
[metadata]
|
3122 |
lock-version = "2.1"
|
3123 |
python-versions = ">=3.10, <4.0"
|
3124 |
-
content-hash = "
|
|
|
2239 |
[package.extras]
|
2240 |
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
2241 |
|
2242 |
+
[[package]]
|
2243 |
+
name = "pytest-asyncio"
|
2244 |
+
version = "0.25.2"
|
2245 |
+
description = "Pytest support for asyncio"
|
2246 |
+
optional = false
|
2247 |
+
python-versions = ">=3.9"
|
2248 |
+
groups = ["dev"]
|
2249 |
+
files = [
|
2250 |
+
{file = "pytest_asyncio-0.25.2-py3-none-any.whl", hash = "sha256:0d0bb693f7b99da304a0634afc0a4b19e49d5e0de2d670f38dc4bfa5727c5075"},
|
2251 |
+
{file = "pytest_asyncio-0.25.2.tar.gz", hash = "sha256:3f8ef9a98f45948ea91a0ed3dc4268b5326c0e7bce73892acc654df4262ad45f"},
|
2252 |
+
]
|
2253 |
+
|
2254 |
+
[package.dependencies]
|
2255 |
+
pytest = ">=8.2,<9"
|
2256 |
+
|
2257 |
+
[package.extras]
|
2258 |
+
docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1)"]
|
2259 |
+
testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"]
|
2260 |
+
|
2261 |
[[package]]
|
2262 |
name = "python-dateutil"
|
2263 |
version = "2.9.0.post0"
|
|
|
3140 |
[metadata]
|
3141 |
lock-version = "2.1"
|
3142 |
python-versions = ">=3.10, <4.0"
|
3143 |
+
content-hash = "e832a3ea167213ca280f213201124d535205b11ddadd8f4affbbdf0431a78906"
|
pyproject.toml
CHANGED
@@ -28,6 +28,7 @@ packages = [
|
|
28 |
|
29 |
[tool.poetry.group.dev.dependencies]
|
30 |
pytest = "^8.3.4"
|
|
|
31 |
|
32 |
[build-system]
|
33 |
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
|
28 |
|
29 |
[tool.poetry.group.dev.dependencies]
|
30 |
pytest = "^8.3.4"
|
31 |
+
pytest-asyncio = "^0.25.2"
|
32 |
|
33 |
[build-system]
|
34 |
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
tests/test_summarizer.py
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pytest
|
2 |
+
import tempfile
|
3 |
+
from unittest.mock import Mock, patch, AsyncMock
|
4 |
+
from pathlib import Path
|
5 |
+
from pydantic_ai import Agent
|
6 |
+
from know_lang_bot.code_parser.summarizer import CodeSummarizer
|
7 |
+
from know_lang_bot.code_parser.parser import CodeChunk, ChunkType
|
8 |
+
from know_lang_bot.config import AppConfig
|
9 |
+
|
10 |
+
@pytest.fixture
|
11 |
+
def config():
|
12 |
+
"""Create a test configuration"""
|
13 |
+
with tempfile.TemporaryDirectory() as temp_dir:
|
14 |
+
yield AppConfig(
|
15 |
+
llm={"model_name": "test-model", "model_provider": "test"},
|
16 |
+
db={"persist_directory": Path(temp_dir), "collection_name": "test_collection"}
|
17 |
+
)
|
18 |
+
|
19 |
+
@pytest.fixture
|
20 |
+
def sample_chunks():
|
21 |
+
"""Create sample code chunks for testing"""
|
22 |
+
return [
|
23 |
+
CodeChunk(
|
24 |
+
type=ChunkType.FUNCTION,
|
25 |
+
content="def hello(): return 'world'",
|
26 |
+
start_line=1,
|
27 |
+
end_line=2,
|
28 |
+
file_path="test.py",
|
29 |
+
name="hello",
|
30 |
+
docstring="Says hello"
|
31 |
+
),
|
32 |
+
CodeChunk(
|
33 |
+
type=ChunkType.CLASS,
|
34 |
+
content="class TestClass:\n def __init__(self):\n pass",
|
35 |
+
start_line=4,
|
36 |
+
end_line=6,
|
37 |
+
file_path="test.py",
|
38 |
+
name="TestClass",
|
39 |
+
docstring="A test class"
|
40 |
+
)
|
41 |
+
]
|
42 |
+
|
43 |
+
@pytest.fixture
|
44 |
+
def mock_summary():
|
45 |
+
"""Create a sample summary result"""
|
46 |
+
return "This is a test function"
|
47 |
+
|
48 |
+
@pytest.fixture
|
49 |
+
def mock_run_result(mock_summary):
|
50 |
+
"""Create a mock run result"""
|
51 |
+
mock_result = Mock()
|
52 |
+
mock_result.data = mock_summary
|
53 |
+
return mock_result
|
54 |
+
|
55 |
+
@pytest.mark.asyncio
|
56 |
+
@patch('know_lang_bot.code_parser.summarizer.Agent')
|
57 |
+
async def test_summarize_chunk(mock_agent_class, config: AppConfig, sample_chunks: list[CodeChunk], mock_run_result: Mock):
|
58 |
+
"""Test summarizing a single chunk"""
|
59 |
+
# Setup the mock agent instance
|
60 |
+
mock_agent = mock_agent_class.return_value
|
61 |
+
mock_agent.run = AsyncMock(return_value=mock_run_result)
|
62 |
+
|
63 |
+
summarizer = CodeSummarizer(config)
|
64 |
+
result = await summarizer.summarize_chunk(sample_chunks[0])
|
65 |
+
|
66 |
+
# Verify result
|
67 |
+
assert isinstance(result, str)
|
68 |
+
assert result == mock_run_result.data
|
69 |
+
|
70 |
+
# Verify agent was called with correct prompt
|
71 |
+
call_args = mock_agent.run.call_args[0][0]
|
72 |
+
assert "def hello()" in call_args
|
73 |
+
assert "Says hello" in call_args
|
74 |
+
|
75 |
+
@patch('know_lang_bot.code_parser.summarizer.Agent')
|
76 |
+
def test_chromadb_initialization(mock_agent_class, config: AppConfig):
|
77 |
+
"""Test ChromaDB initialization"""
|
78 |
+
mock_agent = mock_agent_class.return_value
|
79 |
+
|
80 |
+
summarizer = CodeSummarizer(config)
|
81 |
+
assert summarizer.collection is not None
|
82 |
+
|
83 |
+
# Verify we can create a new collection
|
84 |
+
summarizer.db_client.delete_collection(config.db.collection_name)
|
85 |
+
new_summarizer = CodeSummarizer(config)
|
86 |
+
assert new_summarizer.collection is not None
|