aboutsummaryrefslogtreecommitdiff
path: root/app/tests/test_tts.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/tests/test_tts.py')
-rw-r--r--app/tests/test_tts.py63
1 files changed, 38 insertions, 25 deletions
diff --git a/app/tests/test_tts.py b/app/tests/test_tts.py
index 0e35f78..c17609b 100644
--- a/app/tests/test_tts.py
+++ b/app/tests/test_tts.py
@@ -512,12 +512,11 @@ class AudioCppTTSClientHealthTests(unittest.TestCase):
raise AssertionError(f"unexpected URL: {url}")
return _dispatch
- def _client(self, voice=None, language=None, model_id=None, speaker=None,
- **kwargs):
+ def _client(self, voice=None, language=None, model_id=None, **kwargs):
with patch("converter.tts.urllib.request.urlopen",
side_effect=self._get_responses(**kwargs)):
return AudioCppTTSClient(voice=voice, language=language,
- model_id=model_id, speaker=speaker)
+ model_id=model_id)
def test_unreachable_server_raises_with_readme_pointer(self):
import urllib.error
@@ -549,34 +548,51 @@ class AudioCppTTSClientHealthTests(unittest.TestCase):
self.assertEqual(client.language, config.LANGUAGE)
self.assertEqual(client.voice, "Vivian")
self.assertFalse(client.preset_mode)
+ self.assertTrue(client.speaker_mode)
def test_speaker_mode_uses_configured_speaker(self):
with patch.object(config, "SPEAKER", "uncle_fu"):
client = self._client()
self.assertEqual(client.voice, "Uncle Fu")
+ self.assertTrue(client.speaker_mode)
- def test_explicit_speaker_selects_speaker_mode(self):
- # --speaker picks a CustomVoice speaker; the name is normalized to
- # its wire (display) form and no preset validation runs.
- client = self._client(speaker="Uncle_Fu")
+ def test_voice_speaker_name_selects_speaker_mode(self):
+ # --voice naming a built-in CustomVoice speaker selects speaker
+ # mode; the name is normalized to its wire (display) form and no
+ # preset validation runs.
+ client = self._client(voice="Uncle_Fu")
self.assertEqual(client.voice, "Uncle Fu")
self.assertFalse(client.preset_mode)
+ self.assertTrue(client.speaker_mode)
- def test_explicit_speaker_on_clone_entry_raises(self):
- # --speaker is meaningless on a clone-only (Base) entry.
+ def test_voice_speaker_name_on_clone_entry_is_a_preset(self):
+ # --voice on a clone-only (Base) entry is a server-side preset,
+ # not a built-in speaker, so the name is validated against the
+ # server's voice library.
with self.assertRaises(RuntimeError) as ctx:
- self._client(speaker="Ryan", model_id="Qwen3-TTS-12Hz-1.7B-Base-GGUF",
+ self._client(voice="Ryan", model_id="Qwen3-TTS-12Hz-1.7B-Base-GGUF",
models={"data": [
{"id": "Qwen3-TTS-12Hz-1.7B-Base-GGUF",
"family": "qwen3_tts"}]})
message = str(ctx.exception)
- self.assertIn("no built-in speakers", message)
+ self.assertIn("'Ryan'", message)
self.assertIn("--voice", message)
- def test_voice_and_speaker_are_mutually_exclusive(self):
- with self.assertRaises(ValueError) as ctx:
- AudioCppTTSClient(voice="narrator", speaker="Ryan")
- self.assertIn("mutually exclusive", str(ctx.exception))
+ def test_voice_speaker_name_does_not_reroute_to_clone_model(self):
+ # A built-in speaker name on a CustomVoice primary selects speaker
+ # mode without the AUDIOCPP_CLONE_MODEL_ID reroute.
+ with patch.object(config, "AUDIOCPP_MODEL_ID",
+ "Qwen3-TTS-CustomVoice"), \
+ patch.object(config, "AUDIOCPP_CLONE_MODEL_ID", "qwen3-tts-clone"):
+ client = self._client(
+ voice="Ryan",
+ models={"data": [{"id": "Qwen3-TTS-CustomVoice",
+ "family": "qwen3_tts"},
+ {"id": "qwen3-tts-clone",
+ "family": "qwen3_tts"}]})
+ self.assertEqual(client.model_id, "Qwen3-TTS-CustomVoice")
+ self.assertTrue(client.speaker_mode)
+ self.assertFalse(client.preset_mode)
def test_no_voice_on_base_entry_raises_instead_of_silent_speaker(self):
# The Base model has no built-in speakers: without --voice the run
@@ -1063,7 +1079,6 @@ class AudioCppTTSClientRequestTests(unittest.TestCase):
client.model_id = config.AUDIOCPP_MODEL_ID
client.preset_mode = preset_mode
client.voice = voice
- client.speaker = None
client.language = language
client._seed = seed
client.family = family
@@ -1518,8 +1533,8 @@ class AudioCppUnloadModelsTests(unittest.TestCase):
client.profile = tts.AUDIOCPP_FAMILY_PROFILES["qwen3_tts"]
client.design_mode = False
client.instruction_voice = False
+ client.speaker_mode = False
client.instructions = ""
- client.speaker = None
with patch.object(client, "_check_health"), \
patch.object(client, "_list_models",
return_value=[{"id": client.model_id,
@@ -1548,8 +1563,8 @@ class AudioCppUnloadModelsTests(unittest.TestCase):
client.profile = tts.AUDIOCPP_FAMILY_PROFILES["qwen3_tts"]
client.design_mode = False
client.instruction_voice = False
+ client.speaker_mode = False
client.instructions = ""
- client.speaker = None
with patch.object(client, "_check_health"), \
patch.object(client, "_list_models",
return_value=[{"id": client.model_id,
@@ -1591,8 +1606,7 @@ class BackendWiringTests(unittest.TestCase):
model_id=None,
instructions=None,
request_options={},
- api_url=None,
- speaker=None)
+ api_url=None)
mock_faster.assert_not_called()
mock_qwen.assert_not_called()
@@ -1604,8 +1618,7 @@ class BackendWiringTests(unittest.TestCase):
model_id=None,
instructions=None,
request_options={},
- api_url=None,
- speaker=None)
+ api_url=None)
def test_audiocpp_backend_model_id_is_wired_through(self):
with patch("converter.converter.AudioCppTTSClient") as mock_audiocpp:
@@ -1615,7 +1628,7 @@ class BackendWiringTests(unittest.TestCase):
mock_audiocpp.assert_called_once_with(
voice="narrator", language=config.LANGUAGE,
model_id="higgs", instructions=None,
- request_options={}, api_url=None, speaker=None)
+ request_options={}, api_url=None)
def test_audiocpp_backend_instructions_and_options_are_wired_through(self):
with patch("converter.converter.AudioCppTTSClient") as mock_audiocpp:
@@ -1629,7 +1642,7 @@ class BackendWiringTests(unittest.TestCase):
model_id=None,
instructions="A warm adult narrator",
request_options={"emotion": "neutral", "speed": "1.1"},
- api_url=None, speaker=None)
+ api_url=None)
def test_qwen_backend_uses_qwen_client(self):
with patch("converter.converter.FasterTTSClient") as mock_faster, \
@@ -1656,7 +1669,7 @@ class BackendWiringTests(unittest.TestCase):
mock_audiocpp.assert_called_once_with(
voice="narrator", language=config.LANGUAGE, model_id=None,
instructions=None, request_options={},
- api_url="http://10.0.0.5:8080", speaker=None)
+ api_url="http://10.0.0.5:8080")
with patch("converter.converter.FasterTTSClient") as mock_faster:
AudiobookConverter(voice_mode=tts.VOICE_MODE_CLONE,
backend=tts.BACKEND_FASTER, voice="narrator",