Merge branch 'testing' into wine-access

This commit is contained in:
Storm Dragon
2026-07-19 15:23:05 -04:00
5 changed files with 92 additions and 41 deletions
@@ -7,13 +7,33 @@ from unittest import mock
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
import cthulhu as cthulhu_package
from cthulhu import cthulhu_state from cthulhu import cthulhu_state
from cthulhu import cthulhu
from cthulhu import compositor_state_adapter from cthulhu import compositor_state_adapter
from cthulhu import compositor_state_types from cthulhu import compositor_state_types
from cthulhu import compositor_state_wayland from cthulhu import compositor_state_wayland
stubCthulhu = types.ModuleType("cthulhu.cthulhu")
stubCthulhu.cthulhuApp = mock.Mock()
previousCthulhuModule = sys.modules.get("cthulhu.cthulhu")
sys.modules.setdefault("cthulhu.cthulhu", stubCthulhu)
from cthulhu import event_manager
from cthulhu.wayland_protocols import ext_workspace_v1 from cthulhu.wayland_protocols import ext_workspace_v1
if previousCthulhuModule is None:
sys.modules.pop("cthulhu.cthulhu", None)
if getattr(cthulhu_package, "cthulhu", None) is stubCthulhu:
delattr(cthulhu_package, "cthulhu")
from cthulhu import cthulhu as restoredCthulhuModule
else:
sys.modules["cthulhu.cthulhu"] = previousCthulhuModule
cthulhu_package.cthulhu = previousCthulhuModule
restoredCthulhuModule = previousCthulhuModule
event_manager.cthulhu = restoredCthulhuModule
class FakeWorkspaceBackend: class FakeWorkspaceBackend:
def __init__(self, available: bool, name: str) -> None: def __init__(self, available: bool, name: str) -> None:
@@ -313,23 +333,38 @@ class CompositorStateAdapterRegressionTests(unittest.TestCase):
adapter = mock.Mock() adapter = mock.Mock()
adapter.sync_accessible_context = mock.Mock(return_value=None) adapter.sync_accessible_context = mock.Mock(return_value=None)
listener = mock.Mock() listener = mock.Mock()
fakeAtspi = types.SimpleNamespace(
EventListener=types.SimpleNamespace(new=mock.Mock(return_value=listener)),
)
fakeCthulhu = types.SimpleNamespace(
setActiveWindow=mock.Mock(),
setLocusOfFocus=mock.Mock(),
)
window = object() window = object()
focusedObject = object() focusedObject = object()
with ( with (
mock.patch.object(cthulhu.event_manager.Atspi.EventListener, "new", return_value=listener), mock.patch.object(event_manager, "Atspi", fakeAtspi),
mock.patch.object(cthulhu.event_manager.AXUtilities, "can_be_active_window", return_value=False), mock.patch.object(event_manager.AXUtilities, "can_be_active_window", return_value=False),
mock.patch.object(cthulhu.event_manager.AXUtilities, "find_active_window", return_value=window), mock.patch.object(event_manager.AXUtilities, "find_active_window", return_value=window),
mock.patch.object(cthulhu.event_manager.AXUtilities, "get_focused_object", return_value=focusedObject), mock.patch.object(event_manager.AXUtilities, "get_focused_object", return_value=focusedObject),
mock.patch.object(cthulhu.event_manager.cthulhu, "setActiveWindow") as setActiveWindow, mock.patch.object(event_manager, "cthulhu", fakeCthulhu),
mock.patch.object(cthulhu.event_manager.cthulhu, "setLocusOfFocus") as setLocusOfFocus,
): ):
manager = cthulhu.event_manager.EventManager(mock.Mock()) manager = event_manager.EventManager(mock.Mock())
manager.set_compositor_state_adapter(adapter) manager.set_compositor_state_adapter(adapter)
manager._sync_focus_on_startup() manager._sync_focus_on_startup()
setActiveWindow.assert_called_once_with(window, alsoSetLocusOfFocus=True, notifyScript=False) fakeCthulhu.setActiveWindow.assert_called_once_with(
setLocusOfFocus.assert_called_once_with(None, focusedObject, notifyScript=True, force=True) window,
alsoSetLocusOfFocus=True,
notifyScript=False,
)
fakeCthulhu.setLocusOfFocus.assert_called_once_with(
None,
focusedObject,
notifyScript=True,
force=True,
)
adapter.sync_accessible_context.assert_called_once_with("event-manager-startup") adapter.sync_accessible_context.assert_called_once_with("event-manager-startup")
+9 -3
View File
@@ -30,6 +30,7 @@ sys.modules.setdefault(
), ),
) )
from cthulhu import ax_document_selection
from cthulhu.script_utilities import Utilities from cthulhu.script_utilities import Utilities
@@ -131,9 +132,14 @@ class DocumentSelectionRegressionTests(unittest.TestCase):
stack.enter_context(mock.patch("cthulhu.script_utilities.AXText.set_selected_text", set_selected_text)) stack.enter_context(mock.patch("cthulhu.script_utilities.AXText.set_selected_text", set_selected_text))
stack.enter_context(mock.patch("cthulhu.script_utilities.AXText._get_n_selections", return_value=1)) stack.enter_context(mock.patch("cthulhu.script_utilities.AXText._get_n_selections", return_value=1))
stack.enter_context(mock.patch("cthulhu.script_utilities.AXText._remove_selection", remove_selection)) stack.enter_context(mock.patch("cthulhu.script_utilities.AXText._remove_selection", remove_selection))
stack.enter_context(mock.patch("cthulhu.script_utilities.Atspi.Document.get_text_selections", side_effect=get_text_selections)) fakeAtspi = types.SimpleNamespace(
stack.enter_context(mock.patch("cthulhu.script_utilities.Atspi.Document.set_text_selections", side_effect=set_text_selections)) Document=types.SimpleNamespace(
stack.enter_context(mock.patch("cthulhu.script_utilities.Atspi.TextSelection", side_effect=self._new_text_selection)) get_text_selections=mock.Mock(side_effect=get_text_selections),
set_text_selections=mock.Mock(side_effect=set_text_selections),
),
TextSelection=mock.Mock(side_effect=self._new_text_selection),
)
stack.enter_context(mock.patch.object(ax_document_selection, "Atspi", fakeAtspi))
stack.enter_context( stack.enter_context(
mock.patch( mock.patch(
"cthulhu.script_utilities.cthulhu.cthulhuApp", "cthulhu.script_utilities.cthulhu.cthulhuApp",
@@ -34,11 +34,12 @@ class EventManagerCompositorContextRegressionTests(unittest.TestCase):
self.addCleanup(self._restore_cthulhu_state) self.addCleanup(self._restore_cthulhu_state)
self.listener = mock.Mock() self.listener = mock.Mock()
self.listenerPatch = mock.patch.object( fakeAtspi = types.SimpleNamespace(
event_manager.Atspi.EventListener, Accessible=event_manager.Atspi.Accessible,
"new", EventListener=types.SimpleNamespace(new=mock.Mock(return_value=self.listener)),
return_value=self.listener, Role=event_manager.Atspi.Role,
) )
self.listenerPatch = mock.patch.object(event_manager, "Atspi", fakeAtspi)
self.listenerPatch.start() self.listenerPatch.start()
self.addCleanup(self.listenerPatch.stop) self.addCleanup(self.listenerPatch.stop)
@@ -27,11 +27,12 @@ class FakeEvent:
class EventManagerRelevanceGateRegressionTests(unittest.TestCase): class EventManagerRelevanceGateRegressionTests(unittest.TestCase):
def setUp(self) -> None: def setUp(self) -> None:
self.listener = mock.Mock() self.listener = mock.Mock()
self.listenerPatch = mock.patch.object( fakeAtspi = types.SimpleNamespace(
event_manager.Atspi.EventListener, Accessible=event_manager.Atspi.Accessible,
"new", EventListener=types.SimpleNamespace(new=mock.Mock(return_value=self.listener)),
return_value=self.listener, Role=event_manager.Atspi.Role,
) )
self.listenerPatch = mock.patch.object(event_manager, "Atspi", fakeAtspi)
self.listenerPatch.start() self.listenerPatch.start()
self.addCleanup(self.listenerPatch.stop) self.addCleanup(self.listenerPatch.stop)
@@ -2,6 +2,7 @@ import sys
import types import types
import unittest import unittest
from pathlib import Path from pathlib import Path
from typing import Any
from unittest import mock from unittest import mock
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
@@ -133,6 +134,20 @@ class InputEventManagerPointerMonitorTests(unittest.TestCase):
class MouseReviewBackendSelectionTests(unittest.TestCase): class MouseReviewBackendSelectionTests(unittest.TestCase):
@staticmethod
def _make_atspi(
version: tuple[int, int, int],
listener: Any,
pointerMonitor: int | None = None,
) -> types.SimpleNamespace:
fakeAtspi = types.SimpleNamespace(
EventListener=types.SimpleNamespace(new=mock.Mock(return_value=listener)),
get_version=mock.Mock(return_value=version),
)
if pointerMonitor is not None:
fakeAtspi.DeviceCapability = types.SimpleNamespace(POINTER_MONITOR=pointerMonitor)
return fakeAtspi
@staticmethod @staticmethod
def _make_app(enabled=False): def _make_app(enabled=False):
app = mock.Mock() app = mock.Mock()
@@ -146,16 +161,10 @@ class MouseReviewBackendSelectionTests(unittest.TestCase):
listener = mock.Mock() listener = mock.Mock()
deviceManager = mock.Mock() deviceManager = mock.Mock()
deviceManager.enable_pointer_monitoring.return_value = True deviceManager.enable_pointer_monitoring.return_value = True
fakeAtspi = self._make_atspi((2, 60, 0), listener, pointerMonitor=8)
with ( with (
mock.patch.object(mouse_review.Atspi.EventListener, "new", return_value=listener), mock.patch.object(mouse_review, "Atspi", fakeAtspi),
mock.patch.object(mouse_review.Atspi, "get_version", return_value=(2, 60, 0)),
mock.patch.object(
mouse_review.Atspi,
"DeviceCapability",
new=types.SimpleNamespace(POINTER_MONITOR=8),
create=True,
),
mock.patch.object(mouse_review.input_event_manager, "get_manager", return_value=deviceManager), mock.patch.object(mouse_review.input_event_manager, "get_manager", return_value=deviceManager),
mock.patch.object(mouse_review, "Wnck", None), mock.patch.object(mouse_review, "Wnck", None),
): ):
@@ -170,16 +179,10 @@ class MouseReviewBackendSelectionTests(unittest.TestCase):
listener = mock.Mock() listener = mock.Mock()
deviceManager = mock.Mock() deviceManager = mock.Mock()
deviceManager.enable_pointer_monitoring.return_value = True deviceManager.enable_pointer_monitoring.return_value = True
fakeAtspi = self._make_atspi((2, 60, 0), listener, pointerMonitor=8)
with ( with (
mock.patch.object(mouse_review.Atspi.EventListener, "new", return_value=listener), mock.patch.object(mouse_review, "Atspi", fakeAtspi),
mock.patch.object(mouse_review.Atspi, "get_version", return_value=(2, 60, 0)),
mock.patch.object(
mouse_review.Atspi,
"DeviceCapability",
new=types.SimpleNamespace(POINTER_MONITOR=8),
create=True,
),
mock.patch.object(mouse_review.input_event_manager, "get_manager", return_value=deviceManager), mock.patch.object(mouse_review.input_event_manager, "get_manager", return_value=deviceManager),
mock.patch.object(mouse_review.cthulhu_state, "locusOfFocus", None), mock.patch.object(mouse_review.cthulhu_state, "locusOfFocus", None),
mock.patch.object(mouse_review, "Wnck", None), mock.patch.object(mouse_review, "Wnck", None),
@@ -202,14 +205,19 @@ class MouseReviewBackendSelectionTests(unittest.TestCase):
screen.get_active_workspace.return_value = None screen.get_active_workspace.return_value = None
fakeWnck = mock.Mock() fakeWnck = mock.Mock()
fakeWnck.Screen.get_default.return_value = screen fakeWnck.Screen.get_default.return_value = screen
fakeAtspi = self._make_atspi((2, 58, 4), listener)
fakeGdk = types.SimpleNamespace(
Display=types.SimpleNamespace(
get_default=mock.Mock(return_value=mock.Mock()),
get_default_seat=mock.Mock(return_value=seat),
),
)
with ( with (
mock.patch.object(mouse_review.Atspi.EventListener, "new", return_value=listener), mock.patch.object(mouse_review, "Atspi", fakeAtspi),
mock.patch.object(mouse_review.Atspi, "get_version", return_value=(2, 58, 4)),
mock.patch.object(mouse_review.input_event_manager, "get_manager"), mock.patch.object(mouse_review.input_event_manager, "get_manager"),
mock.patch.object(mouse_review.cthulhu_state, "locusOfFocus", None), mock.patch.object(mouse_review.cthulhu_state, "locusOfFocus", None),
mock.patch.object(mouse_review.Gdk.Display, "get_default", return_value=mock.Mock()), mock.patch.object(mouse_review, "Gdk", fakeGdk),
mock.patch.object(mouse_review.Gdk.Display, "get_default_seat", return_value=seat),
mock.patch.object(mouse_review, "Wnck", fakeWnck), mock.patch.object(mouse_review, "Wnck", fakeWnck),
): ):
reviewer = mouse_review.MouseReviewer(self._make_app(enabled=False)) reviewer = mouse_review.MouseReviewer(self._make_app(enabled=False))