aboutsummaryrefslogtreecommitdiff
path: root/app/tests
diff options
context:
space:
mode:
Diffstat (limited to 'app/tests')
-rw-r--r--app/tests/test_backends.py6
-rw-r--r--app/tests/test_backends_audiocpp.py81
-rw-r--r--app/tests/test_hub.py8
-rw-r--r--app/tests/test_tui.py20
4 files changed, 107 insertions, 8 deletions
diff --git a/app/tests/test_backends.py b/app/tests/test_backends.py
index 15a8649..99742f3 100644
--- a/app/tests/test_backends.py
+++ b/app/tests/test_backends.py
@@ -356,19 +356,17 @@ class QwenSetupScreenTests(unittest.TestCase):
The qwen wizard asks nothing (ports live in Settings, the speaker is
chosen on Generate), so it cannot be aborted: an already-installed
- package is a no-op flash, everything else runs in the task view.
+ package is a silent no-op, everything else runs in the task view.
"""
- def test_already_installed_flashes_and_skips_the_task_view(self):
+ def test_already_installed_is_a_silent_noop(self):
from backends import qwen
settings = {"do_install": False}
with patch.object(qwen, "_wizard", return_value=settings) as mk_wizard, \
- patch.object(qwen.tui, "flash") as mk_flash, \
patch.object(qwen.taskview, "run_steps") as mk_run:
rc = qwen.setup_screen(None)
self.assertEqual(rc, 0)
mk_wizard.assert_called_once()
- mk_flash.assert_called_once()
mk_run.assert_not_called()
def test_missing_package_runs_the_tail_in_the_task_view(self):
diff --git a/app/tests/test_backends_audiocpp.py b/app/tests/test_backends_audiocpp.py
index 8cd7981..37745f3 100644
--- a/app/tests/test_backends_audiocpp.py
+++ b/app/tests/test_backends_audiocpp.py
@@ -1963,6 +1963,87 @@ class WizardNavigationTests(unittest.TestCase):
self.assertFalse(settings["download"]) # no manager script here
self.assertTrue(settings["sync_model_ids"])
+ def test_tree_screen_starts_on_confirm(self):
+ # The model-tree screen opens with focus on Confirm so Enter
+ # accepts the seeded/checked selection immediately.
+ checkout = self._checkout()
+ catalog = make_server.catalog.load_model_catalog(checkout)
+ qwen3 = next(i for i, entry in enumerate(catalog)
+ if entry["family"] == "qwen3_tts")
+ captured = {}
+
+ def fake_tree(*args, **kwargs):
+ captured.update(kwargs)
+ return [(qwen3, "Qwen3-TTS-12Hz-1.7B-Base-GGUF")]
+
+ def fake_form(stdscr, title, fields, **kwargs):
+ return {f["key"]: f["value"] for f in fields}
+
+ with patch.object(make_server.build, "find_local_checkout",
+ return_value=checkout), \
+ patch.object(tui, "checkbox_tree",
+ side_effect=fake_tree), \
+ patch.object(tui, "form", side_effect=fake_form):
+ make_server.wizard._wizard(None, self._args(),
+ make_server.wizard.build_parser())
+ self.assertTrue(captured.get("start_on_buttons"))
+
+ def test_wav_dir_seeded_from_existing_voice_dir(self):
+ # A modify run loads the Voice clone .wav directory from the
+ # server.json being configured instead of starting blank.
+ checkout = self._checkout()
+ recorded_voices = checkout.parent / "recorded-voices"
+ (checkout / "server.json").write_text(json.dumps({
+ "host": "127.0.0.1", "port": 8080, "backend": "cuda",
+ "models": [], "voice_dir": str(recorded_voices),
+ }), encoding="utf-8")
+ catalog = make_server.catalog.load_model_catalog(checkout)
+ qwen3 = next(i for i, entry in enumerate(catalog)
+ if entry["family"] == "qwen3_tts")
+
+ def fake_tree(*args, **kwargs):
+ return [(qwen3, "Qwen3-TTS-12Hz-1.7B-Base-GGUF")]
+
+ def fake_form(stdscr, title, fields, **kwargs):
+ by_key = {f["key"]: f for f in fields}
+ self.assertEqual(by_key["wav_dir"]["value"],
+ Path(recorded_voices))
+ return {f["key"]: f["value"] for f in fields}
+
+ with patch.object(make_server.build, "find_local_checkout",
+ return_value=checkout), \
+ patch.object(tui, "checkbox_tree",
+ side_effect=fake_tree), \
+ patch.object(tui, "form", side_effect=fake_form):
+ make_server.wizard._wizard(None, self._args(),
+ make_server.wizard.build_parser())
+
+ def test_wav_dir_defaults_to_project_voices_when_unconfigured(self):
+ # Without a voice_dir in server.json the field starts on the
+ # project's voices/ directory — never blank.
+ checkout = self._checkout()
+ (checkout / "server.json").write_text(
+ json.dumps({"models": []}), encoding="utf-8")
+ catalog = make_server.catalog.load_model_catalog(checkout)
+ qwen3 = next(i for i, entry in enumerate(catalog)
+ if entry["family"] == "qwen3_tts")
+
+ def fake_tree(*args, **kwargs):
+ return [(qwen3, "Qwen3-TTS-12Hz-1.7B-Base-GGUF")]
+
+ def fake_form(stdscr, title, fields, **kwargs):
+ by_key = {f["key"]: f for f in fields}
+ self.assertEqual(by_key["wav_dir"]["value"], common.VOICES_DIR)
+ return {f["key"]: f["value"] for f in fields}
+
+ with patch.object(make_server.build, "find_local_checkout",
+ return_value=checkout), \
+ patch.object(tui, "checkbox_tree",
+ side_effect=fake_tree), \
+ patch.object(tui, "form", side_effect=fake_form):
+ make_server.wizard._wizard(None, self._args(),
+ make_server.wizard.build_parser())
+
def test_build_offer_hidden_when_backend_already_built(self):
# A checkout with a built binary for the chosen backend must not
# show (or honor) a build offer.
diff --git a/app/tests/test_hub.py b/app/tests/test_hub.py
index 96e4706..6657540 100644
--- a/app/tests/test_hub.py
+++ b/app/tests/test_hub.py
@@ -369,11 +369,11 @@ class SubmenuStatusTableTests(unittest.TestCase):
return_value="/usr/bin/ffmpeg"):
result = hub._Hub(None).screen_configure()
self.assertIs(result, tui.Wizard.BACK)
- # Configure (qwen installed), Install (faster uninstalled), then
- # Uninstall (qwen installed); no audio.cpp means no model actions.
+ # Install (faster uninstalled), then Uninstall (qwen installed);
+ # no audio.cpp means no model actions. qwen has no Configure entry
+ # (its wizard asks nothing to configure).
self.assertEqual([label for label, _ in captured["options"]],
- ["Configure qwen-tts", "Install Backend",
- "Uninstall Backend"])
+ ["Install Backend", "Uninstall Backend"])
# ...the shared status table carries the states instead.
self.assertEqual(captured["table_title"], "Backend status")
self.assertEqual(
diff --git a/app/tests/test_tui.py b/app/tests/test_tui.py
index b15419b..b839a71 100644
--- a/app/tests/test_tui.py
+++ b/app/tests/test_tui.py
@@ -981,6 +981,26 @@ class CheckboxTreeTests(TuiTestCase):
checked={(0, "pkg-b"), (1, "pkg-c")})
self.assertEqual(picked, [(0, "pkg-b"), (1, "pkg-c")])
+ def test_start_on_buttons_confirms_immediately(self):
+ # start_on_buttons=True (the seeded modify flow): Enter alone
+ # accepts the pre-checked tree with no Tab first.
+ screen = FakeScreen(keys=[10])
+ picked = tui.checkbox_tree(
+ screen, "Pick models", self.FAMILIES,
+ checked={(0, "pkg-b"), (1, "pkg-c")}, start_on_buttons=True)
+ self.assertEqual(picked, [(0, "pkg-b"), (1, "pkg-c")])
+
+ def test_start_on_buttons_without_selection_flashes(self):
+ # Focus starting on Confirm changes nothing else: Enter with an
+ # empty tree flashes and stays (the flash dismiss consumes one
+ # scripted key); the user then moves back to the rows, checks
+ # one, and confirms for real.
+ keys = [10, 9, 9, 10, 9, 10]
+ screen = FakeScreen(keys=keys)
+ picked = tui.checkbox_tree(screen, "Pick models", self.FAMILIES,
+ start_on_buttons=True)
+ self.assertEqual(picked, [(0, "pkg-a")])
+
def test_prechecked_options_draw_as_checked(self):
screen = FakeScreen(keys=[9, 10])
tui.checkbox_tree(screen, "Pick models", self.FAMILIES,