aboutsummaryrefslogtreecommitdiff
path: root/app/tests/test_converter.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-28 14:57:48 -0400
committerhistoria <historiavg@proton.me>2026-08-28 14:57:48 -0400
commitdb38085d07ce75f8961eecdc1919e98748254c53 (patch)
treebeaea2ba84de05bfc2fa90e9b92a24568d3b4cb9 /app/tests/test_converter.py
parentafb2c2d5b297c5aa28bcced0e3f90e207d799c2a (diff)
downloadtts-audiobook-generator-db38085d07ce75f8961eecdc1919e98748254c53.tar.gz
refactor: overhaul config.py, remove cli default options
Diffstat (limited to 'app/tests/test_converter.py')
-rw-r--r--app/tests/test_converter.py57
1 files changed, 38 insertions, 19 deletions
diff --git a/app/tests/test_converter.py b/app/tests/test_converter.py
index 4d7a064..eaf96ef 100644
--- a/app/tests/test_converter.py
+++ b/app/tests/test_converter.py
@@ -64,20 +64,29 @@ class ConfigurationValidationTests(unittest.TestCase):
def test_language_defaults_to_config(self):
with patch("converter.converter.QwenTTSClient") as mock_tts:
- AudiobookConverter(backend=BACKEND_QWEN)
+ AudiobookConverter(backend=BACKEND_QWEN, voice="Vivian")
self.assertEqual(mock_tts.call_args.kwargs["language"], config.LANGUAGE)
def test_output_format_defaults_to_config(self):
with patch("converter.converter.QwenTTSClient"):
- converter = AudiobookConverter(backend=BACKEND_QWEN)
+ converter = AudiobookConverter(backend=BACKEND_QWEN,
+ voice="Vivian")
self.assertEqual(converter.output_format, config.AUDIO_FORMAT)
def test_language_normalized_before_tts_client(self):
with patch("converter.converter.QwenTTSClient") as mock_tts:
- converter = AudiobookConverter(language="ja", backend=BACKEND_QWEN)
+ converter = AudiobookConverter(language="ja", backend=BACKEND_QWEN,
+ voice="Vivian")
self.assertEqual(converter.language, "Japanese")
self.assertEqual(mock_tts.call_args.kwargs["language"], "Japanese")
+ def test_qwen_custom_voice_requires_a_speaker(self):
+ # There is no configured default speaker: a qwen built-in-speaker
+ # run must be told which one to use.
+ with self.assertRaises(ValueError) as ctx:
+ AudiobookConverter(backend=BACKEND_QWEN)
+ self.assertIn("requires a speaker", str(ctx.exception))
+
class FindExistingOutputsTests(unittest.TestCase):
def setUp(self):
@@ -133,23 +142,23 @@ class FindExistingOutputsTests(unittest.TestCase):
class NarratorTagTests(unittest.TestCase):
- def _converter(self, voice_mode, ref_audio=None, instructions=None):
+ def _converter(self, voice_mode, ref_audio=None, instructions=None,
+ voice=None):
converter = AudiobookConverter.__new__(AudiobookConverter)
converter.voice_mode = voice_mode
converter.voice_clone_ref_audio = ref_audio
converter.backend = BACKEND_QWEN
- converter.voice = None
+ converter.voice = voice
converter.instructions = instructions
return converter
def test_custom_voice_uses_speaker_display_name(self):
- self.assertEqual(self._converter(VOICE_MODE_CUSTOM)._narrator_tag(),
- "Vivian")
+ converter = self._converter(VOICE_MODE_CUSTOM, voice="Vivian")
+ self.assertEqual(converter._narrator_tag(), "Vivian")
def test_multi_word_display_name_gets_underscores(self):
- with patch.object(config, "SPEAKER", "uncle_fu"):
- self.assertEqual(self._converter(VOICE_MODE_CUSTOM)._narrator_tag(),
- "Uncle_Fu")
+ converter = self._converter(VOICE_MODE_CUSTOM, voice="uncle_fu")
+ self.assertEqual(converter._narrator_tag(), "Uncle_Fu")
def test_clone_uses_reference_audio_stem(self):
self.assertEqual(self._converter(VOICE_MODE_CLONE, "/x/ref.wav")._narrator_tag(),
@@ -186,14 +195,21 @@ class NarratorTagTests(unittest.TestCase):
self.assertEqual(converter._narrator_tag(), "narrator")
def test_audiocpp_speaker_mode_keeps_speaker_tag(self):
- converter = self._audiocpp_converter()
+ converter = self._audiocpp_converter(voice="Vivian")
self.assertEqual(converter._narrator_tag(), "Vivian")
def test_audiocpp_explicit_speaker_uses_speaker_tag(self):
- # A chosen CustomVoice speaker names the output, not config.SPEAKER.
+ # A chosen CustomVoice speaker names the output.
converter = self._audiocpp_converter(voice="Ryan")
self.assertEqual(converter._narrator_tag(), "Ryan")
+ def test_audiocpp_without_voice_or_instruction_uses_fallback_tag(self):
+ # A run like this fails at connect time (the client refuses a
+ # speaker-capable entry without --voice); the pre-flight still
+ # needs a stable tag for it.
+ converter = self._audiocpp_converter()
+ self.assertEqual(converter._narrator_tag(), "narrator")
+
def test_audiocpp_explicit_speaker_normalizes_display_name(self):
converter = self._audiocpp_converter(voice="Uncle_Fu")
self.assertEqual(converter._narrator_tag(), "Uncle_Fu")
@@ -332,8 +348,11 @@ class DebugDumpTests(unittest.TestCase):
def test_debug_flag_wiring(self):
with patch("converter.converter.QwenTTSClient"):
- self.assertFalse(AudiobookConverter(backend=BACKEND_QWEN).debug)
- self.assertTrue(AudiobookConverter(debug=True, backend=BACKEND_QWEN).debug)
+ self.assertFalse(AudiobookConverter(backend=BACKEND_QWEN,
+ voice="Vivian").debug)
+ self.assertTrue(AudiobookConverter(debug=True,
+ backend=BACKEND_QWEN,
+ voice="Vivian").debug)
class SetupLoggingTests(unittest.TestCase):
@@ -549,14 +568,14 @@ class PreflightOverwritesTests(unittest.TestCase):
(converter_mod.BOOKS_FOLDER / "book.txt").unlink()
with patch("builtins.input", side_effect=AssertionError("should not prompt")):
book_files, planned = AudiobookConverter.preflight_overwrites(
- BACKEND_QWEN, None, VOICE_MODE_CUSTOM, None, "mp3")
+ BACKEND_QWEN, "Vivian", VOICE_MODE_CUSTOM, None, "mp3")
self.assertEqual(book_files, [])
self.assertEqual(planned, [])
def test_new_book_planned_without_prompt(self):
with patch("builtins.input", side_effect=AssertionError("should not prompt")):
book_files, planned = AudiobookConverter.preflight_overwrites(
- BACKEND_QWEN, None, VOICE_MODE_CUSTOM, None, "mp3")
+ BACKEND_QWEN, "Vivian", VOICE_MODE_CUSTOM, None, "mp3")
self.assertEqual(len(book_files), 1)
self.assertEqual(planned, [(book_files[0], "book_Vivian")])
@@ -564,14 +583,14 @@ class PreflightOverwritesTests(unittest.TestCase):
(converter_mod.AUDIOBOOKS_FOLDER / "book_Vivian.mp3").write_bytes(b"existing")
with patch("builtins.input", return_value=""):
book_files, planned = AudiobookConverter.preflight_overwrites(
- BACKEND_QWEN, None, VOICE_MODE_CUSTOM, None, "mp3")
+ BACKEND_QWEN, "Vivian", VOICE_MODE_CUSTOM, None, "mp3")
self.assertEqual(planned, [(book_files[0], "book_Vivian")])
def test_existing_output_declined_is_skipped(self):
(converter_mod.AUDIOBOOKS_FOLDER / "book_Vivian.mp3").write_bytes(b"existing")
with patch("builtins.input", return_value="n"):
book_files, planned = AudiobookConverter.preflight_overwrites(
- BACKEND_QWEN, None, VOICE_MODE_CUSTOM, None, "mp3")
+ BACKEND_QWEN, "Vivian", VOICE_MODE_CUSTOM, None, "mp3")
self.assertEqual(len(book_files), 1)
self.assertEqual(planned, [])
@@ -590,7 +609,7 @@ class RunOverwritePromptTests(unittest.TestCase):
self.converter.voice_mode = VOICE_MODE_CUSTOM
self.converter.voice_clone_ref_audio = None
self.converter.backend = BACKEND_QWEN
- self.converter.voice = None
+ self.converter.voice = "Vivian"
self.converter.instructions = None
self.converter.speed = 1.0
self.converter.single_file = False