aboutsummaryrefslogtreecommitdiff
path: root/app/tests/test_audiobook_cli.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/tests/test_audiobook_cli.py')
-rw-r--r--app/tests/test_audiobook_cli.py74
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.