test: tests for apply_overrides, LLM mode, usage_counter, chunk_groups

This commit is contained in:
Artem Akymenko
2026-07-24 19:17:38 +03:00
parent c79838a5a1
commit 332934c0cf
2 changed files with 89 additions and 0 deletions
+65
View File
@@ -245,6 +245,71 @@ class TestConversionService:
log_messages = [msg for msg, _ in events.logs]
assert any("Conversion failed" in msg for msg in log_messages)
def test_tts_context_applies_normalization_overrides(self):
"""Service applies normalization_overrides from request to apostrophe config."""
from abogen.application.conversion_service import run_conversion
with tempfile.TemporaryDirectory() as tmpdir:
from abogen.application.conversion_config import PronunciationConfig
req = ConversionRequest(
direct_text="Hello",
voice="M1",
save_mode="custom_folder",
output_folder=Path(tmpdir),
pronunciation=PronunciationConfig(
normalization_overrides={"normalization_numbers": False},
),
)
events = FakeEvents()
pipeline = FakePipelineProvider()
resolver = FakeVoiceResolver()
result = run_conversion(req, events, pipeline, resolver)
assert result is not None
def test_tts_context_rejects_unconfigured_llm_mode(self):
"""Service raises RuntimeError if LLM apostrophe mode is selected but unconfigured."""
from abogen.application.conversion_service import run_conversion
with tempfile.TemporaryDirectory() as tmpdir:
from abogen.application.conversion_config import PronunciationConfig
req = ConversionRequest(
direct_text="Hello",
voice="M1",
save_mode="custom_folder",
output_folder=Path(tmpdir),
pronunciation=PronunciationConfig(
normalization_overrides={"normalization_apostrophe_mode": "llm"},
),
)
events = FakeEvents()
pipeline = FakePipelineProvider()
resolver = FakeVoiceResolver()
with pytest.raises(RuntimeError, match="LLM.*apostrophe"):
run_conversion(req, events, pipeline, resolver)
def test_usage_counter_populated_in_result(self):
"""usage_counter is created and accessible in result."""
from abogen.application.conversion_service import run_conversion
with tempfile.TemporaryDirectory() as tmpdir:
req = ConversionRequest(
direct_text="Hello",
voice="M1",
save_mode="custom_folder",
output_folder=Path(tmpdir),
)
events = FakeEvents()
pipeline = FakePipelineProvider()
resolver = FakeVoiceResolver()
result = run_conversion(req, events, pipeline, resolver)
assert hasattr(result, "usage_counter")
assert isinstance(result.usage_counter, dict)
# ─── Tests for output_layout_service.py ─────────────────────────────
+24
View File
@@ -246,6 +246,30 @@ class TestWordSubstitution:
assert len(plan.chapters) >= 1
assert "cat" in plan.chapters[0].body_text
def test_chunks_assigned_to_correct_chapter(self):
"""Chunks are grouped by chapter_index and only assigned to matching chapters."""
req = ConversionRequest(
direct_text="<<CHAPTER_MARKER:Ch1>>\nText A\n<<CHAPTER_MARKER:Ch2>>\nText B",
voice="M1",
chapter_chunk=ChapterChunkConfig(
chunks=[
{"text": "Ch1 chunk", "chapter_index": 0},
{"text": "Ch2 chunk", "chapter_index": 1},
],
),
)
plan = build_conversion_plan(req)
assert len(plan.chapters) == 2
# Ch1 should have only its chunk
ch1_texts = [s.text for s in plan.chapters[0].segments]
assert "Ch1 chunk" in ch1_texts
assert "Ch2 chunk" not in ch1_texts
# Ch2 should have only its chunk
ch2_texts = [s.text for s in plan.chapters[1].segments]
assert "Ch2 chunk" in ch2_texts
assert "Ch1 chunk" not in ch2_texts
def test_no_substitution_when_disabled(self):
"""No substitution when word_substitution is None."""
req = ConversionRequest(