Files
mnemosyne/mnemosyne/library/tests/test_chunker.py
Robert Helewka 99bdb4ac92 Add Themis application with custom widgets, views, and utilities
- Implemented custom form widgets for date, time, and datetime fields with DaisyUI styling.
- Created utility functions for formatting dates, times, and numbers according to user preferences.
- Developed views for profile settings, API key management, and notifications, including health check endpoints.
- Added URL configurations for Themis tests and main application routes.
- Established test cases for custom widgets to ensure proper functionality and integration.
- Defined project metadata and dependencies in pyproject.toml for package management.
2026-03-21 02:00:18 +00:00

109 lines
4.1 KiB
Python

"""
Tests for the content-type-aware chunking service.
"""
from unittest.mock import MagicMock, patch
from django.test import TestCase
from library.services.chunker import ChunkResult, ContentTypeChunker
from library.services.parsers import ParseResult, TextBlock
class ChunkResultTests(TestCase):
"""Tests for ChunkResult dataclass."""
def test_len(self):
result = ChunkResult(chunks=["a", "b", "c"], chunk_page_map={}, strategy="test")
self.assertEqual(len(result), 3)
def test_empty(self):
result = ChunkResult(chunks=[], chunk_page_map={}, strategy="test")
self.assertEqual(len(result), 0)
class ContentTypeChunkerTests(TestCase):
"""Tests for ContentTypeChunker."""
def _make_parse_result(self, text: str, pages: int = 1) -> ParseResult:
"""Helper to create a ParseResult with text blocks."""
blocks = []
if pages == 1:
blocks = [TextBlock(text=text, page=0)]
else:
chunk_size = len(text) // pages
for i in range(pages):
start = i * chunk_size
end = start + chunk_size if i < pages - 1 else len(text)
blocks.append(TextBlock(text=text[start:end], page=i))
return ParseResult(text_blocks=blocks, images=[], metadata={}, file_type="txt")
@patch("library.services.chunker.ContentTypeChunker._get_splitter")
def test_chunk_dispatches_strategy(self, mock_splitter):
"""Chunker uses the strategy from config."""
mock_instance = MagicMock()
mock_instance.chunks.return_value = ["chunk1", "chunk2"]
mock_splitter.return_value = mock_instance
chunker = ContentTypeChunker()
parse_result = self._make_parse_result("Some text to chunk into pieces")
config = {"strategy": "chapter_aware", "chunk_size": 512, "chunk_overlap": 64}
result = chunker.chunk(parse_result, config, library_type="fiction")
self.assertIsInstance(result, ChunkResult)
self.assertEqual(result.strategy, "chapter_aware")
self.assertEqual(len(result.chunks), 2)
mock_splitter.assert_called_once_with(512, 64)
@patch("library.services.chunker.ContentTypeChunker._get_splitter")
def test_empty_text_returns_empty(self, mock_splitter):
"""Empty text produces no chunks."""
chunker = ContentTypeChunker()
parse_result = ParseResult(text_blocks=[], images=[], metadata={}, file_type="txt")
config = {"strategy": "section_aware", "chunk_size": 512, "chunk_overlap": 64}
result = chunker.chunk(parse_result, config)
self.assertEqual(len(result), 0)
mock_splitter.assert_not_called()
@patch("library.services.chunker.ContentTypeChunker._get_splitter")
def test_default_config_values(self, mock_splitter):
"""Missing config keys use defaults."""
mock_instance = MagicMock()
mock_instance.chunks.return_value = ["chunk"]
mock_splitter.return_value = mock_instance
chunker = ContentTypeChunker()
parse_result = self._make_parse_result("Text")
result = chunker.chunk(parse_result, {})
# Default: strategy=section_aware, chunk_size=512, overlap=64
self.assertEqual(result.strategy, "section_aware")
mock_splitter.assert_called_once_with(512, 64)
@patch("library.services.chunker.ContentTypeChunker._get_splitter")
def test_page_mapping(self, mock_splitter):
"""Chunks are mapped to their source pages."""
mock_instance = MagicMock()
mock_instance.chunks.return_value = ["Page 0 text", "Page 1 text"]
mock_splitter.return_value = mock_instance
chunker = ContentTypeChunker()
parse_result = ParseResult(
text_blocks=[
TextBlock(text="Page 0 text content", page=0),
TextBlock(text="Page 1 text content", page=1),
],
images=[],
metadata={},
file_type="pdf",
)
config = {"strategy": "section_aware", "chunk_size": 512, "chunk_overlap": 64}
result = chunker.chunk(parse_result, config)
self.assertIn(0, result.chunk_page_map)