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.
This commit is contained in:
108
mnemosyne/library/tests/test_chunker.py
Normal file
108
mnemosyne/library/tests/test_chunker.py
Normal file
@@ -0,0 +1,108 @@
|
||||
"""
|
||||
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)
|
||||
Reference in New Issue
Block a user