Fix stuff, apply ruff rules.
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
"""Regression tests for BrlAPI command exports."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from cthulhu import braille
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_braille_exports_brlapi_command_aliases():
|
||||
expected_names = [
|
||||
"BRLAPI_KEY_CMD_HWINLT",
|
||||
"BRLAPI_KEY_CMD_FWINLT",
|
||||
"BRLAPI_KEY_CMD_FWINLTSKIP",
|
||||
"BRLAPI_KEY_CMD_HWINRT",
|
||||
"BRLAPI_KEY_CMD_FWINRT",
|
||||
"BRLAPI_KEY_CMD_FWINRTSKIP",
|
||||
"BRLAPI_KEY_CMD_LNUP",
|
||||
"BRLAPI_KEY_CMD_LNDN",
|
||||
"BRLAPI_KEY_CMD_FREEZE",
|
||||
"BRLAPI_KEY_CMD_TOP_LEFT",
|
||||
"BRLAPI_KEY_CMD_BOT_LEFT",
|
||||
"BRLAPI_KEY_CMD_HOME",
|
||||
"BRLAPI_KEY_CMD_SIXDOTS",
|
||||
"BRLAPI_KEY_CMD_ROUTE",
|
||||
"BRLAPI_KEY_CMD_CUTBEGIN",
|
||||
"BRLAPI_KEY_CMD_CUTLINE",
|
||||
]
|
||||
|
||||
for name in expected_names:
|
||||
assert hasattr(braille, name), name
|
||||
|
||||
if braille._brlAPIAvailable:
|
||||
assert braille.BRLAPI_KEY_CMD_HWINLT == braille.brlapi.KEY_CMD_HWINLT
|
||||
assert braille.BRLAPI_KEY_CMD_ROUTE == braille.brlapi.KEY_CMD_ROUTE
|
||||
@@ -0,0 +1,128 @@
|
||||
"""Regression tests for braille API compatibility."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from cthulhu import braille
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_braille_exports_snake_case_compatibility_apis():
|
||||
expected_names = [
|
||||
"check_braille_setting",
|
||||
"disable_braille",
|
||||
"display_line",
|
||||
"display_message",
|
||||
"get_caret_context",
|
||||
"get_default_contraction_table",
|
||||
"get_region_at_cell",
|
||||
"is_flash_active",
|
||||
"kill_flash",
|
||||
"pan_left",
|
||||
"pan_right",
|
||||
"process_routing_key",
|
||||
"return_to_region_with_focus",
|
||||
"set_brlapi_priority",
|
||||
"set_contraction_table",
|
||||
"set_enable_braille",
|
||||
"set_enable_computer_braille_at_cursor",
|
||||
"set_enable_contracted_braille",
|
||||
"set_enable_eol",
|
||||
"set_enable_word_wrap",
|
||||
"set_link_indicator",
|
||||
"set_monitor_callback",
|
||||
"set_selector_indicator",
|
||||
"set_text_attributes_indicator",
|
||||
"setup_key_ranges",
|
||||
"toggle_contracted_braille",
|
||||
"try_reposition_cursor",
|
||||
]
|
||||
|
||||
for name in expected_names:
|
||||
assert hasattr(braille, name), name
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_line_exports_snake_case_helpers():
|
||||
line = braille.Line()
|
||||
first = braille.Region("first")
|
||||
second = braille.Region("second")
|
||||
|
||||
line.add_region(first)
|
||||
line.add_regions([second])
|
||||
|
||||
assert line.regions == [first, second]
|
||||
assert line.get_line_info() == line.getLineInfo()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_setup_key_ranges_delegates_to_legacy_api(monkeypatch):
|
||||
calls = []
|
||||
|
||||
def setup_key_ranges(keys):
|
||||
calls.append(keys)
|
||||
|
||||
monkeypatch.setattr(braille, "setupKeyRanges", setup_key_ranges)
|
||||
|
||||
braille.setup_key_ranges({1, 2})
|
||||
|
||||
assert calls == [{1, 2}]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_snake_case_runtime_setters_update_legacy_settings(monkeypatch):
|
||||
monkeypatch.setattr(braille.settings, "enableBraille", True)
|
||||
monkeypatch.setattr(braille.settings, "enableContractedBraille", False)
|
||||
monkeypatch.setattr(braille.settings, "brailleContractionTable", "")
|
||||
monkeypatch.setattr(braille.settings, "disableBrailleEOL", False)
|
||||
monkeypatch.setattr(braille.settings, "enableBrailleWordWrap", False)
|
||||
monkeypatch.setattr(braille.settings, "brailleSelectorIndicator", 0)
|
||||
monkeypatch.setattr(braille.settings, "brailleLinkIndicator", 0)
|
||||
monkeypatch.setattr(braille.settings, "textAttributesBrailleIndicator", 0)
|
||||
|
||||
braille.set_enable_braille(False)
|
||||
braille.set_enable_contracted_braille(True)
|
||||
braille.set_contraction_table("/tmp/table.ctb")
|
||||
braille.set_enable_eol(False)
|
||||
braille.set_enable_word_wrap(True)
|
||||
braille.set_selector_indicator(64)
|
||||
braille.set_link_indicator(128)
|
||||
braille.set_text_attributes_indicator(192)
|
||||
|
||||
assert braille.settings.enableBraille is False
|
||||
assert braille.settings.enableContractedBraille is True
|
||||
assert braille.settings.brailleContractionTable == "/tmp/table.ctb"
|
||||
assert braille.settings.disableBrailleEOL is True
|
||||
assert braille.settings.enableBrailleWordWrap is True
|
||||
assert braille.settings.brailleSelectorIndicator == 64
|
||||
assert braille.settings.brailleLinkIndicator == 128
|
||||
assert braille.settings.textAttributesBrailleIndicator == 192
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_display_message_accepts_snake_case_keyword(monkeypatch):
|
||||
calls = []
|
||||
|
||||
def display_message(message, cursor=-1, flashTime=0):
|
||||
calls.append((message, cursor, flashTime))
|
||||
|
||||
monkeypatch.setattr(braille, "displayMessage", display_message)
|
||||
|
||||
braille.display_message("hello", flash_time=250)
|
||||
|
||||
assert calls == [("hello", -1, 250)]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_kill_flash_accepts_snake_case_keyword(monkeypatch):
|
||||
calls = []
|
||||
|
||||
def kill_flash(restoreSaved=True):
|
||||
calls.append(restoreSaved)
|
||||
|
||||
monkeypatch.setattr(braille, "killFlash", kill_flash)
|
||||
|
||||
braille.kill_flash(restore_saved=False)
|
||||
|
||||
assert calls == [False]
|
||||
@@ -0,0 +1,38 @@
|
||||
"""Regression tests for command-name exports."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from cthulhu import cmdnames
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.parametrize(
|
||||
"name",
|
||||
[
|
||||
"BYPASS_MODE_TOGGLE",
|
||||
"CHAT_NEXT_MESSAGE",
|
||||
"CLIPBOARD_PRESENT_CONTENTS",
|
||||
"DEBUG_CLEAR_ATSPI_CACHE_FOR_APPLICATION",
|
||||
"DEBUG_CYCLE_LEVEL",
|
||||
"LIVE_REGIONS_ARE_ANNOUNCED",
|
||||
"LIVE_REGIONS_NEXT",
|
||||
"LIVE_REGIONS_PREVIOUS",
|
||||
"PRESENT_BATTERY_STATUS",
|
||||
"PRESENT_CELL_FORMULA",
|
||||
"PRESENT_CPU_AND_MEMORY_USAGE",
|
||||
"PRESENT_CURRENT_PROFILE",
|
||||
"STRUCTURAL_NAVIGATION_MODE_CYCLE",
|
||||
"TABLE_CELL_BEGINNING_OF_ROW",
|
||||
"TABLE_CELL_BOTTOM_OF_COLUMN",
|
||||
"TABLE_CELL_END_OF_ROW",
|
||||
"TABLE_CELL_TOP_OF_COLUMN",
|
||||
"TABLE_NAVIGATION_TOGGLE",
|
||||
"TOGGLE_BRAILLE_MONITOR",
|
||||
"TOGGLE_KEYBOARD_LAYOUT",
|
||||
"TOGGLE_SPEECH_MONITOR",
|
||||
],
|
||||
)
|
||||
def test_referenced_command_name_is_exported(name: str) -> None:
|
||||
assert getattr(cmdnames, name)
|
||||
@@ -0,0 +1,33 @@
|
||||
"""Regression tests for focus manager API compatibility."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from cthulhu import focus_manager
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_is_in_preferences_window_tracks_cthulhu_active_window(monkeypatch):
|
||||
manager = focus_manager.FocusManager.__new__(focus_manager.FocusManager)
|
||||
window = object()
|
||||
app = object()
|
||||
manager._window = window
|
||||
|
||||
monkeypatch.setattr(focus_manager.AXObject, "get_application", lambda obj: app)
|
||||
monkeypatch.setattr(focus_manager.AXObject, "get_name", lambda obj: "Cthulhu")
|
||||
|
||||
assert manager.is_in_preferences_window() is True
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_is_in_preferences_window_is_false_for_non_cthulhu_window(monkeypatch):
|
||||
manager = focus_manager.FocusManager.__new__(focus_manager.FocusManager)
|
||||
window = object()
|
||||
app = object()
|
||||
manager._window = window
|
||||
|
||||
monkeypatch.setattr(focus_manager.AXObject, "get_application", lambda obj: app)
|
||||
monkeypatch.setattr(focus_manager.AXObject, "get_name", lambda obj: "Terminal")
|
||||
|
||||
assert manager.is_in_preferences_window() is False
|
||||
@@ -348,6 +348,29 @@ class TestInputEventManager:
|
||||
if case["expects_debug_call"]:
|
||||
essential_modules["cthulhu.debug"].print_tokens.assert_called()
|
||||
|
||||
def test_add_grabs_for_keybinding_allows_default_cthulhu_modifiers(
|
||||
self,
|
||||
test_context: CthulhuTestContext,
|
||||
) -> None:
|
||||
"""Plugin bindings can be grabbed before a script supplies modifier keys."""
|
||||
|
||||
input_event_manager, _essential_modules = self._setup_input_event_manager(test_context)
|
||||
|
||||
mock_device = test_context.Mock()
|
||||
mock_device.add_key_grab.return_value = 123
|
||||
input_event_manager._device = mock_device
|
||||
|
||||
mock_kd = test_context.Mock()
|
||||
mock_binding = test_context.Mock()
|
||||
mock_binding.has_grabs.return_value = False
|
||||
mock_binding.key_definitions.return_value = [mock_kd]
|
||||
|
||||
result = input_event_manager.add_grabs_for_keybinding(mock_binding)
|
||||
|
||||
assert result == [123]
|
||||
mock_binding.key_definitions.assert_called_once_with(None)
|
||||
mock_device.add_key_grab.assert_called_once_with(mock_kd, None)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"case",
|
||||
[
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
"""Regression tests for keybinding API compatibility."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from cthulhu import keybindings
|
||||
|
||||
|
||||
class DummyHandler:
|
||||
description = "dummy handler"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_keybinding_accepts_lightweight_command_manager_form():
|
||||
binding = keybindings.KeyBinding("KP_Divide", keybindings.CTHULHU_MODIFIER_MASK)
|
||||
|
||||
assert binding.keysymstring == "KP_Divide"
|
||||
assert binding.modifier_mask == keybindings.defaultModifierMask
|
||||
assert binding.modifiers == keybindings.CTHULHU_MODIFIER_MASK
|
||||
assert binding.handler is None
|
||||
assert binding.click_count == 1
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_keybinding_accepts_lightweight_positional_click_count():
|
||||
binding = keybindings.KeyBinding("a", keybindings.CTHULHU_MODIFIER_MASK, 2)
|
||||
|
||||
assert binding.modifier_mask == keybindings.defaultModifierMask
|
||||
assert binding.modifiers == keybindings.CTHULHU_MODIFIER_MASK
|
||||
assert binding.click_count == 2
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_keybinding_preserves_legacy_handler_form():
|
||||
handler = DummyHandler()
|
||||
|
||||
binding = keybindings.KeyBinding(
|
||||
"b",
|
||||
keybindings.defaultModifierMask,
|
||||
keybindings.CTHULHU_SHIFT_MODIFIER_MASK,
|
||||
handler,
|
||||
3,
|
||||
)
|
||||
|
||||
assert binding.modifier_mask == keybindings.defaultModifierMask
|
||||
assert binding.modifiers == keybindings.CTHULHU_SHIFT_MODIFIER_MASK
|
||||
assert binding.handler is handler
|
||||
assert binding.click_count == 3
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_keybinding_exposes_command_manager_helpers():
|
||||
binding = keybindings.KeyBinding("c", keybindings.CTHULHU_MODIFIER_MASK)
|
||||
|
||||
assert keybindings.get_modifier_names is keybindings.getModifierNames
|
||||
assert keybindings.CTHULHU_ALT_SHIFT_MODIFIER_MASK == (
|
||||
keybindings.CTHULHU_MODIFIER_MASK
|
||||
| keybindings.ALT_MODIFIER_MASK
|
||||
| keybindings.SHIFT_MODIFIER_MASK
|
||||
)
|
||||
binding.set_grab_ids([42])
|
||||
assert binding.get_grab_ids() == [42]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_keybinding_add_grabs_accepts_explicit_cthulhu_modifiers(monkeypatch):
|
||||
binding = keybindings.KeyBinding("d", keybindings.CTHULHU_MODIFIER_MASK)
|
||||
captured = {}
|
||||
|
||||
class FakeInputEventManager:
|
||||
def add_grabs_for_keybinding(self, grab_binding, cthulhu_modifiers):
|
||||
captured["binding"] = grab_binding
|
||||
captured["cthulhu_modifiers"] = cthulhu_modifiers
|
||||
return [7]
|
||||
|
||||
from cthulhu import input_event_manager
|
||||
|
||||
monkeypatch.setattr(
|
||||
input_event_manager,
|
||||
"get_manager",
|
||||
lambda: FakeInputEventManager(),
|
||||
)
|
||||
|
||||
binding.add_grabs(["Insert"])
|
||||
|
||||
assert captured == {"binding": binding, "cthulhu_modifiers": ["Insert"]}
|
||||
assert binding.get_grab_ids() == [7]
|
||||
@@ -17,6 +17,12 @@ from cthulhu import learn_mode_presenter
|
||||
|
||||
|
||||
class LearnModePresenterRegressionTests(unittest.TestCase):
|
||||
def test_get_presenter_alias_matches_legacy_get_presenter(self):
|
||||
self.assertIs(learn_mode_presenter.get_presenter, learn_mode_presenter.getPresenter)
|
||||
|
||||
def test_exposes_default_extension_setup_hook(self):
|
||||
self.assertTrue(hasattr(learn_mode_presenter.LearnModePresenter, "set_up_commands"))
|
||||
|
||||
def test_escape_keyval_exits_learn_mode_when_event_string_is_control_character(self):
|
||||
presenter = learn_mode_presenter.LearnModePresenter(mock.Mock())
|
||||
presenter._is_active = True
|
||||
|
||||
@@ -59,6 +59,12 @@ class InputEventManagerPointerMonitorTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.manager = input_event_manager.InputEventManager()
|
||||
|
||||
def test_get_reviewer_alias_matches_legacy_get_reviewer(self):
|
||||
self.assertIs(mouse_review.get_reviewer, mouse_review.getReviewer)
|
||||
|
||||
def test_exposes_default_extension_setup_hook(self):
|
||||
self.assertTrue(hasattr(mouse_review.MouseReviewer, "set_up_commands"))
|
||||
|
||||
def test_activate_device_creates_the_device_only_once(self):
|
||||
device = FakeDevice()
|
||||
deviceFactory = FakeDeviceFactory(device)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
"""Compatibility tests for the notification presenter."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from cthulhu import notification_presenter
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_get_presenter_alias_matches_legacy_get_presenter() -> None:
|
||||
"""The Mako monitor still uses the legacy camelCase singleton accessor."""
|
||||
|
||||
assert notification_presenter.getPresenter is notification_presenter.get_presenter
|
||||
assert notification_presenter.getPresenter() is notification_presenter.get_presenter()
|
||||
@@ -0,0 +1,61 @@
|
||||
"""Regression tests for script startup ordering."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from cthulhu.scripts import default
|
||||
|
||||
script_module = default.script
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_script_initializes_formatting_before_generators(monkeypatch):
|
||||
"""Generator construction needs script.formatting during startup."""
|
||||
|
||||
monkeypatch.setattr(script_module.AXObject, "get_name", staticmethod(lambda _app: "test-app"))
|
||||
init_order = []
|
||||
formatting = {"sentinel": True}
|
||||
|
||||
class FormattingAwareScript(script_module.Script):
|
||||
def get_formatting(self):
|
||||
init_order.append("formatting")
|
||||
return formatting
|
||||
|
||||
def get_listeners(self):
|
||||
return {}
|
||||
|
||||
def get_utilities(self):
|
||||
return object()
|
||||
|
||||
def _create_braille_generator(self):
|
||||
init_order.append("braille")
|
||||
assert self.formatting is formatting
|
||||
return "braille"
|
||||
|
||||
def _create_sound_generator(self):
|
||||
init_order.append("sound")
|
||||
assert self.formatting is formatting
|
||||
return "sound"
|
||||
|
||||
def _create_speech_generator(self):
|
||||
init_order.append("speech")
|
||||
assert self.formatting is formatting
|
||||
return "speech"
|
||||
|
||||
def get_label_inference(self):
|
||||
return None
|
||||
|
||||
def get_chat(self):
|
||||
return None
|
||||
|
||||
def set_up_commands(self):
|
||||
pass
|
||||
|
||||
test_script = FormattingAwareScript(object())
|
||||
|
||||
assert init_order == ["formatting", "braille", "sound", "speech"]
|
||||
assert test_script.formatting is formatting
|
||||
assert test_script.get_braille_generator() == "braille"
|
||||
assert test_script.get_sound_generator() == "sound"
|
||||
assert test_script.get_speech_generator() == "speech"
|
||||
@@ -0,0 +1,55 @@
|
||||
"""Compatibility tests for the sleep mode manager."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import sys
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .cthulhu_test_context import CthulhuTestContext
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_get_manager_alias_matches_legacy_get_manager(
|
||||
test_context: CthulhuTestContext,
|
||||
) -> None:
|
||||
"""The default script expects the snake_case singleton accessor."""
|
||||
|
||||
test_context.setup_shared_dependencies()
|
||||
sys.modules.pop("cthulhu.sleep_mode_manager", None)
|
||||
sleep_mode_manager = importlib.import_module("cthulhu.sleep_mode_manager")
|
||||
|
||||
assert sleep_mode_manager.get_manager is sleep_mode_manager.getManager
|
||||
assert sleep_mode_manager.get_manager() is sleep_mode_manager.getManager()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_sleep_mode_manager_exposes_default_extension_setup_hook(
|
||||
test_context: CthulhuTestContext,
|
||||
) -> None:
|
||||
"""The default script calls set_up_commands() on all extensions."""
|
||||
|
||||
test_context.setup_shared_dependencies()
|
||||
sys.modules.pop("cthulhu.sleep_mode_manager", None)
|
||||
sleep_mode_manager = importlib.import_module("cthulhu.sleep_mode_manager")
|
||||
|
||||
assert hasattr(sleep_mode_manager.get_manager(), "set_up_commands")
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_sleep_mode_manager_exposes_snake_case_app_state_accessor(
|
||||
test_context: CthulhuTestContext,
|
||||
) -> None:
|
||||
"""The script manager checks sleep mode using the snake_case method name."""
|
||||
|
||||
test_context.setup_shared_dependencies()
|
||||
sys.modules.pop("cthulhu.sleep_mode_manager", None)
|
||||
sleep_mode_manager = importlib.import_module("cthulhu.sleep_mode_manager")
|
||||
manager = sleep_mode_manager.get_manager()
|
||||
|
||||
app = object()
|
||||
|
||||
assert manager.is_active_for_app(app) == manager.isActiveForApp(app)
|
||||
@@ -0,0 +1,53 @@
|
||||
"""Regression tests for speech monitor callback registration."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from cthulhu import speech
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_set_monitor_callbacks_accepts_snake_case_keywords() -> None:
|
||||
captured: list[str] = []
|
||||
|
||||
speech.set_monitor_callbacks(
|
||||
write_text=captured.append,
|
||||
write_key=lambda _key: None,
|
||||
begin_group=lambda: None,
|
||||
end_group=lambda: None,
|
||||
)
|
||||
try:
|
||||
speech._write_to_monitor("hello")
|
||||
finally:
|
||||
speech.set_monitor_callbacks()
|
||||
|
||||
assert captured == ["hello"]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_set_monitor_callbacks_preserves_legacy_write_text_argument() -> None:
|
||||
captured: list[str] = []
|
||||
|
||||
speech.set_monitor_callbacks(writeText=captured.append)
|
||||
try:
|
||||
speech._write_to_monitor("legacy")
|
||||
finally:
|
||||
speech.set_monitor_callbacks()
|
||||
|
||||
assert captured == ["legacy"]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_speech_server_snake_case_accessors_delegate_to_legacy_api(monkeypatch) -> None:
|
||||
monkeypatch.setattr(speech, "_refreshEchoSpeechServer", lambda: None)
|
||||
original_server = speech.getSpeechServer()
|
||||
server = object()
|
||||
|
||||
try:
|
||||
speech.set_server(server)
|
||||
|
||||
assert speech.get_speech_server() is server
|
||||
assert speech.getSpeechServer() is server
|
||||
finally:
|
||||
speech.setSpeechServer(original_server)
|
||||
@@ -0,0 +1,121 @@
|
||||
"""Regression tests for speech server API compatibility."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from cthulhu import speechserver
|
||||
from cthulhu.acss import ACSS
|
||||
|
||||
|
||||
class DummySpeechServer(speechserver.SpeechServer):
|
||||
factory_calls = []
|
||||
active_servers_shutdown = False
|
||||
|
||||
@staticmethod
|
||||
def getFactoryName():
|
||||
return "Dummy"
|
||||
|
||||
@staticmethod
|
||||
def getSpeechServers():
|
||||
return ["server-a"]
|
||||
|
||||
@staticmethod
|
||||
def getSpeechServer(info=None):
|
||||
DummySpeechServer.factory_calls.append(info)
|
||||
return DummySpeechServer()
|
||||
|
||||
@staticmethod
|
||||
def shutdownActiveServers():
|
||||
DummySpeechServer.active_servers_shutdown = True
|
||||
|
||||
def __init__(self):
|
||||
self.calls = []
|
||||
self._current_voice_properties = {}
|
||||
|
||||
def getInfo(self):
|
||||
return ["Dummy", "dummy"]
|
||||
|
||||
def getVoiceFamilies(self):
|
||||
return ["voice-a"]
|
||||
|
||||
def getVoiceFamiliesForLanguage(self, language, dialect="", maximum=None):
|
||||
return [(language, dialect, maximum)]
|
||||
|
||||
def getOutputModule(self):
|
||||
return "module-a"
|
||||
|
||||
def setOutputModule(self, module):
|
||||
self.calls.append(("setOutputModule", module))
|
||||
|
||||
def updateCapitalizationStyle(self):
|
||||
self.calls.append(("updateCapitalizationStyle",))
|
||||
|
||||
def updatePunctuationLevel(self):
|
||||
self.calls.append(("updatePunctuationLevel",))
|
||||
|
||||
def increaseSpeechRate(self, step=5):
|
||||
self.calls.append(("increaseSpeechRate", step))
|
||||
|
||||
def decreaseSpeechVolume(self, step=0.5):
|
||||
self.calls.append(("decreaseSpeechVolume", step))
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_snake_case_factory_methods_delegate_to_legacy_methods():
|
||||
DummySpeechServer.factory_calls.clear()
|
||||
DummySpeechServer.active_servers_shutdown = False
|
||||
|
||||
server = DummySpeechServer.get_speech_server(("Dummy", "dummy"))
|
||||
|
||||
assert isinstance(server, DummySpeechServer)
|
||||
assert DummySpeechServer.factory_calls == [("Dummy", "dummy")]
|
||||
assert DummySpeechServer.get_speech_servers() == ["server-a"]
|
||||
assert DummySpeechServer.get_factory_name() == "Dummy"
|
||||
|
||||
DummySpeechServer.shutdown_active_servers()
|
||||
|
||||
assert DummySpeechServer.active_servers_shutdown is True
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_snake_case_instance_methods_delegate_to_legacy_methods():
|
||||
server = DummySpeechServer()
|
||||
|
||||
assert server.get_info() == ["Dummy", "dummy"]
|
||||
assert server.get_voice_families() == ["voice-a"]
|
||||
assert server.get_voice_families_for_language("en", variant="us") == [("en", "us", None)]
|
||||
assert server.get_output_module() == "module-a"
|
||||
|
||||
server.set_output_module("module-b")
|
||||
server.update_capitalization_style("none")
|
||||
server.update_punctuation_level(speechserver.PunctuationStyle.SOME)
|
||||
server.increase_speech_rate(9)
|
||||
server.decrease_speech_volume(1.5)
|
||||
|
||||
assert server.calls == [
|
||||
("setOutputModule", "module-b"),
|
||||
("updateCapitalizationStyle",),
|
||||
("updatePunctuationLevel",),
|
||||
("increaseSpeechRate", 9),
|
||||
("decreaseSpeechVolume", 1.5),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_voice_property_helpers_store_and_clear_default_voice():
|
||||
server = DummySpeechServer()
|
||||
default_voice = {ACSS.FAMILY: {speechserver.VoiceFamily.NAME: "Voice A"}}
|
||||
next_family = {speechserver.VoiceFamily.NAME: "Voice B"}
|
||||
|
||||
server.set_default_voice(default_voice)
|
||||
|
||||
assert server.get_voice_family() == default_voice[ACSS.FAMILY]
|
||||
|
||||
server.set_voice_family(next_family)
|
||||
|
||||
assert server.get_voice_family() == next_family
|
||||
|
||||
server.clear_cached_voice_properties()
|
||||
|
||||
assert server.get_voice_family() is None
|
||||
Reference in New Issue
Block a user