aboutsummaryrefslogtreecommitdiff
path: root/app/tests/test_backends_common.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-24 23:49:34 -0400
committerhistoria <historiavg@proton.me>2026-08-24 23:49:34 -0400
commitfe4b2b9eb7fb8aac81f65630720c9079d0a3121a (patch)
tree9c5e5f56d0b931d25e6580f10d09453505eddc2f /app/tests/test_backends_common.py
parentf4b1de303704e13818259d5057d176cd841b6ed8 (diff)
downloadtts-audiobook-generator-fe4b2b9eb7fb8aac81f65630720c9079d0a3121a.tar.gz
feat: user-friendly menu gating, clearer install/configure path for backends
Diffstat (limited to 'app/tests/test_backends_common.py')
-rw-r--r--app/tests/test_backends_common.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/app/tests/test_backends_common.py b/app/tests/test_backends_common.py
new file mode 100644
index 0000000..b8a8e90
--- /dev/null
+++ b/app/tests/test_backends_common.py
@@ -0,0 +1,76 @@
+"""Tests for backends.common subprocess/git helpers.
+
+The streaming mode of ``run_console_subprocess`` (used by the in-TUI task
+view) is exercised with a real child process: output lines are captured and
+forwarded, cancellation kills the child and returns 130, and an on_cancel
+hook runs first.
+"""
+
+import sys
+import threading
+import unittest
+from unittest import mock
+
+from backends import common
+
+
+class RunConsoleSubprocessStreamingTests(unittest.TestCase):
+ def test_streaming_emits_merged_lines(self):
+ lines = []
+ rc = common.run_console_subprocess(
+ [sys.executable, "-c",
+ "import sys; sys.stdout.write('hello\\nworld\\n'); "
+ "sys.stderr.write('oops\\n')"],
+ emit=lines.append)
+ self.assertEqual(rc, 0)
+ # stdout/stderr are merged, in arrival order.
+ self.assertEqual(sorted(lines), ["hello", "oops", "world"])
+
+ def test_streaming_returns_the_exit_code(self):
+ rc = common.run_console_subprocess(
+ [sys.executable, "-c", "import sys; sys.exit(3)"],
+ emit=lambda line: None)
+ self.assertEqual(rc, 3)
+
+ def test_cancel_kills_the_process_and_returns_130(self):
+ cancel = threading.Event()
+ cancel.set()
+ rc = common.run_console_subprocess(
+ [sys.executable, "-c", "import time; time.sleep(60)"],
+ emit=lambda line: None, cancel=cancel)
+ self.assertEqual(rc, 130)
+
+ def test_on_cancel_hook_runs_before_kill(self):
+ cancel = threading.Event()
+ cancel.set()
+ touched = []
+ common.run_console_subprocess(
+ [sys.executable, "-c", "import time; time.sleep(60)"],
+ emit=lambda line: None, cancel=cancel,
+ on_cancel=lambda: touched.append(True))
+ self.assertEqual(touched, [True])
+
+
+class GitCloneTests(unittest.TestCase):
+ def test_git_clone_console_passes_through(self):
+ with mock.patch.object(common, "run_console_subprocess",
+ return_value=0) as run:
+ self.assertEqual(common.git_clone("url", common.Path("/t")), 0)
+ # Console mode: no --progress flag, plain git clone.
+ self.assertEqual(run.call_args[0][0],
+ ["git", "clone", "url", "/t"])
+
+ def test_git_clone_streaming_adds_progress(self):
+ emit = lambda line: None
+ with mock.patch.object(common, "run_console_subprocess",
+ return_value=0) as run:
+ self.assertEqual(common.git_clone("url", common.Path("/t"),
+ emit=emit), 0)
+ argv = run.call_args[0][0]
+ self.assertEqual(argv[:3], ["git", "clone", "--progress"])
+ self.assertIn("url", argv)
+ self.assertEqual(run.call_args[1]["emit"], emit)
+
+
+if __name__ == "__main__":
+ unittest.main()