From 38c8fdcba7ce54ad0ad76be9ef0748df1c55ebc1 Mon Sep 17 00:00:00 2001 From: historia Date: Thu, 20 Aug 2026 23:50:37 -0400 Subject: feat: make_audiocpp_server_json.py takes an argument. remove chunk wording with audiocpp backend. --- tests/test_make_audiocpp_server_json.py | 129 +++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 45 deletions(-) (limited to 'tests/test_make_audiocpp_server_json.py') diff --git a/tests/test_make_audiocpp_server_json.py b/tests/test_make_audiocpp_server_json.py index f9fa794..2bd262a 100644 --- a/tests/test_make_audiocpp_server_json.py +++ b/tests/test_make_audiocpp_server_json.py @@ -304,20 +304,6 @@ class PromptHelperTests(unittest.TestCase): def tearDown(self): self._tmp.cleanup() - def test_ask_wav_dir_reprompts_until_valid(self): - with patch("builtins.input", - side_effect=[str(self.folder / "nope"), - str(self.folder)]): - self.assertEqual(make_server.ask_wav_dir(), self.folder) - - def test_ask_wav_dir_empty_skips(self): - with patch("builtins.input", return_value=""): - self.assertIsNone(make_server.ask_wav_dir()) - - def test_ask_wav_dir_eof_returns_none(self): - with patch("builtins.input", side_effect=EOFError): - self.assertIsNone(make_server.ask_wav_dir()) - def test_ask_port_reprompts_until_valid(self): with patch("builtins.input", side_effect=["abc", "8081"]): self.assertEqual(make_server.ask_port(8080), 8081) @@ -341,6 +327,46 @@ class PromptHelperTests(unittest.TestCase): "one") +class ResolveWavDirArgTests(unittest.TestCase): + """Path normalization for the required WAV_DIR argument.""" + + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.folder = Path(self._tmp.name) + + def tearDown(self): + self._tmp.cleanup() + + def test_resolves_to_absolute(self): + self.assertEqual(make_server.resolve_wav_dir_arg(str(self.folder)), + self.folder.resolve()) + + def test_strips_surrounding_quotes(self): + quoted = f'"{self.folder}"' + self.assertEqual(make_server.resolve_wav_dir_arg(quoted), + self.folder.resolve()) + + def test_strips_single_quotes(self): + quoted = f"'{self.folder}'" + self.assertEqual(make_server.resolve_wav_dir_arg(quoted), + self.folder.resolve()) + + def test_strips_whitespace(self): + self.assertEqual(make_server.resolve_wav_dir_arg(f" {self.folder} "), + self.folder.resolve()) + + def test_expands_tilde(self): + with patch.object(make_server.os.path, "expanduser", + return_value=str(self.folder)) as mock_expand: + result = make_server.resolve_wav_dir_arg("~/voices") + mock_expand.assert_called_once_with("~/voices") + self.assertEqual(result, self.folder.resolve()) + + def test_trailing_slash_preserved_as_dir(self): + self.assertEqual(make_server.resolve_wav_dir_arg(f"{self.folder}/"), + self.folder.resolve()) + + class MainTests(unittest.TestCase): def setUp(self): self._tmp = tempfile.TemporaryDirectory() @@ -370,14 +396,21 @@ class MainTests(unittest.TestCase): return make_server.main() def _defaults(self, models="", host="", port="", backend="", - lazy="", custom_path="", clone_path="", wav_dir="", + lazy="", custom_path="", clone_path="", confirm="y", prefix=()): - # First input selects the model family (default: Qwen3-TTS). + # First input selects the model family (default: Qwen3-TTS). The + # wav directory is always a positional argument, never prompted. return list(prefix) + ["", models, host, port, backend, lazy, - custom_path, clone_path, wav_dir, confirm] + custom_path, clone_path, confirm] + + def test_required_wav_dir_missing_prints_usage(self): + with self.assertRaises(SystemExit) as ctx: + self._run(["--output", str(self.output)], inputs=[]) + self.assertEqual(ctx.exception.code, 2) + self.assertFalse(self.output.exists()) def test_default_run_hosts_both_models(self): - exit_code = self._run(["--output", str(self.output)], + exit_code = self._run([str(self.folder), "--output", str(self.output)], inputs=self._defaults()) self.assertEqual(exit_code, 0) data = json.loads(self.output.read_text(encoding="utf-8")) @@ -395,7 +428,7 @@ class MainTests(unittest.TestCase): self.assertNotIn("voice_presets", data["models"][1]) def test_eof_uses_all_defaults(self): - exit_code = self._run(["--output", str(self.output)]) + exit_code = self._run([str(self.folder), "--output", str(self.output)]) self.assertEqual(exit_code, 0) data = json.loads(self.output.read_text(encoding="utf-8")) self.assertEqual(data["host"], "127.0.0.1") @@ -427,7 +460,7 @@ class MainTests(unittest.TestCase): def test_custom_only_single_model(self): inputs = ["", "", "", "", "", "", "y"] exit_code = self._run( - ["--output", str(self.output), "--models", "custom"], + [str(self.folder), "--output", str(self.output), "--models", "custom"], inputs=inputs) self.assertEqual(exit_code, 0) data = json.loads(self.output.read_text(encoding="utf-8")) @@ -437,8 +470,8 @@ class MainTests(unittest.TestCase): def test_duplicate_ids_prompt_for_distinct_clone_id(self): with patch.object(config, "AUDIOCPP_MODEL_ID", "qwen"), \ patch.object(config, "AUDIOCPP_CLONE_MODEL_ID", "qwen"): - inputs = ["", "1", "qwen-clone-2", "", "", "", "", "", "", "", "y"] - exit_code = self._run(["--output", str(self.output)], + inputs = ["", "1", "qwen-clone-2", "", "", "", "", "", "", "y"] + exit_code = self._run([str(self.folder), "--output", str(self.output)], inputs=inputs) self.assertEqual(exit_code, 0) data = json.loads(self.output.read_text(encoding="utf-8")) @@ -449,7 +482,7 @@ class MainTests(unittest.TestCase): with patch.object(config, "AUDIOCPP_MODEL_ID", "qwen"), \ patch.object(config, "AUDIOCPP_CLONE_MODEL_ID", "qwen"): with self.assertRaises(SystemExit) as ctx: - self._run(["--output", str(self.output)]) + self._run([str(self.folder), "--output", str(self.output)]) self.assertNotEqual(ctx.exception.code, 0) self.assertFalse(self.output.exists()) @@ -457,7 +490,7 @@ class MainTests(unittest.TestCase): with patch.object(config, "AUDIOCPP_API_URL", "http://127.0.0.1:9999"): inputs = ["", "", "", "y", "", "", "", "", "", "y"] - exit_code = self._run(["--output", str(self.output), + exit_code = self._run([str(self.folder), "--output", str(self.output), "--port", "8080"], inputs=inputs) self.assertEqual(exit_code, 0) @@ -470,7 +503,7 @@ class MainTests(unittest.TestCase): with patch.object(config, "AUDIOCPP_API_URL", "http://127.0.0.1:9999"): inputs = ["", "", "", "n", "", "", "", "", "", "y"] - exit_code = self._run(["--output", str(self.output), + exit_code = self._run([str(self.folder), "--output", str(self.output), "--port", "8080"], inputs=inputs) self.assertEqual(exit_code, 0) @@ -481,7 +514,7 @@ class MainTests(unittest.TestCase): with patch.object(config, "AUDIOCPP_API_URL", "http://127.0.0.1:8080"): inputs = self._defaults() - exit_code = self._run(["--output", str(self.output)], + exit_code = self._run([str(self.folder), "--output", str(self.output)], inputs=inputs) self.assertEqual(exit_code, 0) self.assertEqual(self.fake_config.read_text(encoding="utf-8"), @@ -489,8 +522,8 @@ class MainTests(unittest.TestCase): def test_invalid_menu_choice_reprompts(self): # Family menu default, then an invalid models-menu choice retried. - inputs = ["", "9", "", "", "", "", "", "", "", "", "y"] - exit_code = self._run(["--output", str(self.output)], + inputs = ["", "9", "", "", "", "", "", "", "", "y"] + exit_code = self._run([str(self.folder), "--output", str(self.output)], inputs=inputs) self.assertEqual(exit_code, 0) data = json.loads(self.output.read_text(encoding="utf-8")) @@ -498,14 +531,14 @@ class MainTests(unittest.TestCase): def test_confirm_declined_writes_nothing(self): inputs = self._defaults(confirm="n") - exit_code = self._run(["--output", str(self.output)], + exit_code = self._run([str(self.folder), "--output", str(self.output)], inputs=inputs) self.assertEqual(exit_code, 1) self.assertFalse(self.output.exists()) def test_existing_output_declined_keeps_file(self): self.output.write_text('{"old": true}', encoding="utf-8") - exit_code = self._run(["--output", str(self.output)], + exit_code = self._run([str(self.folder), "--output", str(self.output)], inputs=["n"]) self.assertEqual(exit_code, 1) self.assertEqual(json.loads(self.output.read_text(encoding="utf-8")), @@ -514,7 +547,7 @@ class MainTests(unittest.TestCase): def test_existing_output_accepted_overwrites(self): self.output.write_text('{"old": true}', encoding="utf-8") inputs = ["y"] + self._defaults() - exit_code = self._run(["--output", str(self.output)], + exit_code = self._run([str(self.folder), "--output", str(self.output)], inputs=inputs) self.assertEqual(exit_code, 0) data = json.loads(self.output.read_text(encoding="utf-8")) @@ -523,7 +556,8 @@ class MainTests(unittest.TestCase): def test_force_overwrites_without_prompt(self): self.output.write_text('{"old": true}', encoding="utf-8") inputs = self._defaults() - exit_code = self._run(["--output", str(self.output), "--force"], + exit_code = self._run([str(self.folder), "--output", str(self.output), + "--force"], inputs=inputs) self.assertEqual(exit_code, 0) data = json.loads(self.output.read_text(encoding="utf-8")) @@ -531,13 +565,13 @@ class MainTests(unittest.TestCase): def test_flags_skip_prompts(self): # Family still asked (no --family flag); port 9000 differs from the - # config port so its sync prompt fires; custom/clone paths and the - # wav dir use their defaults. + # config port so its sync prompt fires; custom/clone paths use + # their defaults. exit_code = self._run( - ["--output", str(self.output), "--models", "both", + [str(self.folder), "--output", str(self.output), "--models", "both", "--host", "0.0.0.0", "--port", "9000", "--backend", "cpu", "--lazy-load"], - inputs=["", "y", "", "", "", "y"]) + inputs=["", "y", "", "", "y"]) self.assertEqual(exit_code, 0) self.assertIn('"http://127.0.0.1:9000"', self.fake_config.read_text(encoding="utf-8")) @@ -548,11 +582,15 @@ class MainTests(unittest.TestCase): self.assertTrue(data["lazy_load"]) def test_missing_positional_wav_dir_errors(self): - with self.assertRaises(SystemExit) as ctx: - self._run([str(self.folder / "nope"), - "--output", str(self.output)], + missing = self.folder / "nope" + with self.assertRaises(SystemExit) as ctx, \ + patch("sys.stderr") as mock_stderr: + self._run([str(missing), "--output", str(self.output)], inputs=self._defaults()) self.assertEqual(ctx.exception.code, 2) + shown = "".join(call[0][0] for call in mock_stderr.write.call_args_list) + self.assertIn(f"WAV directory not found: {missing.resolve()}", shown) + self.assertIn("directory containing the .wav", shown) class NonQwenFamilyMainTests(unittest.TestCase): @@ -613,10 +651,10 @@ class NonQwenFamilyMainTests(unittest.TestCase): self.fake_config.read_text(encoding="utf-8")) def test_model_id_sync_declined_keeps_config(self): - # sync declined, host, port, backend, lazy, wav dir skipped, confirm - inputs = ["n", "", "", "", "", "", "y"] + # sync declined, host, port, backend, lazy, confirm + inputs = ["n", "", "", "", "", "y"] exit_code = self._run( - ["--output", str(self.output), "--family", "voxcpm2", + [str(self.folder), "--output", str(self.output), "--family", "voxcpm2", "--model-id", "voxcpm2", "--model-path", "models/VoxCPM2-GGUF"], inputs=inputs) self.assertEqual(exit_code, 0) @@ -628,13 +666,14 @@ class NonQwenFamilyMainTests(unittest.TestCase): def test_no_voice_presets_warns(self): buf = io.StringIO() - # sync accepted, host, port, backend, lazy, wav dir skipped, confirm + # sync accepted, host, port, backend, lazy, confirm with patch.object(sys, "argv", ["make_audiocpp_server_json.py", + str(self.folder), "--output", str(self.output), "--family", "index_tts2", "--model-id", "indextts2", "--model-path", "models/IndexTTS2-GGUF"]), \ - patch("builtins.input", side_effect=["y", "", "", "", "", "", "y"]), \ + patch("builtins.input", side_effect=["y", "", "", "", "", "y"]), \ patch.object(make_server, "transcribe_reference_audio"), \ patch.object(make_server, "whisper_backend_available", return_value="faster_whisper"), \ @@ -649,7 +688,7 @@ class NonQwenFamilyMainTests(unittest.TestCase): def test_models_flag_rejected_for_non_qwen_family(self): with self.assertRaises(SystemExit) as ctx: - self._run(["--output", str(self.output), + self._run([str(self.folder), "--output", str(self.output), "--family", "higgs_audio_tts", "--models", "both"]) self.assertEqual(ctx.exception.code, 2) -- cgit v1.2.3