Files
voculinux/tests/test_misc_edge_cases.py
T
xavierk 80a3792576
CI / security (pull_request) Failing after 1m25s
CI / lint (pull_request) Failing after 34s
CI / ai-review (pull_request) Successful in 25s
chore: import vocalinux project
Import the vocalinux source tree (tray app, Next.js site in web/,
packaging, installers, docs and tests) on top of the Gitea template
commit. The project README replaces the template README, and the
template CI files (.gitea/workflows/ci.yml, .jscpd.json, CI.md) are kept.
2026-11-06 11:51:44 +05:30

164 lines
5.5 KiB
Python

"""Final coverage tests targeting the last few uncovered lines."""
import sys
import unittest
from unittest.mock import MagicMock, patch
import pytest
@pytest.fixture(autouse=True)
def _restore_sys_modules():
saved = dict(sys.modules)
yield
added = set(sys.modules.keys()) - set(saved.keys())
for k in added:
del sys.modules[k]
for k, v in saved.items():
if k not in sys.modules or sys.modules[k] is not v:
sys.modules[k] = v
class TestCommandProcessorEdgeCases(unittest.TestCase):
"""Cover edge case lines in command_processor.py."""
def test_capitalize_command(self):
from vocalinux.speech_recognition.command_processor import CommandProcessor
cp = CommandProcessor()
result = cp.process_text("capitalize")
self.assertIsInstance(result, tuple)
def test_format_with_no_target(self):
from vocalinux.speech_recognition.command_processor import CommandProcessor
cp = CommandProcessor()
result = cp.process_text("format with no target word")
self.assertIsInstance(result, tuple)
def test_multiple_format_modifiers(self):
from vocalinux.speech_recognition.command_processor import CommandProcessor
cp = CommandProcessor()
result = cp.process_text("multiple format modifiers")
self.assertIsInstance(result, tuple)
class TestResourceManagerFallback(unittest.TestCase):
"""Cover resource_manager.py fallback lines."""
def test_resources_dir_fallback(self):
from vocalinux.utils.resource_manager import ResourceManager
rm = ResourceManager()
# Just access the property - it should return a valid path
path = rm.resources_dir
self.assertIsInstance(path, str)
class TestKeyboardBackendImportFallbacks(unittest.TestCase):
"""Cover import fallback lines in keyboard_backends/__init__.py."""
def test_evdev_import_failure(self):
"""Test that EVDEV_AVAILABLE is False when evdev isn't installed."""
import importlib
saved = dict(sys.modules)
# Remove evdev modules to force ImportError
for key in list(sys.modules.keys()):
if "evdev" in key:
del sys.modules[key]
# Create a module that will raise ImportError on evdev import
mock_evdev = MagicMock()
mock_evdev.side_effect = ImportError("No evdev")
import vocalinux.ui.keyboard_backends as kb_mod
# The module already imported - we can check the constants
# EVDEV_AVAILABLE and PYNPUT_AVAILABLE should be booleans
self.assertIsInstance(kb_mod.EVDEV_AVAILABLE, bool)
self.assertIsInstance(kb_mod.PYNPUT_AVAILABLE, bool)
# Restore
for key, val in saved.items():
sys.modules[key] = val
def test_desktop_environment_detect_unknown(self):
"""Test DesktopEnvironment detection with unknown session."""
from vocalinux.ui.keyboard_backends import DesktopEnvironment
with patch.dict(os.environ, {"XDG_SESSION_TYPE": "mir"}, clear=False):
de = DesktopEnvironment.detect()
self.assertIsNotNone(de)
def test_desktop_environment_detect_wayland(self):
from vocalinux.ui.keyboard_backends import DesktopEnvironment
with patch.dict(os.environ, {"XDG_SESSION_TYPE": "wayland"}, clear=False):
de = DesktopEnvironment.detect()
self.assertEqual(de, "wayland")
def test_desktop_environment_detect_x11(self):
from vocalinux.ui.keyboard_backends import DesktopEnvironment
with patch.dict(os.environ, {"XDG_SESSION_TYPE": "x11"}, clear=False):
de = DesktopEnvironment.detect()
self.assertEqual(de, "x11")
class TestKeyboardBaseAbstractMethods(unittest.TestCase):
"""Cover abstract method stubs in keyboard_backends/base.py."""
def test_abstract_start(self):
from vocalinux.ui.keyboard_backends.base import KeyboardBackend
class TestBackend(KeyboardBackend):
def start(self):
return super().start()
def stop(self):
return super().stop()
def is_available(self):
return super().is_available()
def get_permission_hint(self):
return super().get_permission_hint()
b = TestBackend.__new__(TestBackend)
# Call the abstract methods through super() - they just return pass/None
b.start()
b.stop()
b.is_available()
b.get_permission_hint()
class TestWhispercppModelInfoExtra(unittest.TestCase):
"""Cover a few more lines in whispercpp_model_info.py."""
def test_detect_compute_backend_returns_tuple(self):
from vocalinux.utils.whispercpp_model_info import detect_compute_backend
backend, name = detect_compute_backend()
self.assertIsInstance(backend, str)
self.assertIsInstance(name, str)
self.assertIn(backend, ["cuda", "rocm", "vulkan", "metal", "cpu"])
def test_detect_compute_backend_cpu_fallback(self):
from vocalinux.utils.whispercpp_model_info import detect_compute_backend
# When all GPU checks fail, should fall back to cpu
with patch("subprocess.run", side_effect=FileNotFoundError("not found")):
with patch("platform.system", return_value="Linux"):
with patch("shutil.which", return_value=None):
backend, name = detect_compute_backend()
self.assertIsInstance(backend, str)
import os # noqa: E402 - needed for os.environ patches
if __name__ == "__main__":
unittest.main()