diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_audio.py | 18 | ||||
| -rw-r--r-- | tests/test_converter.py | 43 | ||||
| -rw-r--r-- | tests/test_tts.py | 38 |
3 files changed, 50 insertions, 49 deletions
diff --git a/tests/test_audio.py b/tests/test_audio.py index 97280ae..fb448f8 100644 --- a/tests/test_audio.py +++ b/tests/test_audio.py @@ -55,12 +55,12 @@ class CleanupChunksTests(unittest.TestCase): (chunks_dir / "chunk_0002.wav").write_bytes(b"stale") (chunks_dir / "keep.txt").write_bytes(b"keep") - original = config.CHUNKS_FOLDER - config.CHUNKS_FOLDER = chunks_dir + original = audio.CHUNKS_FOLDER + audio.CHUNKS_FOLDER = chunks_dir try: cleanup_chunks() finally: - config.CHUNKS_FOLDER = original + audio.CHUNKS_FOLDER = original self.assertFalse((chunks_dir / "chunk_0001.wav").exists()) self.assertFalse((chunks_dir / "chunk_0002.wav").exists()) @@ -72,12 +72,12 @@ class CleanupChunksTests(unittest.TestCase): (chunks_dir / "chapter_0001.m4b").write_bytes(b"stale") (chunks_dir / "chunk_0001.wav").write_bytes(b"stale") - original = config.CHUNKS_FOLDER - config.CHUNKS_FOLDER = chunks_dir + original = audio.CHUNKS_FOLDER + audio.CHUNKS_FOLDER = chunks_dir try: cleanup_chunks() finally: - config.CHUNKS_FOLDER = original + audio.CHUNKS_FOLDER = original self.assertFalse((chunks_dir / "chapter_0001.m4b").exists()) self.assertFalse((chunks_dir / "chunk_0001.wav").exists()) @@ -178,12 +178,12 @@ class CollectChunkFilesTests(unittest.TestCase): (chunks_dir / "chunk_0002.wav").write_bytes(b"audio") (chunks_dir / "chunk_0001.wav").write_bytes(b"audio") - original = config.CHUNKS_FOLDER - config.CHUNKS_FOLDER = chunks_dir + original = audio.CHUNKS_FOLDER + audio.CHUNKS_FOLDER = chunks_dir try: files, missing = _collect_chunk_files(3) finally: - config.CHUNKS_FOLDER = original + audio.CHUNKS_FOLDER = original self.assertEqual(files, [chunks_dir / "chunk_0001.wav", chunks_dir / "chunk_0002.wav"]) diff --git a/tests/test_converter.py b/tests/test_converter.py index a79ae58..91ab0b5 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -6,7 +6,8 @@ import unittest from pathlib import Path from unittest.mock import MagicMock, patch -from converter import config +from converter import config, tts +from converter import converter as converter_mod from converter.converter import ( AudiobookConverter, find_existing_outputs, @@ -66,11 +67,11 @@ class FindExistingOutputsTests(unittest.TestCase): def setUp(self): self._tmp = tempfile.TemporaryDirectory() self.folder = Path(self._tmp.name) - self._original = config.AUDIOBOOKS_FOLDER - config.AUDIOBOOKS_FOLDER = self.folder + self._original = converter_mod.AUDIOBOOKS_FOLDER + converter_mod.AUDIOBOOKS_FOLDER = self.folder def tearDown(self): - config.AUDIOBOOKS_FOLDER = self._original + converter_mod.AUDIOBOOKS_FOLDER = self._original self._tmp.cleanup() def _touch(self, name): @@ -125,28 +126,28 @@ class NarratorTagTests(unittest.TestCase): return converter def test_custom_voice_uses_speaker_display_name(self): - self.assertEqual(self._converter(config.VOICE_MODE_CUSTOM)._narrator_tag(), + self.assertEqual(self._converter(tts.VOICE_MODE_CUSTOM)._narrator_tag(), "Vivian") def test_multi_word_display_name_gets_underscores(self): with patch.object(config, "CUSTOM_VOICE_SPEAKER", "uncle_fu"): - self.assertEqual(self._converter(config.VOICE_MODE_CUSTOM)._narrator_tag(), + self.assertEqual(self._converter(tts.VOICE_MODE_CUSTOM)._narrator_tag(), "Uncle_Fu") def test_clone_uses_reference_audio_stem(self): - self.assertEqual(self._converter(config.VOICE_MODE_CLONE, "/x/ref.wav")._narrator_tag(), + self.assertEqual(self._converter(tts.VOICE_MODE_CLONE, "/x/ref.wav")._narrator_tag(), "ref") def test_clone_stem_spaces_become_underscores(self): - self.assertEqual(self._converter(config.VOICE_MODE_CLONE, "/x/my voice.wav")._narrator_tag(), + self.assertEqual(self._converter(tts.VOICE_MODE_CLONE, "/x/my voice.wav")._narrator_tag(), "my_voice") def test_invalid_characters_sanitized(self): - self.assertEqual(self._converter(config.VOICE_MODE_CLONE, "/x/bad:name?.wav")._narrator_tag(), + self.assertEqual(self._converter(tts.VOICE_MODE_CLONE, "/x/bad:name?.wav")._narrator_tag(), "bad_name") def test_empty_after_sanitize_falls_back(self): - self.assertEqual(self._converter(config.VOICE_MODE_CLONE, "/x/???.wav")._narrator_tag(), + self.assertEqual(self._converter(tts.VOICE_MODE_CLONE, "/x/???.wav")._narrator_tag(), "narrator") @@ -171,7 +172,7 @@ class DebugDumpTests(unittest.TestCase): def setUp(self): self._tmp = tempfile.TemporaryDirectory() - self._debug_folder = patch.object(config, "DEBUG_FOLDER", Path(self._tmp.name)) + self._debug_folder = patch.object(converter_mod, "DEBUG_FOLDER", Path(self._tmp.name)) self._debug_folder.start() self.debug_root = Path(self._tmp.name) self.converter = AudiobookConverter.__new__(AudiobookConverter) @@ -259,7 +260,7 @@ class SetupLoggingTests(unittest.TestCase): def setUp(self): self._tmp = tempfile.TemporaryDirectory() - self._logs_folder = patch.object(config, "LOGS_FOLDER", Path(self._tmp.name)) + self._logs_folder = patch.object(converter_mod, "LOGS_FOLDER", Path(self._tmp.name)) self._logs_folder.start() self._root = logging.getLogger() self._saved_handlers = self._root.handlers[:] @@ -376,12 +377,12 @@ class RunOverwritePromptTests(unittest.TestCase): def setUp(self): self._books_tmp = tempfile.TemporaryDirectory() self._output_tmp = tempfile.TemporaryDirectory() - self._original_folders = (config.BOOKS_FOLDER, config.AUDIOBOOKS_FOLDER) - config.BOOKS_FOLDER = Path(self._books_tmp.name) - config.AUDIOBOOKS_FOLDER = Path(self._output_tmp.name) - (config.BOOKS_FOLDER / "book.txt").write_text("hello world", encoding="utf-8") + self._original_folders = (converter_mod.BOOKS_FOLDER, converter_mod.AUDIOBOOKS_FOLDER) + converter_mod.BOOKS_FOLDER = Path(self._books_tmp.name) + converter_mod.AUDIOBOOKS_FOLDER = Path(self._output_tmp.name) + (converter_mod.BOOKS_FOLDER / "book.txt").write_text("hello world", encoding="utf-8") self.converter = AudiobookConverter.__new__(AudiobookConverter) - self.converter.voice_mode = config.VOICE_MODE_CUSTOM + self.converter.voice_mode = tts.VOICE_MODE_CUSTOM self.converter.voice_clone_ref_audio = None self.converter.faster = False self.converter.faster_voice = None @@ -396,19 +397,19 @@ class RunOverwritePromptTests(unittest.TestCase): not self.converted.append((file_path.name, output_name)) or True) def tearDown(self): - config.BOOKS_FOLDER, config.AUDIOBOOKS_FOLDER = self._original_folders + converter_mod.BOOKS_FOLDER, converter_mod.AUDIOBOOKS_FOLDER = self._original_folders self._books_tmp.cleanup() self._output_tmp.cleanup() def test_declined_book_is_skipped(self): - (config.AUDIOBOOKS_FOLDER / "book_Vivian.mp3").write_bytes(b"existing") + (converter_mod.AUDIOBOOKS_FOLDER / "book_Vivian.mp3").write_bytes(b"existing") with patch("builtins.input", return_value="n"): self.assertTrue(self.converter.run()) self.assertEqual(self.converted, []) - self.assertTrue((config.AUDIOBOOKS_FOLDER / "book_Vivian.mp3").exists()) + self.assertTrue((converter_mod.AUDIOBOOKS_FOLDER / "book_Vivian.mp3").exists()) def test_accepted_book_is_converted(self): - (config.AUDIOBOOKS_FOLDER / "book_Vivian.mp3").write_bytes(b"existing") + (converter_mod.AUDIOBOOKS_FOLDER / "book_Vivian.mp3").write_bytes(b"existing") with patch("builtins.input", return_value="y"): self.assertTrue(self.converter.run()) self.assertEqual(self.converted, [("book.txt", "book_Vivian")]) diff --git a/tests/test_tts.py b/tests/test_tts.py index dfeda6f..47a8309 100644 --- a/tests/test_tts.py +++ b/tests/test_tts.py @@ -7,7 +7,7 @@ import wave from pathlib import Path from unittest.mock import MagicMock, patch -from converter import config +from converter import config, tts from converter.converter import AudiobookConverter from converter.tts import FasterTTSClient, QwenTTSClient, normalize_language @@ -35,7 +35,7 @@ class NormalizeLanguageTests(unittest.TestCase): self.assertEqual(normalize_language("it"), "Italian") def test_all_supported_languages_round_trip(self): - for name in config.TTS_LANGUAGES: + for name in tts.TTS_LANGUAGES: self.assertEqual(normalize_language(name.lower()), name) def test_unknown_language_rejected_with_guidance(self): @@ -60,14 +60,14 @@ class QwenTTSClientLanguageTests(unittest.TestCase): return QwenTTSClient(**kwargs) def test_default_follows_config_for_each_mode(self): - custom = self._make_client(voice_mode=config.VOICE_MODE_CUSTOM) - self.assertEqual(custom.language, config.CUSTOM_VOICE_LANGUAGE) - clone = self._make_client(voice_mode=config.VOICE_MODE_CLONE, + custom = self._make_client(voice_mode=tts.VOICE_MODE_CUSTOM) + self.assertEqual(custom.language, config.LANGUAGE) + clone = self._make_client(voice_mode=tts.VOICE_MODE_CLONE, voice_clone_ref_audio="ref.wav") - self.assertEqual(clone.language, config.VOICE_CLONE_LANGUAGE) + self.assertEqual(clone.language, config.LANGUAGE) def test_explicit_language_normalized(self): - client = self._make_client(voice_mode=config.VOICE_MODE_CUSTOM, language="ja") + client = self._make_client(voice_mode=tts.VOICE_MODE_CUSTOM, language="ja") self.assertEqual(client.language, "Japanese") def test_invalid_language_fails_before_connect(self): @@ -90,7 +90,7 @@ class PayloadLanguageTests(unittest.TestCase): def _custom_client(self, language, endpoint, api_info=None): client = QwenTTSClient.__new__(QwenTTSClient) - client.voice_mode = config.VOICE_MODE_CUSTOM + client.voice_mode = tts.VOICE_MODE_CUSTOM client.language = language client.api_info = api_info if api_info is not None else { "named_endpoints": {endpoint: {}} @@ -100,7 +100,7 @@ class PayloadLanguageTests(unittest.TestCase): def _clone_client(self, language, endpoint, api_info=None, ref_text="hello"): client = QwenTTSClient.__new__(QwenTTSClient) - client.voice_mode = config.VOICE_MODE_CLONE + client.voice_mode = tts.VOICE_MODE_CLONE client.language = language client.voice_clone_ref_audio = str(self.ref_audio) client.voice_clone_ref_text = ref_text @@ -149,8 +149,8 @@ class PayloadLanguageTests(unittest.TestCase): client = self._clone_client("English", "/generate_voice_clone", api_info=api_info) client._generate_voice_clone("text") kwargs = client.clone_client.predict.call_args.kwargs - self.assertEqual(kwargs["model_size"], config.VOICE_CLONE_MODEL_SIZE) - self.assertEqual(kwargs["seed"], config.VOICE_CLONE_SEED) + self.assertEqual(kwargs["model_size"], tts.MODEL_SIZE) + self.assertEqual(kwargs["seed"], config.SEED) self.assertNotIn("max_chunk_chars", kwargs) @@ -201,7 +201,7 @@ class FasterTTSClientGenerateTests(unittest.TestCase): def setUp(self): self._tmp = tempfile.TemporaryDirectory() - self._chunks = patch.object(config, "CHUNKS_FOLDER", Path(self._tmp.name)) + self._chunks = patch.object(tts, "CHUNKS_FOLDER", Path(self._tmp.name)) self._chunks.start() self._sleep = patch("converter.tts.time.sleep") self._sleep.start() @@ -233,7 +233,7 @@ class FasterTTSClientGenerateTests(unittest.TestCase): channels, sampwidth, framerate, frames = self._read_wav(path) self.assertEqual(channels, 1) self.assertEqual(sampwidth, 2) - self.assertEqual(framerate, config.FASTER_TTS_SAMPLE_RATE) + self.assertEqual(framerate, tts.SAMPLE_RATE) self.assertEqual(frames, pcm) def test_long_text_is_subchunked_and_concatenated_in_order(self): @@ -241,7 +241,7 @@ class FasterTTSClientGenerateTests(unittest.TestCase): sentences = [" ".join(f"word{i}" for i in range(6)) + "." for _ in range(3)] text = " ".join(sentences) pcm_parts = [b"\x01\x00" * 10, b"\x02\x00" * 20, b"\x03\x00" * 30] - with patch.object(config, "FASTER_SUBCHUNK_WORDS", 10), \ + with patch.object(config, "CHUNK_SIZE_WORDS", 10), \ patch.object(client, "_request_pcm", side_effect=pcm_parts) as mock_pcm: result = client.generate_chunk(text, 1) self.assertEqual(mock_pcm.call_count, 3) @@ -290,7 +290,7 @@ class FasterTTSClientGenerateTests(unittest.TestCase): side_effect=RuntimeError("down")) as mock_pcm: result = client.generate_chunk("Hello.", 1) self.assertIsNone(result) - self.assertEqual(mock_pcm.call_count, config.FASTER_SUBCHUNK_RETRIES) + self.assertEqual(mock_pcm.call_count, config.MAX_RETRIES) def test_empty_text_fails_the_chunk(self): client = self._make_client() @@ -322,7 +322,7 @@ class FasterModeWiringTests(unittest.TestCase): def test_faster_mode_uses_faster_client_without_reference(self): with patch("converter.converter.FasterTTSClient") as mock_faster, \ patch("converter.converter.QwenTTSClient") as mock_qwen: - AudiobookConverter(voice_mode=config.VOICE_MODE_CLONE, + AudiobookConverter(voice_mode=tts.VOICE_MODE_CLONE, faster=True, faster_voice="narrator") mock_faster.assert_called_once_with(voice="narrator") mock_qwen.assert_not_called() @@ -330,7 +330,7 @@ class FasterModeWiringTests(unittest.TestCase): def test_non_faster_clone_mode_still_requires_reference(self): with patch("converter.converter.QwenTTSClient"): with self.assertRaises(ValueError): - AudiobookConverter(voice_mode=config.VOICE_MODE_CLONE) + AudiobookConverter(voice_mode=tts.VOICE_MODE_CLONE) def test_faster_mode_still_validates_other_settings(self): with patch("converter.converter.FasterTTSClient"): @@ -341,7 +341,7 @@ class FasterModeWiringTests(unittest.TestCase): def _faster_converter(self, faster_voice=None): with patch("converter.converter.FasterTTSClient"): - return AudiobookConverter(voice_mode=config.VOICE_MODE_CLONE, + return AudiobookConverter(voice_mode=tts.VOICE_MODE_CLONE, faster=True, faster_voice=faster_voice) def test_narrator_tag_uses_faster_voice_name(self): @@ -362,7 +362,7 @@ class FasterModeWiringTests(unittest.TestCase): ref = Path(tmp) / "ref.wav" ref.write_bytes(b"x") with patch("converter.converter.QwenTTSClient"): - converter = AudiobookConverter(voice_mode=config.VOICE_MODE_CLONE, + converter = AudiobookConverter(voice_mode=tts.VOICE_MODE_CLONE, voice_clone_ref_audio=str(ref)) self.assertEqual(converter._narrator_tag(), "ref") |
