"""TtsConfig 配音配置模型单测.""" import pytest from packages.domain.tts_config import TtsConfig class TestTtsConfigDefaults: def test_default_values(self): config = TtsConfig() assert config.enabled is False assert config.voice_id == "" assert config.speed == 1.0 assert config.pitch == 0.0 assert config.volume == 0.8 assert config.text == "" assert config.align_mode == "full" assert config.overlap_mode == "replace" class TestTtsConfigParse: def test_parse_none(self): config = TtsConfig.parse(None) assert config.enabled is False assert isinstance(config, TtsConfig) def test_parse_empty_dict(self): config = TtsConfig.parse({}) assert config.enabled is False def test_parse_not_dict(self): config = TtsConfig.parse("not a dict") assert config.enabled is False def test_parse_enabled_false_returns_disabled(self): # 即使传了其他参数,enabled=False 就直接返回禁用 config = TtsConfig.parse({"enabled": False, "voice_id": "v1", "speed": 1.5}) assert config.enabled is False assert config.voice_id == "" assert config.speed == 1.0 def test_parse_enabled_true_with_all_fields(self): config = TtsConfig.parse( { "enabled": True, "voice_id": "female_warm", "speed": 1.5, "pitch": 2.0, "volume": 0.9, "text": "你好世界", "align_mode": "subtitle", "overlap_mode": "mix", } ) assert config.enabled is True assert config.voice_id == "female_warm" assert config.speed == 1.5 assert config.pitch == 2.0 assert config.volume == 0.9 assert config.text == "你好世界" assert config.align_mode == "subtitle" assert config.overlap_mode == "mix" def test_parse_enabled_not_bool(self): config = TtsConfig.parse({"enabled": "true", "voice_id": "v1"}) assert config.enabled is False # 非 bool 值视为 False def test_parse_voice_id_not_string(self): config = TtsConfig.parse({"enabled": True, "voice_id": 123}) assert config.voice_id == "" def test_parse_speed_not_number(self): config = TtsConfig.parse({"enabled": True, "speed": "fast"}) assert config.speed == 1.0 def test_parse_pitch_not_number(self): config = TtsConfig.parse({"enabled": True, "pitch": "high"}) assert config.pitch == 0.0 def test_parse_volume_not_number(self): config = TtsConfig.parse({"enabled": True, "volume": "loud"}) assert config.volume == 0.8 def test_parse_text_not_string(self): config = TtsConfig.parse({"enabled": True, "text": 12345}) assert config.text == "" def test_parse_invalid_align_mode(self): config = TtsConfig.parse({"enabled": True, "align_mode": "invalid"}) assert config.align_mode == "full" def test_parse_invalid_overlap_mode(self): config = TtsConfig.parse({"enabled": True, "overlap_mode": "invalid"}) assert config.overlap_mode == "replace" class TestTtsConfigClamp: def test_speed_below_min(self): config = TtsConfig.parse({"enabled": True, "speed": 0.1}) assert config.speed == 0.5 def test_speed_above_max(self): config = TtsConfig.parse({"enabled": True, "speed": 3.0}) assert config.speed == 2.0 def test_speed_within_range(self): config = TtsConfig.parse({"enabled": True, "speed": 1.2}) assert config.speed == 1.2 def test_speed_boundary_values(self): config_low = TtsConfig.parse({"enabled": True, "speed": 0.5}) assert config_low.speed == 0.5 config_high = TtsConfig.parse({"enabled": True, "speed": 2.0}) assert config_high.speed == 2.0 def test_pitch_below_min(self): config = TtsConfig.parse({"enabled": True, "pitch": -20}) assert config.pitch == -12 def test_pitch_above_max(self): config = TtsConfig.parse({"enabled": True, "pitch": 20}) assert config.pitch == 12 def test_pitch_within_range(self): config = TtsConfig.parse({"enabled": True, "pitch": -3.5}) assert config.pitch == -3.5 def test_volume_below_min(self): config = TtsConfig.parse({"enabled": True, "volume": -0.5}) assert config.volume == 0.0 def test_volume_above_max(self): config = TtsConfig.parse({"enabled": True, "volume": 2.0}) assert config.volume == 1.0 def test_volume_within_range(self): config = TtsConfig.parse({"enabled": True, "volume": 0.5}) assert config.volume == 0.5 def test_int_speed_converted_to_float(self): config = TtsConfig.parse({"enabled": True, "speed": 1}) assert isinstance(config.speed, float) assert config.speed == 1.0 def test_int_pitch_converted_to_float(self): config = TtsConfig.parse({"enabled": True, "pitch": 2}) assert isinstance(config.pitch, float) assert config.pitch == 2.0 def test_int_volume_converted_to_float(self): config = TtsConfig.parse({"enabled": True, "volume": 1}) assert isinstance(config.volume, float) assert config.volume == 1.0