diff options
Diffstat (limited to 'app/tests/test_runview.py')
| -rw-r--r-- | app/tests/test_runview.py | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/app/tests/test_runview.py b/app/tests/test_runview.py index 7006427..556cb52 100644 --- a/app/tests/test_runview.py +++ b/app/tests/test_runview.py @@ -7,8 +7,11 @@ own queue to exercise state transitions, rendering, and the Esc/q cancel → stop-server flow. """ +import os import sys +import tempfile import unittest +from queue import Empty from unittest.mock import patch from tests.test_tui import FakeCurses, FakeScreen @@ -234,5 +237,51 @@ class RunLoopTests(_FakeTui, unittest.TestCase): mk_stop.assert_not_called() +class WorkerTests(_FakeTui, unittest.TestCase): + """The worker thread's handoff into audiobook.convert.""" + + def make_view(self, **cfg): + screen = FakeScreen() + return runview.RunView(screen, _config(**cfg), clock=lambda: 1000.0) + + def _drain(self, view): + events = [] + while True: + try: + events.append(view._queue.get_nowait()) + except Empty: + return events + + def test_book_files_reach_convert_once(self): + # Regression: _preflight stashes book_files/planned in the form + # kwargs and RunConfig carries them as fields too; passing both to + # convert() raised "got multiple values for keyword argument". + view = self.make_view( + kwargs={"voice": "alloy", "book_files": ["b.txt"], + "planned": ["b.txt"]}, + book_files=["b.txt"], planned=["b.txt"]) + with patch("audiobook.convert") as mk_convert: + view._worker_main() + _, kw = mk_convert.call_args + self.assertEqual(kw["book_files"], ["b.txt"]) + self.assertEqual(kw["planned"], ["b.txt"]) + self.assertEqual(kw["voice"], "alloy") + self.assertNotIn("error", [e["kind"] for e in self._drain(view)]) + + def test_worker_error_is_appended_to_the_dated_log(self): + # A crash before convert() configures logging must still leave its + # trace in the file the failure screen points at. + with tempfile.TemporaryDirectory() as tmp: + log_path = os.path.join(tmp, "audiobook_20260825.log") + view = self.make_view(log_path=log_path) + with patch("audiobook.convert", + side_effect=TypeError("boom")): + view._worker_main() + with open(log_path, encoding="utf-8") as handle: + text = handle.read() + self.assertIn("ERROR - boom", text) + self.assertIn("error", [e["kind"] for e in self._drain(view)]) + + if __name__ == "__main__": unittest.main() |
