""" Basic tests for TTS service functionality. """ import pytest import numpy as np from services.tts_service import TTSService def test_tts_service_initialization(): """Test that TTSService initializes correctly.""" service = TTSService() assert service is not None assert service.pipelines == {} assert service.DEFAULT_VOICE == "af_bella" assert service.SAMPLE_RATE == 24000 def test_get_pipeline_caching(): """Test that pipelines are cached per language.""" service = TTSService() # Get pipeline for American English pipeline1 = service.get_pipeline('a') assert pipeline1 is not None assert 'a' in service.pipelines # Get same pipeline again - should return cached version pipeline2 = service.get_pipeline('a') assert pipeline1 is pipeline2 def test_get_pipeline_invalid_language(): """Test that invalid language codes raise ValueError.""" service = TTSService() with pytest.raises(ValueError, match="Unsupported language code"): service.get_pipeline('x') def test_segment_text_colon_pattern(): """Test text segmentation with colon pattern.""" service = TTSService() text = "Alice: Hello there\nBob: Hi Alice" role_voice_map = {"Alice": "af_bella", "Bob": "am_adam"} segments = service.segment_text(text, role_voice_map) assert len(segments) == 2 assert segments[0] == ("Alice", "af_bella", "Hello there") assert segments[1] == ("Bob", "am_adam", "Hi Alice") def test_segment_text_bracket_pattern(): """Test text segmentation with bracket pattern.""" service = TTSService() text = "[Narrator] The story begins\n[Alice] Hello world" role_voice_map = {"Narrator": "af_sarah", "Alice": "af_bella"} segments = service.segment_text(text, role_voice_map) assert len(segments) == 2 assert segments[0] == ("Narrator", "af_sarah", "The story begins") assert segments[1] == ("Alice", "af_bella", "Hello world") def test_segment_text_default_voice_fallback(): """Test that unmapped roles fall back to default voice.""" service = TTSService() text = "Alice: Hello\nBob: Hi" role_voice_map = {"Alice": "af_bella"} # Bob not mapped segments = service.segment_text(text, role_voice_map) assert len(segments) == 2 assert segments[0] == ("Alice", "af_bella", "Hello") assert segments[1] == ("Bob", "af_bella", "Hi") # Falls back to default def test_segment_text_no_markers(): """Test text without role markers uses Narrator.""" service = TTSService() text = "This is plain text without markers" role_voice_map = {"Narrator": "af_sarah"} segments = service.segment_text(text, role_voice_map) assert len(segments) == 1 assert segments[0] == ("Narrator", "af_sarah", "This is plain text without markers") def test_chunk_text_short(): """Test that short text is not chunked.""" service = TTSService() text = "This is a short sentence." chunks = service._chunk_text(text, max_length=500) assert len(chunks) == 1 assert chunks[0] == text def test_chunk_text_long(): """Test that long text is chunked on sentence boundaries.""" service = TTSService() text = "First sentence. Second sentence. Third sentence. Fourth sentence." chunks = service._chunk_text(text, max_length=30) assert len(chunks) > 1 # Each chunk should contain complete sentences for chunk in chunks: assert chunk.strip() def test_concatenate_audio_empty(): """Test concatenating empty list returns empty array.""" service = TTSService() result = service.concatenate_audio([]) assert isinstance(result, np.ndarray) assert len(result) == 0 def test_concatenate_audio_single(): """Test concatenating single segment.""" service = TTSService() audio = np.array([0.1, 0.2, 0.3], dtype=np.float32) result = service.concatenate_audio([audio]) assert isinstance(result, np.ndarray) assert len(result) == 3 np.testing.assert_array_equal(result, audio) def test_concatenate_audio_multiple(): """Test concatenating multiple segments.""" service = TTSService() audio1 = np.array([0.1, 0.2], dtype=np.float32) audio2 = np.array([0.3, 0.4], dtype=np.float32) audio3 = np.array([0.5, 0.6], dtype=np.float32) result = service.concatenate_audio([audio1, audio2, audio3]) assert isinstance(result, np.ndarray) assert len(result) == 6 expected = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6], dtype=np.float32) np.testing.assert_array_almost_equal(result, expected) def test_concatenate_audio_filters_empty(): """Test that empty segments are filtered out.""" service = TTSService() audio1 = np.array([0.1, 0.2], dtype=np.float32) audio2 = np.array([], dtype=np.float32) audio3 = np.array([0.3, 0.4], dtype=np.float32) result = service.concatenate_audio([audio1, audio2, audio3]) assert len(result) == 4 expected = np.array([0.1, 0.2, 0.3, 0.4], dtype=np.float32) np.testing.assert_array_almost_equal(result, expected)