diff options
Diffstat (limited to 'app/tests/test_backends_faster.py')
| -rw-r--r-- | app/tests/test_backends_faster.py | 161 |
1 files changed, 136 insertions, 25 deletions
diff --git a/app/tests/test_backends_faster.py b/app/tests/test_backends_faster.py index 800acb0..c03f031 100644 --- a/app/tests/test_backends_faster.py +++ b/app/tests/test_backends_faster.py @@ -5,7 +5,6 @@ import sys import tempfile import threading import unittest -import contextlib from pathlib import Path from unittest.mock import patch @@ -126,37 +125,58 @@ class DecideFasterTranscriptionTests(unittest.TestCase): self._tmp.cleanup() def test_new_voices_default_to_missing_mode(self): - confirm = lambda q, default=True: True # noqa: E731 - plan = make_voices._decide_faster_transcription( + choices, default = make_voices._decide_faster_transcription( [self.narrator, self.new_voice], - {"narrator": {"ref_text": "old"}}, confirm) + {"narrator": {"ref_text": "old"}}) + self.assertEqual(default, "missing") + modes = [mode for _label, mode in choices] + self.assertIn("missing", modes) + self.assertIn("all", modes) + missing = [w for w in (self.narrator, self.new_voice) + if w.stem not in {"narrator"}] + plan = make_voices._plan_for("missing", self.folder, + {"narrator": {"ref_text": "old"}}) self.assertEqual(plan["mode"], "missing") - self.assertEqual([w.name for w in plan["missing"]], ["new.wav"]) + self.assertEqual([w.name for w in plan["missing"]], + [w.name for w in missing]) def test_declining_new_voices_transcribes_all(self): - confirm = lambda q, default=True: False # noqa: E731 - plan = make_voices._decide_faster_transcription( + choices, default = make_voices._decide_faster_transcription( [self.narrator, self.new_voice], - {"narrator": {"ref_text": "old"}}, confirm) + {"narrator": {"ref_text": "old"}}) + # Re-transcribing everything stays available alongside new-only. + modes = [mode for _label, mode in choices] + self.assertIn("all", modes) + plan = make_voices._plan_for("all", self.folder, + {"narrator": {"ref_text": "old"}}) self.assertEqual(plan["mode"], "all") - def test_no_new_voices_offers_retranscribe_default_no(self): - confirm = lambda q, default=True: default # noqa: E731 - plan = make_voices._decide_faster_transcription( - [self.narrator], {"narrator": {"ref_text": "old"}}, confirm) - self.assertEqual(plan["mode"], "keep") - - def test_no_new_voices_accepted_retranscribes_all(self): - confirm = lambda q, default=True: True # noqa: E731 - plan = make_voices._decide_faster_transcription( - [self.narrator], {"narrator": {"ref_text": "old"}}, confirm) + def test_no_new_voices_offers_retranscribe_default_keep(self): + choices, default = make_voices._decide_faster_transcription( + [self.narrator], {"narrator": {"ref_text": "old"}}) + self.assertEqual(default, "keep") + modes = [mode for _label, mode in choices] + self.assertEqual(modes, ["keep", "all"]) + + def test_no_new_voices_can_retranscribe_all(self): + _choices, _default = make_voices._decide_faster_transcription( + [self.narrator], {"narrator": {"ref_text": "old"}}) + plan = make_voices._plan_for("all", self.folder, + {"narrator": {"ref_text": "old"}}) self.assertEqual(plan["mode"], "all") - def test_cancel_returns_none(self): - confirm = lambda q, default=True: None # noqa: E731 - plan = make_voices._decide_faster_transcription( - [self.narrator], {"narrator": {"ref_text": "old"}}, confirm) - self.assertIsNone(plan) + def test_choice_labels_are_the_renamed_ones(self): + # The option names shown for the Voice-transcripts choice. + with_new, _ = make_voices._decide_faster_transcription( + [self.narrator, self.new_voice], + {"narrator": {"ref_text": "old"}}) + self.assertEqual([label for label, _mode in with_new], + ["Only transcribe new voices", "Re-transcribe all"]) + without_new, _ = make_voices._decide_faster_transcription( + [self.narrator], {"narrator": {"ref_text": "old"}}) + self.assertEqual([label for label, _mode in without_new], + ["Keep the existing voices.json", + "Re-transcribe all"]) class MainTests(unittest.TestCase): @@ -273,8 +293,99 @@ class MainTests(unittest.TestCase): self.assertEqual(list(data), ["alpha", "narrator"]) -if __name__ == "__main__": - unittest.main() +class WizardFormTests(unittest.TestCase): + """The faster wizard: one combined form instead of a screen chain.""" + + def _args(self, *extra): + return make_voices.build_parser().parse_args(list(extra)) + + def _wavs(self): + tmp = tempfile.TemporaryDirectory() + self.addCleanup(tmp.cleanup) + folder = Path(tmp.name) + (folder / "narrator.wav").write_bytes(b"x") + return folder + + def test_fresh_run_asks_one_form_without_transcription_choice(self): + folder = self._wavs() + captured = {} + + def fake_form(stdscr, title, fields, **kwargs): + captured["title"] = title + captured["keys"] = [f["key"] for f in fields] + by_key = {f["key"]: f for f in fields} + by_key["wav_dir"]["value"] = folder + return {f["key"]: f["value"] for f in fields} + + with patch.object(make_voices, "_is_installed", return_value=True), \ + patch.object(make_voices, "_is_cloned", return_value=True), \ + patch.object(make_voices.tui, "form", + side_effect=fake_form) as mk_form: + settings = make_voices._wizard( + None, self._args("--output", str(folder / "voices.json"), + "--skip-install", "--skip-clone")) + self.assertIsNotNone(settings) + self.assertEqual(mk_form.call_count, 1) + self.assertEqual(captured["keys"], + ["wav_dir", "language", "whisper_model"]) + self.assertEqual(settings["wav_dir"], folder) + # Nothing was configured before, so everything is transcribed and + # no keep/new-only choice exists. + self.assertEqual(settings["plan"]["mode"], "all") + + def test_modify_run_offers_transcription_modes(self): + folder = self._wavs() + (folder / "new.wav").write_bytes(b"x") # a voice not in voices.json + output = folder / "voices.json" + existing = {"narrator": { + "ref_audio": str(folder / "narrator.wav"), + "ref_text": "old transcript", "language": "English"}} + output.write_text(json.dumps(existing), encoding="utf-8") + captured = {} + + def fake_form(stdscr, title, fields, **kwargs): + captured["keys"] = [f["key"] for f in fields] + by_key = {f["key"]: f for f in fields} + self.assertIn("transcription", by_key) + modes = [mode for _label, mode in by_key[ + "transcription"]["choices"](fields)] + # New .wavs exist, so both transcribing only those and + # re-transcribing everything are offered. + self.assertEqual(modes, ["missing", "all"]) + result = {f["key"]: f["value"] for f in fields} + result["transcription"] = "missing" + return result + + with patch.object(make_voices, "_is_installed", return_value=True), \ + patch.object(make_voices, "_is_cloned", return_value=True), \ + patch.object(make_voices.tui, "form", + side_effect=fake_form): + settings = make_voices._wizard( + None, self._args("--output", str(output), + "--skip-install", "--skip-clone")) + self.assertIsNotNone(settings) + self.assertEqual(captured["keys"], + ["wav_dir", "language", "whisper_model", + "transcription"]) + self.assertEqual(settings["plan"]["mode"], "missing") + self.assertEqual([w.name for w in settings["plan"]["missing"]], + ["new.wav"]) + self.assertEqual(settings["wav_dir"], folder) + + def test_cancel_aborts(self): + with patch.object(make_voices, "_is_installed", return_value=True), \ + patch.object(make_voices, "_is_cloned", return_value=True), \ + patch.object(make_voices.tui, "form", + side_effect=lambda *a, **k: k["back_value"]): + settings = make_voices._wizard( + None, self._args("--output", "/tmp/x.json", + "--skip-install", "--skip-clone")) + self.assertIsNone(settings) + + def test_port_flag_removed(self): + parser = make_voices.build_parser() + with self.assertRaises(SystemExit): + parser.parse_args(["--port", "8000"]) class SetupScreenTests(unittest.TestCase): |
