forked from cardosofelipe/fast-next-template
Improved code formatting, line breaks, and indentation across chunking logic and multiple test modules to enhance code clarity and maintain consistent style. No functional changes made.
312 lines
9.9 KiB
Python
312 lines
9.9 KiB
Python
"""Tests for exception classes."""
|
|
|
|
|
|
class TestErrorCode:
|
|
"""Tests for ErrorCode enum."""
|
|
|
|
def test_error_code_values(self):
|
|
"""Test error code values."""
|
|
from exceptions import ErrorCode
|
|
|
|
assert ErrorCode.UNKNOWN_ERROR.value == "KB_UNKNOWN_ERROR"
|
|
assert (
|
|
ErrorCode.DATABASE_CONNECTION_ERROR.value == "KB_DATABASE_CONNECTION_ERROR"
|
|
)
|
|
assert (
|
|
ErrorCode.EMBEDDING_GENERATION_ERROR.value
|
|
== "KB_EMBEDDING_GENERATION_ERROR"
|
|
)
|
|
assert ErrorCode.CHUNKING_ERROR.value == "KB_CHUNKING_ERROR"
|
|
assert ErrorCode.SEARCH_ERROR.value == "KB_SEARCH_ERROR"
|
|
assert ErrorCode.COLLECTION_NOT_FOUND.value == "KB_COLLECTION_NOT_FOUND"
|
|
assert ErrorCode.DOCUMENT_NOT_FOUND.value == "KB_DOCUMENT_NOT_FOUND"
|
|
|
|
|
|
class TestKnowledgeBaseError:
|
|
"""Tests for base exception class."""
|
|
|
|
def test_basic_error(self):
|
|
"""Test basic error creation."""
|
|
from exceptions import ErrorCode, KnowledgeBaseError
|
|
|
|
error = KnowledgeBaseError(
|
|
message="Something went wrong",
|
|
code=ErrorCode.UNKNOWN_ERROR,
|
|
)
|
|
|
|
assert error.message == "Something went wrong"
|
|
assert error.code == ErrorCode.UNKNOWN_ERROR
|
|
assert error.details == {}
|
|
assert error.cause is None
|
|
|
|
def test_error_with_details(self):
|
|
"""Test error with details."""
|
|
from exceptions import ErrorCode, KnowledgeBaseError
|
|
|
|
error = KnowledgeBaseError(
|
|
message="Query failed",
|
|
code=ErrorCode.DATABASE_QUERY_ERROR,
|
|
details={"query": "SELECT * FROM table", "error_code": 42},
|
|
)
|
|
|
|
assert error.details["query"] == "SELECT * FROM table"
|
|
assert error.details["error_code"] == 42
|
|
|
|
def test_error_with_cause(self):
|
|
"""Test error with underlying cause."""
|
|
from exceptions import ErrorCode, KnowledgeBaseError
|
|
|
|
original = ValueError("Original error")
|
|
error = KnowledgeBaseError(
|
|
message="Wrapped error",
|
|
code=ErrorCode.INTERNAL_ERROR,
|
|
cause=original,
|
|
)
|
|
|
|
assert error.cause is original
|
|
assert isinstance(error.cause, ValueError)
|
|
|
|
def test_to_dict(self):
|
|
"""Test to_dict method."""
|
|
from exceptions import ErrorCode, KnowledgeBaseError
|
|
|
|
error = KnowledgeBaseError(
|
|
message="Test error",
|
|
code=ErrorCode.INVALID_REQUEST,
|
|
details={"field": "value"},
|
|
)
|
|
|
|
result = error.to_dict()
|
|
|
|
assert result["error"] == "KB_INVALID_REQUEST"
|
|
assert result["message"] == "Test error"
|
|
assert result["details"]["field"] == "value"
|
|
|
|
def test_str_representation(self):
|
|
"""Test string representation."""
|
|
from exceptions import ErrorCode, KnowledgeBaseError
|
|
|
|
error = KnowledgeBaseError(
|
|
message="Test error",
|
|
code=ErrorCode.INVALID_REQUEST,
|
|
)
|
|
|
|
assert str(error) == "[KB_INVALID_REQUEST] Test error"
|
|
|
|
def test_repr_representation(self):
|
|
"""Test repr representation."""
|
|
from exceptions import ErrorCode, KnowledgeBaseError
|
|
|
|
error = KnowledgeBaseError(
|
|
message="Test error",
|
|
code=ErrorCode.INVALID_REQUEST,
|
|
details={"key": "value"},
|
|
)
|
|
|
|
repr_str = repr(error)
|
|
assert "KnowledgeBaseError" in repr_str
|
|
assert "Test error" in repr_str
|
|
assert "KB_INVALID_REQUEST" in repr_str
|
|
|
|
|
|
class TestDatabaseErrors:
|
|
"""Tests for database-related exceptions."""
|
|
|
|
def test_database_connection_error(self):
|
|
"""Test database connection error."""
|
|
from exceptions import DatabaseConnectionError, ErrorCode
|
|
|
|
error = DatabaseConnectionError(
|
|
message="Cannot connect to database",
|
|
details={"host": "localhost", "port": 5432},
|
|
)
|
|
|
|
assert error.code == ErrorCode.DATABASE_CONNECTION_ERROR
|
|
assert error.details["host"] == "localhost"
|
|
|
|
def test_database_connection_error_default_message(self):
|
|
"""Test database connection error with default message."""
|
|
from exceptions import DatabaseConnectionError
|
|
|
|
error = DatabaseConnectionError()
|
|
|
|
assert error.message == "Failed to connect to database"
|
|
|
|
def test_database_query_error(self):
|
|
"""Test database query error."""
|
|
from exceptions import DatabaseQueryError, ErrorCode
|
|
|
|
error = DatabaseQueryError(
|
|
message="Query failed",
|
|
query="SELECT * FROM missing_table",
|
|
)
|
|
|
|
assert error.code == ErrorCode.DATABASE_QUERY_ERROR
|
|
assert error.details["query"] == "SELECT * FROM missing_table"
|
|
|
|
|
|
class TestEmbeddingErrors:
|
|
"""Tests for embedding-related exceptions."""
|
|
|
|
def test_embedding_generation_error(self):
|
|
"""Test embedding generation error."""
|
|
from exceptions import EmbeddingGenerationError, ErrorCode
|
|
|
|
error = EmbeddingGenerationError(
|
|
message="Failed to generate",
|
|
texts_count=10,
|
|
)
|
|
|
|
assert error.code == ErrorCode.EMBEDDING_GENERATION_ERROR
|
|
assert error.details["texts_count"] == 10
|
|
|
|
def test_embedding_dimension_mismatch(self):
|
|
"""Test embedding dimension mismatch error."""
|
|
from exceptions import EmbeddingDimensionMismatchError, ErrorCode
|
|
|
|
error = EmbeddingDimensionMismatchError(
|
|
expected=1536,
|
|
actual=768,
|
|
)
|
|
|
|
assert error.code == ErrorCode.EMBEDDING_DIMENSION_MISMATCH
|
|
assert "expected 1536" in error.message
|
|
assert "got 768" in error.message
|
|
assert error.details["expected_dimension"] == 1536
|
|
assert error.details["actual_dimension"] == 768
|
|
|
|
|
|
class TestChunkingErrors:
|
|
"""Tests for chunking-related exceptions."""
|
|
|
|
def test_unsupported_file_type_error(self):
|
|
"""Test unsupported file type error."""
|
|
from exceptions import ErrorCode, UnsupportedFileTypeError
|
|
|
|
error = UnsupportedFileTypeError(
|
|
file_type=".xyz",
|
|
supported_types=[".py", ".js", ".md"],
|
|
)
|
|
|
|
assert error.code == ErrorCode.UNSUPPORTED_FILE_TYPE
|
|
assert error.details["file_type"] == ".xyz"
|
|
assert len(error.details["supported_types"]) == 3
|
|
|
|
def test_file_too_large_error(self):
|
|
"""Test file too large error."""
|
|
from exceptions import ErrorCode, FileTooLargeError
|
|
|
|
error = FileTooLargeError(
|
|
file_size=10_000_000,
|
|
max_size=1_000_000,
|
|
)
|
|
|
|
assert error.code == ErrorCode.FILE_TOO_LARGE
|
|
assert error.details["file_size"] == 10_000_000
|
|
assert error.details["max_size"] == 1_000_000
|
|
|
|
def test_encoding_error(self):
|
|
"""Test encoding error."""
|
|
from exceptions import EncodingError, ErrorCode
|
|
|
|
error = EncodingError(
|
|
message="Cannot decode file",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
assert error.code == ErrorCode.ENCODING_ERROR
|
|
assert error.details["encoding"] == "utf-8"
|
|
|
|
|
|
class TestSearchErrors:
|
|
"""Tests for search-related exceptions."""
|
|
|
|
def test_invalid_search_type_error(self):
|
|
"""Test invalid search type error."""
|
|
from exceptions import ErrorCode, InvalidSearchTypeError
|
|
|
|
error = InvalidSearchTypeError(
|
|
search_type="invalid",
|
|
valid_types=["semantic", "keyword", "hybrid"],
|
|
)
|
|
|
|
assert error.code == ErrorCode.INVALID_SEARCH_TYPE
|
|
assert error.details["search_type"] == "invalid"
|
|
assert len(error.details["valid_types"]) == 3
|
|
|
|
def test_search_timeout_error(self):
|
|
"""Test search timeout error."""
|
|
from exceptions import ErrorCode, SearchTimeoutError
|
|
|
|
error = SearchTimeoutError(timeout=30.0)
|
|
|
|
assert error.code == ErrorCode.SEARCH_TIMEOUT
|
|
assert error.details["timeout"] == 30.0
|
|
assert "30" in error.message
|
|
|
|
|
|
class TestCollectionErrors:
|
|
"""Tests for collection-related exceptions."""
|
|
|
|
def test_collection_not_found_error(self):
|
|
"""Test collection not found error."""
|
|
from exceptions import CollectionNotFoundError, ErrorCode
|
|
|
|
error = CollectionNotFoundError(
|
|
collection="missing-collection",
|
|
project_id="proj-123",
|
|
)
|
|
|
|
assert error.code == ErrorCode.COLLECTION_NOT_FOUND
|
|
assert error.details["collection"] == "missing-collection"
|
|
assert error.details["project_id"] == "proj-123"
|
|
|
|
|
|
class TestDocumentErrors:
|
|
"""Tests for document-related exceptions."""
|
|
|
|
def test_document_not_found_error(self):
|
|
"""Test document not found error."""
|
|
from exceptions import DocumentNotFoundError, ErrorCode
|
|
|
|
error = DocumentNotFoundError(
|
|
source_path="/path/to/file.py",
|
|
project_id="proj-123",
|
|
)
|
|
|
|
assert error.code == ErrorCode.DOCUMENT_NOT_FOUND
|
|
assert error.details["source_path"] == "/path/to/file.py"
|
|
|
|
def test_invalid_document_error(self):
|
|
"""Test invalid document error."""
|
|
from exceptions import ErrorCode, InvalidDocumentError
|
|
|
|
error = InvalidDocumentError(
|
|
message="Empty content",
|
|
details={"reason": "no content"},
|
|
)
|
|
|
|
assert error.code == ErrorCode.INVALID_DOCUMENT
|
|
|
|
|
|
class TestProjectErrors:
|
|
"""Tests for project-related exceptions."""
|
|
|
|
def test_project_not_found_error(self):
|
|
"""Test project not found error."""
|
|
from exceptions import ErrorCode, ProjectNotFoundError
|
|
|
|
error = ProjectNotFoundError(project_id="missing-proj")
|
|
|
|
assert error.code == ErrorCode.PROJECT_NOT_FOUND
|
|
assert error.details["project_id"] == "missing-proj"
|
|
|
|
def test_project_access_denied_error(self):
|
|
"""Test project access denied error."""
|
|
from exceptions import ErrorCode, ProjectAccessDeniedError
|
|
|
|
error = ProjectAccessDeniedError(project_id="restricted-proj")
|
|
|
|
assert error.code == ErrorCode.PROJECT_ACCESS_DENIED
|
|
assert "restricted-proj" in error.message
|