diff options
Diffstat (limited to 'app/tests/test_hub.py')
| -rw-r--r-- | app/tests/test_hub.py | 113 |
1 files changed, 97 insertions, 16 deletions
diff --git a/app/tests/test_hub.py b/app/tests/test_hub.py index 84796ee..183e8aa 100644 --- a/app/tests/test_hub.py +++ b/app/tests/test_hub.py @@ -2873,7 +2873,10 @@ class ConvertFlowTests(unittest.TestCase): elif entry.capability == "clone": if entry.requires_reference: overrides["voice"] = str(ref) - else: # design + if entry.supports_instructions \ + or entry.capability == "design": + # Supported entries show the optional + # delivery/style field; design requires it. overrides["instructions"] = "A warm narrator." self._answer_form(**overrides) if hub.converter_mod.chunk_clamp_needed(entry): @@ -2924,10 +2927,15 @@ class ConvertFlowTests(unittest.TestCase): else: # design expected = {"sglomni.model_id", "sglomni.instructions"} - self.assertEqual(kwargs.get("instructions"), - "A warm narrator.") self.assertNotIn("voice", kwargs) self.assertNotIn("clone", kwargs) + if entry.supports_instructions: + # Design requires it; supported entries forward + # it as an optional delivery/style control. + expected = set(expected) | \ + {"sglomni.instructions"} + self.assertEqual(kwargs.get("instructions"), + "A warm narrator.") self.assertEqual(shown, expected) @@ -3521,7 +3529,8 @@ class SettingsTests(unittest.TestCase): # Keys _apply_settings persists; every test that triggers a real or # fake config write restores these afterwards. _SETTING_KEYS = ("AUDIO_FORMAT", "AUDIO_BITRATE", "LANGUAGE", - "CHUNK_SIZE", "INPUT_DIR", "OUTPUT_DIR", + "CHUNK_SIZE", "SMART_CHUNKING", "INPUT_DIR", + "OUTPUT_DIR", "CLONE_WAV_DIR", "SPEED", "DEBUG", "STOP_SERVER_AND_EXIT", "AUDIOCPP_UNLOAD_MODELS", @@ -3556,12 +3565,13 @@ class SettingsTests(unittest.TestCase): self.assertTrue(hub.common.update_config_value( key, value, config_path=path)) text = path.read_text(encoding="utf-8") + # Strings render as proper Python literals (repr). self.assertEqual( text, "# Default output options\n" - 'AUDIO_FORMAT = "mp3"\n' - 'AUDIO_BITRATE = "192k"\n' - 'LANGUAGE = "Japanese"\n' + "AUDIO_FORMAT = 'mp3'\n" + "AUDIO_BITRATE = '192k'\n" + "LANGUAGE = 'Japanese'\n" "\n" "CHUNK_SIZE = 300 # words per request\n") # The imported module mirrors the file immediately. @@ -3596,6 +3606,7 @@ class SettingsTests(unittest.TestCase): original_folders[1]) values = {"audio_format": "ogg", "audio_bitrate": " 192k ", "language": "en", "chunk_size": "300", + "smart_chunking": True, "input_dir": " /books ", "output_dir": "/audiobooks", "clone_wav_dir": " /refs/wavs ", "speed": "1.5", "debug": True, @@ -3618,6 +3629,7 @@ class SettingsTests(unittest.TestCase): "AUDIO_BITRATE": "192k", "LANGUAGE": "English", "CHUNK_SIZE": 300, + "SMART_CHUNKING": True, "INPUT_DIR": "/books", "OUTPUT_DIR": "/audiobooks", "CLONE_WAV_DIR": "/refs/wavs", @@ -3644,6 +3656,7 @@ class SettingsTests(unittest.TestCase): self.assertEqual(hub.config.AUDIO_BITRATE, "192k") self.assertEqual(hub.config.LANGUAGE, "English") self.assertEqual(hub.config.CHUNK_SIZE, 300) + self.assertEqual(hub.config.SMART_CHUNKING, True) self.assertEqual(hub.config.INPUT_DIR, "/books") self.assertEqual(hub.config.OUTPUT_DIR, "/audiobooks") self.assertEqual(hub.config.CLONE_WAV_DIR, "/refs/wavs") @@ -3663,6 +3676,7 @@ class SettingsTests(unittest.TestCase): self._snapshot_settings() base = {"audio_format": "m4b", "audio_bitrate": "128k", "language": "English", "chunk_size": "250", + "smart_chunking": True, "input_dir": "./input", "output_dir": "./output", "clone_wav_dir": "./voices", "speed": "1.0", "debug": False, @@ -3693,9 +3707,46 @@ class SettingsTests(unittest.TestCase): "audiocpp_remote_url": "not a url"}) mk_update.assert_not_called() + def test_smart_chunking_toggle_persists(self): + self._snapshot_settings() + + def fake_update(key, value, config_path=None): + setattr(hub.config, key, value) + return True + + values = {"audio_format": "m4b", "audio_bitrate": "128k", + "language": "English", "chunk_size": "250", + "smart_chunking": False, + "input_dir": "./input", "output_dir": "./output", + "clone_wav_dir": "./voices", + "speed": "1.0", "debug": False, + "stop_and_exit": True, "unload_models": True, + "qwen_port": "7860", + "faster_port": "8000", "audiocpp_port": "8080", + "sglomni_port": "8100"} + with patch.object(hub.common, "update_config_value", fake_update), \ + patch.object(hub, "_sync_audiocpp_server_port"): + hub._apply_settings(values) + self.assertEqual(hub.config.SMART_CHUNKING, False) + + values["smart_chunking"] = True + with patch.object(hub.common, "update_config_value", fake_update), \ + patch.object(hub, "_sync_audiocpp_server_port"): + hub._apply_settings(values) + self.assertEqual(hub.config.SMART_CHUNKING, True) + + def test_smart_chunking_field_defaults_on_with_help(self): + fields = hub._settings_fields() + field = next(f for f in fields if f["key"] == "smart_chunking") + self.assertEqual(field["kind"], "bool") + self.assertEqual(field["value"], hub.config.SMART_CHUNKING) + self.assertTrue(field["help"]) + self.assertTrue(field["label"], "Smart chunking") + def test_field_validators(self): self.assertIsNone(hub._validate_bitrate("128k")) self.assertIsNotNone(hub._validate_bitrate(" ")) + self.assertIsNotNone(hub._validate_bitrate(" ")) self.assertIsNone(hub._validate_language("English")) self.assertIsNone(hub._validate_language("en")) self.assertIsNotNone(hub._validate_language("Klingon")) @@ -3786,6 +3837,7 @@ class SettingsTests(unittest.TestCase): captured["fields"] = fields return {"audio_format": "ogg", "audio_bitrate": "192k", "language": "English", "chunk_size": "300", + "smart_chunking": True, "input_dir": "/books", "output_dir": "/audiobooks", "clone_wav_dir": "/refs/wavs", "speed": "1.0", "debug": False, @@ -3809,7 +3861,8 @@ class SettingsTests(unittest.TestCase): hub._Hub(None).screen_settings() self.assertEqual([f["key"] for f in captured["fields"]], ["audio_format", "audio_bitrate", "language", - "chunk_size", "input_dir", "output_dir", + "chunk_size", "smart_chunking", "input_dir", + "output_dir", "clone_wav_dir", "speed", "debug", "stop_and_exit", "unload_models", @@ -3859,6 +3912,7 @@ class SettingsTests(unittest.TestCase): "audio_bitrate": "192k", "language": "English", "chunk_size": "300", + "smart_chunking": True, "input_dir": "/books", "output_dir": "/audiobooks", "clone_wav_dir": "/refs/wavs", @@ -4012,7 +4066,8 @@ class SettingsTests(unittest.TestCase): original = {name: getattr(hub.config, name) for name in ("AUDIO_FORMAT", "AUDIO_BITRATE", "LANGUAGE", - "CHUNK_SIZE", "INPUT_DIR", "OUTPUT_DIR", + "CHUNK_SIZE", "SMART_CHUNKING", "INPUT_DIR", + "OUTPUT_DIR", "CLONE_WAV_DIR", "SPEED", "DEBUG", "STOP_SERVER_AND_EXIT", "AUDIOCPP_UNLOAD_MODELS", @@ -4034,6 +4089,7 @@ class SettingsTests(unittest.TestCase): 'LANGUAGE = "English"\n' "\n" "CHUNK_SIZE = 250\n" + "SMART_CHUNKING = True\n" 'INPUT_DIR = "./input"\n' 'OUTPUT_DIR = "./output"\n' 'CLONE_WAV_DIR = "./voices"\n' @@ -4062,10 +4118,11 @@ class SettingsTests(unittest.TestCase): text = path.read_text(encoding="utf-8") self.assertIn('AUDIO_FORMAT = "m4b"', text) self.assertIn("CHUNK_SIZE = 300", text) - # The settings-only fields are written back unchanged. - self.assertIn('INPUT_DIR = "', text) - self.assertIn('OUTPUT_DIR = "', text) - self.assertIn('CLONE_WAV_DIR = "', text) + # The settings-only fields are written back (as repr string + # literals for the values the menu saved). + self.assertIn("INPUT_DIR = '/workspace/input'", text) + self.assertIn("OUTPUT_DIR = '/workspace/output'", text) + self.assertIn("CLONE_WAV_DIR = '/workspace/voices'", text) self.assertIn("SPEED = 1.0", text) self.assertIn("DEBUG = False", text) # The running session also picked up the change in-memory. @@ -4092,9 +4149,33 @@ class SettingsTests(unittest.TestCase): ("AUDIOCPP_API_URL", "http://127.0.0.1:8081")): hub.common.update_config_value(key, value, config_path=path) text = path.read_text(encoding="utf-8") - self.assertIn('QWEN_API_URL = "http://127.0.0.1:7862"', text) - self.assertIn('FASTER_API_URL = "http://127.0.0.1:8001"', text) - self.assertIn('AUDIOCPP_API_URL = "http://127.0.0.1:8081"', text) + self.assertIn("QWEN_API_URL = 'http://127.0.0.1:7862'", text) + self.assertIn("FASTER_API_URL = 'http://127.0.0.1:8001'", text) + self.assertIn("AUDIOCPP_API_URL = 'http://127.0.0.1:8081'", text) + + def test_update_config_value_escapes_quotes_and_backslashes(self): + # Strings containing quotes or backslashes must stay valid, + # unchanging Python: bare double-quote quoting would corrupt + # config.py (invalidating every later start) or silently alter + # the value once backslashes became escapes. + import tempfile + self._snapshot_settings() + with tempfile.TemporaryDirectory() as td: + path = Path(td) / "config.py" + path.write_text('INPUT_DIR = "input"\n', encoding="utf-8") + self.assertTrue(hub.common.update_config_value( + "INPUT_DIR", '/books/A "quoted" title\\', config_path=path)) + text = path.read_text(encoding="utf-8") + compiled = compile(text, str(path), "exec") + scope = {} + exec(compiled, scope) + # The matcher must still find the (now weirdly quoted) value + # to update it again. + self.assertTrue(hub.common.update_config_value( + "INPUT_DIR", "plain", config_path=path)) + self.assertIn("INPUT_DIR = 'plain'", + path.read_text(encoding="utf-8")) + self.assertEqual(scope["INPUT_DIR"], '/books/A "quoted" title\\') class AudiocppServerConfigTests(unittest.TestCase): |
