User-facing docs, About page and website now point at the fork and the Void xbps repository, with one credit line to upstream Vocalinux. Channels this fork does not publish are removed from navigation.
136 lines
4.8 KiB
Python
136 lines
4.8 KiB
Python
"""Model recommendations are informational and never change the selection."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import importlib
|
|
import inspect
|
|
import sys
|
|
from collections.abc import Iterator
|
|
from typing import Any
|
|
from unittest.mock import MagicMock, Mock, patch
|
|
|
|
import pytest
|
|
|
|
import vocalinux.ui
|
|
|
|
|
|
@pytest.fixture(scope="module")
|
|
def settings_dialog() -> Iterator[Any]:
|
|
"""Import settings_dialog with concrete GTK base classes."""
|
|
repository = sys.modules["gi.repository"]
|
|
bases = {name: type(name, (), {}) for name in ("Box", "ListBoxRow", "Dialog")}
|
|
saved_module = sys.modules.pop("vocalinux.ui.settings_dialog", None)
|
|
saved_attribute = getattr(vocalinux.ui, "settings_dialog", None)
|
|
try:
|
|
with patch.object(repository, "Gtk", MagicMock(**bases)):
|
|
module = importlib.import_module("vocalinux.ui.settings_dialog")
|
|
yield module
|
|
finally:
|
|
sys.modules.pop("vocalinux.ui.settings_dialog", None)
|
|
if saved_module is not None:
|
|
sys.modules["vocalinux.ui.settings_dialog"] = saved_module
|
|
if saved_attribute is not None:
|
|
vocalinux.ui.settings_dialog = saved_attribute
|
|
elif hasattr(vocalinux.ui, "settings_dialog"):
|
|
del vocalinux.ui.settings_dialog
|
|
|
|
|
|
@pytest.fixture
|
|
def dialog_class(settings_dialog: Any) -> Any:
|
|
return settings_dialog.SettingsDialog
|
|
|
|
|
|
def _dialog_stub() -> Mock:
|
|
dialog = Mock()
|
|
dialog.engine_combo.get_active_text.return_value = "whisper.cpp"
|
|
dialog.model_variant_combo.get_active_id.return_value = "small.en"
|
|
dialog.model_combo.get_active_id.return_value = "small"
|
|
dialog.language_combo.get_active_id.return_value = "en-us"
|
|
dialog._get_selected_whispercpp_model.return_value = "small.en"
|
|
dialog._get_recommended_whispercpp_model_for_language.return_value = (
|
|
"small",
|
|
"8GB RAM - good balance",
|
|
)
|
|
dialog._refresh_simple_readout = Mock()
|
|
return dialog
|
|
|
|
|
|
def test_recommendation_has_no_action_button(settings_dialog: Any, dialog_class: Any) -> None:
|
|
source = inspect.getsource(dialog_class.__init__)
|
|
|
|
assert "Use it" not in source
|
|
assert "model_recommendation_button" not in source
|
|
|
|
|
|
def test_same_size_whispercpp_variant_is_not_shown(settings_dialog: Any, dialog_class: Any) -> None:
|
|
dialog = _dialog_stub()
|
|
|
|
with patch.object(settings_dialog, "is_whispercpp_model_downloaded", return_value=True):
|
|
dialog_class._update_model_info(dialog)
|
|
|
|
dialog.model_recommendation_box.hide.assert_called_once_with()
|
|
dialog.model_recommendation.set_text.assert_not_called()
|
|
|
|
|
|
def test_different_size_recommendation_shows_size_and_reason(
|
|
settings_dialog: Any, dialog_class: Any
|
|
) -> None:
|
|
dialog = _dialog_stub()
|
|
dialog._get_selected_whispercpp_model.return_value = "tiny"
|
|
|
|
with patch.object(settings_dialog, "is_whispercpp_model_downloaded", return_value=True):
|
|
dialog_class._update_model_info(dialog)
|
|
|
|
message = dialog.model_recommendation.set_text.call_args.args[0]
|
|
assert message.startswith("Suggested for this computer: Small")
|
|
assert "MB" in message
|
|
assert "8GB RAM - good balance" in message
|
|
dialog.model_recommendation_box.show.assert_called_once_with()
|
|
|
|
|
|
def test_other_engine_recommendation_uses_recommended_model_size(
|
|
settings_dialog: Any, dialog_class: Any
|
|
) -> None:
|
|
dialog = _dialog_stub()
|
|
dialog.engine_combo.get_active_text.return_value = "Vosk"
|
|
dialog.model_combo.get_active_id.return_value = "small"
|
|
dialog.language = "en-us"
|
|
|
|
with (
|
|
patch.object(
|
|
settings_dialog,
|
|
"VOSK_MODEL_INFO",
|
|
{
|
|
"small": {"size_mb": 50, "desc": "Selected model"},
|
|
"large": {"size_mb": 250, "desc": "Recommended model"},
|
|
},
|
|
),
|
|
patch.object(settings_dialog, "_is_vosk_model_downloaded", return_value=True),
|
|
patch.object(settings_dialog, "_get_recommended_vosk_model", return_value=("large", "RAM")),
|
|
):
|
|
dialog_class._update_model_info(dialog)
|
|
|
|
assert "(250 MB, RAM)" in dialog.model_recommendation.set_text.call_args.args[0]
|
|
|
|
|
|
def test_recommendation_does_not_change_picker_or_config_state(
|
|
settings_dialog: Any, dialog_class: Any
|
|
) -> None:
|
|
dialog = _dialog_stub()
|
|
dialog.config_manager = Mock()
|
|
|
|
with patch.object(settings_dialog, "is_whispercpp_model_downloaded", return_value=True):
|
|
dialog_class._update_model_info(dialog)
|
|
|
|
dialog.model_combo.set_active_id.assert_not_called()
|
|
dialog.model_variant_combo.set_active_id.assert_not_called()
|
|
dialog.config_manager.set.assert_not_called()
|
|
dialog.config_manager.save_settings.assert_not_called()
|
|
|
|
|
|
def test_model_selection_docs_url_is_stable(settings_dialog: Any) -> None:
|
|
assert (
|
|
settings_dialog.MODEL_SELECTION_DOC_URL
|
|
== "https://git.bongbetic.com/xavierk/voculinux/src/branch/main/docs/MODEL_SELECTION.md"
|
|
)
|