File size: 5,173 Bytes
2182a08 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
import pytest
from pathlib import Path
from know_lang_bot.core.types import ChunkType
from tests.test_data.python_files import (
TEST_FILES,
INVALID_SYNTAX,
SIMPLE_FILE_EXPECTATIONS,
NESTED_CLASS_EXPECTATIONS,
COMPLEX_FILE_EXPECTATIONS
)
from know_lang_bot.core.types import CodeChunk
from know_lang_bot.parser.languages.python.parser import PythonParser
from typing import List
import tempfile
def find_chunk_by_criteria(chunks: List[CodeChunk], **criteria) -> CodeChunk:
"""Helper function to find a chunk matching given criteria"""
for chunk in chunks:
if all(getattr(chunk, k) == v for k, v in criteria.items()):
return chunk
return None
def verify_chunk_matches_expectation(
chunk: CodeChunk,
expected_name: str,
expected_docstring: str,
expected_content_snippet: str
) -> bool:
"""Verify that a chunk matches expected values"""
return (
chunk.name == expected_name and
expected_content_snippet in chunk.content and
chunk.docstring is not None and
expected_docstring in chunk.docstring
)
class TestPythonParser:
"""Test suite for PythonParser"""
def test_parser_initialization(self, python_parser: PythonParser):
"""Test parser initialization"""
assert python_parser.parser is not None
assert python_parser.language is not None
def test_simple_file_parsing(self, python_parser: PythonParser, temp_repo: tempfile.TemporaryDirectory):
"""Test parsing a simple Python file with function and class"""
chunks = python_parser.parse_file(Path(temp_repo) / "simple.py")
# Test function
function_chunk = find_chunk_by_criteria(
chunks,
type=ChunkType.FUNCTION,
name="hello_world"
)
assert function_chunk is not None
expected = SIMPLE_FILE_EXPECTATIONS['hello_world']
assert verify_chunk_matches_expectation(
function_chunk,
expected.name,
expected.docstring,
expected.content_snippet
)
# Test class
class_chunk = find_chunk_by_criteria(
chunks,
type=ChunkType.CLASS,
name="SimpleClass"
)
assert class_chunk is not None
expected = SIMPLE_FILE_EXPECTATIONS['SimpleClass']
assert verify_chunk_matches_expectation(
class_chunk,
expected.name,
expected.docstring,
expected.content_snippet
)
def test_complex_file_parsing(self, python_parser: PythonParser, temp_repo: tempfile.TemporaryDirectory):
"""Test parsing a complex Python file"""
chunks = python_parser.parse_file(Path(temp_repo) / "complex.py")
# Test complex function
complex_func = find_chunk_by_criteria(
chunks,
type=ChunkType.FUNCTION,
name="complex_function"
)
assert complex_func is not None
expected = COMPLEX_FILE_EXPECTATIONS['complex_function']
assert verify_chunk_matches_expectation(
complex_func,
expected.name,
expected.docstring,
expected.content_snippet
)
# Test complex class
complex_class = find_chunk_by_criteria(
chunks,
type=ChunkType.CLASS,
name="ComplexClass"
)
assert complex_class is not None
expected = COMPLEX_FILE_EXPECTATIONS['ComplexClass']
assert verify_chunk_matches_expectation(
complex_class,
expected.name,
expected.docstring,
expected.content_snippet
)
def test_error_handling(self, python_parser: PythonParser, temp_repo: tempfile.TemporaryDirectory):
"""Test error handling for various error cases"""
# Test invalid syntax
invalid_file = Path(temp_repo) / "invalid.py"
invalid_file.write_text(INVALID_SYNTAX)
chunks = python_parser.parse_file(invalid_file)
assert chunks == []
# Test non-existent file
nonexistent = Path(temp_repo) / "nonexistent.py"
chunks = python_parser.parse_file(nonexistent)
assert chunks == []
# Test non-Python file
non_python = Path(temp_repo) / "readme.md"
non_python.write_text("# README")
chunks = python_parser.parse_file(non_python)
assert chunks == []
def test_file_size_limits(self, python_parser: PythonParser, temp_repo: tempfile.TemporaryDirectory):
"""Test file size limit enforcement"""
large_file = Path(temp_repo) / "large.py"
# Create a file larger than the limit
large_file.write_text("x = 1\n" * 1_000_000)
chunks = python_parser.parse_file(large_file)
assert chunks == []
@pytest.mark.parametrize("test_file", TEST_FILES.keys())
def test_supported_extensions(self, python_parser: PythonParser, test_file: str):
"""Test file extension support"""
assert any(test_file.endswith(ext) for ext in python_parser.language_config.file_extensions)
|