diff options
Diffstat (limited to 'app/tests/test_audiobook_cli.py')
| -rw-r--r-- | app/tests/test_audiobook_cli.py | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/app/tests/test_audiobook_cli.py b/app/tests/test_audiobook_cli.py index ab13107..f25ec23 100644 --- a/app/tests/test_audiobook_cli.py +++ b/app/tests/test_audiobook_cli.py @@ -334,6 +334,80 @@ class ConvertWiringTests(unittest.TestCase): self._convert(output_file=self.tmp / "dune.mp3") +class SglomniChunkClampTests(unittest.TestCase): + """convert(backend="sglomni"): the chunk-cap popup runs pre-flight + for CLI runs and its answer rides chunk_size into the converter.""" + + def setUp(self): + self.tmp = Path(tempfile.mkdtemp(prefix="audiobook_sglomni_")) + self.addCleanup(shutil.rmtree, self.tmp, True) + self.book = _make_book(self.tmp) + self._old_folders = (converter_mod.BOOKS_FOLDER, + converter_mod.AUDIOBOOKS_FOLDER) + self.addCleanup(self._restore_folders) + + def _restore_folders(self): + converter_mod.BOOKS_FOLDER, converter_mod.AUDIOBOOKS_FOLDER = \ + self._old_folders + + def _convert(self, *, prompt=None, **kwargs): + """Run convert() for a higgs run with the prompt mocked. + + PROMPT replaces converter.prompt_chunk_clamp (default: a MagicMock + answering 80). Returns (code, prompt mock, converter ctor kwargs). + """ + if prompt is None: + prompt = MagicMock(return_value=80) + preflight = MagicMock( + return_value=([self.book], [(self.book, "dune")])) + fake_instance = MagicMock() + fake_instance.run.return_value = True + fake_class = MagicMock(return_value=fake_instance) + fake_class.preflight_overwrites = preflight + stdout = io.StringIO() + with patch.object(audiobook, "setup_logging"), \ + patch.object(audiobook, "setup_directories"), \ + patch.object(audiobook, "AudiobookConverter", fake_class), \ + patch.object(converter_mod, "prompt_chunk_clamp", prompt), \ + contextlib.redirect_stdout(stdout): + code = audiobook.convert( + backend="sglomni", model_id="higgs_audio_v3_tts", + api_url="http://127.0.0.1:8100", **kwargs) + # A cancelled run stops before any converter is constructed. + ctor = (fake_class.call_args.kwargs + if fake_class.call_args is not None else None) + return code, prompt, stdout, ctor + + def test_cli_run_asks_and_carries_the_clamp(self): + code, prompt, _, ctor = self._convert() + self.assertEqual(code, 0) + self.assertEqual(prompt.call_args[0][0].key, "higgs_audio_v3_tts") + self.assertEqual(ctor["chunk_size"], 80) + + def test_prompt_anyway_sends_no_clamp(self): + _, prompt, _, ctor = self._convert( + prompt=MagicMock(return_value=None)) + self.assertIsNone(ctor["chunk_size"]) + + def test_prompt_cancel_stops_the_run_unstarted(self): + def cancel(entry): + raise converter_mod.ChunkClampCancelled("cancelled") + code, prompt, stdout, ctor = self._convert(prompt=cancel) + self.assertEqual(code, 0) + self.assertIn("Conversion cancelled", stdout.getvalue()) + self.assertFalse(ctor) + + def test_hub_run_with_a_plan_skips_the_prompt(self): + # The hub pre-flights inside the TUI (where the popup lives) and + # carries the answer as chunk_size; convert() must not re-ask. + _, prompt, _, ctor = self._convert( + prompt=MagicMock(side_effect=AssertionError("should not ask")), + book_files=[self.book], + planned=[(self.book, "dune")], + chunk_size=80) + self.assertEqual(ctor["chunk_size"], 80) + + class AllModelsConvertTests(unittest.TestCase): """convert(model_ids=...): the "All (multiple generation)" loop. |
