diff options
Diffstat (limited to 'app/tests/test_runview.py')
| -rw-r--r-- | app/tests/test_runview.py | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/app/tests/test_runview.py b/app/tests/test_runview.py index f2d5180..8feeee1 100644 --- a/app/tests/test_runview.py +++ b/app/tests/test_runview.py @@ -10,6 +10,7 @@ cancel → stop-server flow. import os import sys import tempfile +import types import unittest from queue import Empty from unittest.mock import patch @@ -129,6 +130,70 @@ class StateTransitionTests(_FakeTui, unittest.TestCase): self.assertEqual(view.server, "stopped") +class LogAppenderTests(_FakeTui, unittest.TestCase): + """_LogAppender: stray console output survives in the run's log file.""" + + def _appender(self): + tmp = tempfile.TemporaryDirectory() + self.addCleanup(tmp.cleanup) + path = os.path.join(tmp.name, "audiobook_20260828.log") + return path, runview._LogAppender(path) + + def test_write_splits_lines_into_the_file(self): + path, appender = self._appender() + appender.write("one\ntwo\n") + appender.write("three") + appender.flush() + with open(path, encoding="utf-8") as handle: + lines = handle.read().splitlines() + self.assertEqual(len(lines), 3) + self.assertTrue(lines[0].endswith(" - one")) + self.assertTrue(lines[2].endswith(" - three")) + + def test_blank_lines_and_empty_path_are_skipped(self): + path, appender = self._appender() + appender.write("\n\n") + appender.flush() + appender.write("x") + appender.flush() + empty = runview._LogAppender("") + empty.write("ignored\n") # must not raise + with open(path, encoding="utf-8") as handle: + self.assertEqual(len(handle.read().splitlines()), 1) + + def test_unwritable_path_never_raises(self): + appender = runview._LogAppender("/nonexistent-dir-zz/log.log") + appender.write("boom\n") # must not raise + appender.flush() + + def test_worker_stdout_is_mirrored_to_the_run_log(self): + tmp = tempfile.TemporaryDirectory() + self.addCleanup(tmp.cleanup) + log_path = os.path.join(tmp.name, "audiobook_20260828.log") + view, _ = self.make_view(log_path=log_path) + + fake = types.ModuleType("audiobook") + + def convert(**_kwargs): + print("[INFO] stray console output") + + fake.convert = convert + with patch.dict(sys.modules, {"audiobook": fake}): + view._worker_main() + + with open(log_path, encoding="utf-8") as handle: + text = handle.read() + self.assertIn("[INFO] stray console output", text) + # The worker signed off normally through the event queue. + kinds = [] + while True: + try: + kinds.append(view._queue.get_nowait()["kind"]) + except Empty: + break + self.assertEqual(kinds, ["worker_exit"]) + + class RenderTests(_FakeTui, unittest.TestCase): def _strings(self, screen): return " ".join(text for _, _, text, _ in screen.strings) |
