Merge branch 'testing' into wine-access
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
|
||||
|
||||
stubCthulhu = types.ModuleType("cthulhu.cthulhu")
|
||||
stubCthulhu.cthulhuApp = mock.Mock()
|
||||
sys.modules.setdefault("cthulhu.cthulhu", stubCthulhu)
|
||||
|
||||
from cthulhu import event_manager
|
||||
|
||||
|
||||
class FakeEvent:
|
||||
def __init__(self, event_type, source="window", detail1=0):
|
||||
self.type = event_type
|
||||
self.source = source
|
||||
self.detail1 = detail1
|
||||
self.detail2 = 0
|
||||
self.any_data = None
|
||||
|
||||
|
||||
class EventManagerXtermHandoffRegressionTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
listener = mock.Mock()
|
||||
fakeAtspi = types.SimpleNamespace(
|
||||
Accessible=event_manager.Atspi.Accessible,
|
||||
EventListener=types.SimpleNamespace(new=mock.Mock(return_value=listener)),
|
||||
Role=event_manager.Atspi.Role,
|
||||
)
|
||||
self.listenerPatch = mock.patch.object(event_manager, "Atspi", fakeAtspi)
|
||||
self.listenerPatch.start()
|
||||
self.addCleanup(self.listenerPatch.stop)
|
||||
|
||||
self.manager = event_manager.EventManager(mock.Mock(), asyncMode=False)
|
||||
self.manager._active = True
|
||||
self.manager._inputEventManager = mock.Mock()
|
||||
self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.return_value = True
|
||||
self.manager._get_scriptForEvent = mock.Mock()
|
||||
|
||||
def test_window_activate_is_dropped_while_xterm_is_foreground(self) -> None:
|
||||
event = FakeEvent("window:activate")
|
||||
|
||||
with (
|
||||
mock.patch.object(event_manager.debug, "printObjectEvent"),
|
||||
mock.patch.object(event_manager.debug, "printMessage"),
|
||||
):
|
||||
self.manager._processObjectEvent(event)
|
||||
|
||||
self.manager._get_scriptForEvent.assert_not_called()
|
||||
self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.assert_called_once_with(
|
||||
refresh=True,
|
||||
)
|
||||
|
||||
def test_active_frame_event_is_dropped_while_xterm_is_foreground(self) -> None:
|
||||
event = FakeEvent("object:state-changed:active", detail1=1)
|
||||
|
||||
with (
|
||||
mock.patch.object(event_manager.debug, "printObjectEvent"),
|
||||
mock.patch.object(event_manager.debug, "printMessage"),
|
||||
mock.patch.object(event_manager.AXUtilities, "is_frame", return_value=True),
|
||||
):
|
||||
self.manager._processObjectEvent(event)
|
||||
|
||||
self.manager._get_scriptForEvent.assert_not_called()
|
||||
self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.assert_called_once_with(
|
||||
refresh=True,
|
||||
)
|
||||
|
||||
def test_focused_event_is_dropped_while_xterm_is_foreground(self) -> None:
|
||||
event = FakeEvent("object:state-changed:focused", detail1=1)
|
||||
|
||||
with (
|
||||
mock.patch.object(event_manager.debug, "printObjectEvent"),
|
||||
mock.patch.object(event_manager.debug, "printMessage"),
|
||||
):
|
||||
self.manager._processObjectEvent(event)
|
||||
|
||||
self.manager._get_scriptForEvent.assert_not_called()
|
||||
self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.assert_called_once_with(
|
||||
refresh=True,
|
||||
)
|
||||
|
||||
def test_background_event_is_dropped_during_xterm_handoff_without_refresh(self) -> None:
|
||||
event = FakeEvent("object:text-changed:insert")
|
||||
|
||||
with (
|
||||
mock.patch.object(event_manager.debug, "printObjectEvent"),
|
||||
mock.patch.object(event_manager.debug, "printMessage"),
|
||||
):
|
||||
self.manager._processObjectEvent(event)
|
||||
|
||||
self.manager._get_scriptForEvent.assert_not_called()
|
||||
self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.assert_called_once_with(
|
||||
refresh=False,
|
||||
)
|
||||
|
||||
def test_notification_daemon_window_create_is_processed_during_xterm_handoff(self) -> None:
|
||||
event = FakeEvent("window:create", source=object())
|
||||
notificationApp = object()
|
||||
self.manager._isActivatableEvent = mock.Mock(return_value=(False, "test"))
|
||||
|
||||
with (
|
||||
mock.patch.object(event_manager.debug, "printObjectEvent"),
|
||||
mock.patch.object(event_manager.debug, "printMessage"),
|
||||
mock.patch.object(
|
||||
event_manager.AXObject,
|
||||
"get_application",
|
||||
return_value=notificationApp,
|
||||
),
|
||||
mock.patch.object(
|
||||
event_manager.AXObject,
|
||||
"get_name",
|
||||
return_value="xfce4-notifyd",
|
||||
),
|
||||
mock.patch.object(event_manager.AXObject, "is_dead", return_value=False),
|
||||
mock.patch.object(event_manager.AXUtilities, "is_defunct", return_value=False),
|
||||
mock.patch.object(event_manager.AXUtilities, "is_iconified", return_value=False),
|
||||
):
|
||||
self.manager._processObjectEvent(event)
|
||||
|
||||
self.manager._get_scriptForEvent.assert_called_once_with(event)
|
||||
self.manager._inputEventManager.should_suppress_atspi_events_for_xterm.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -130,6 +130,7 @@ class InputEventManagerKeyWatcherTests(unittest.TestCase):
|
||||
),
|
||||
mock.patch.object(input_event_manager.pyatspi.Registry, "registerKeystrokeListener") as register,
|
||||
mock.patch.object(input_event_manager.pyatspi.Registry, "deregisterKeystrokeListener") as deregister,
|
||||
mock.patch.object(manager, "_initialize_xterm_handoff") as initializeXtermHandoff,
|
||||
):
|
||||
manager.start_key_watcher()
|
||||
manager.stop_key_watcher()
|
||||
@@ -161,6 +162,7 @@ class InputEventManagerKeyWatcherTests(unittest.TestCase):
|
||||
mask=expectedMasks,
|
||||
kind=(0, 1),
|
||||
)
|
||||
initializeXtermHandoff.assert_called_once_with()
|
||||
self.assertEqual(
|
||||
device.connect_calls,
|
||||
[
|
||||
|
||||
@@ -530,19 +530,200 @@ class InputEventManagerX11FocusRegressionTests(unittest.TestCase):
|
||||
activeScript = mock.Mock()
|
||||
scriptManager = mock.Mock()
|
||||
scriptManager.get_active_script.return_value = activeScript
|
||||
screen = mock.Mock()
|
||||
activeWindow = object()
|
||||
screen.get_active_window.return_value = activeWindow
|
||||
manager._scriptWithSuspendedGrabsForXterm = activeScript
|
||||
|
||||
with (
|
||||
mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager),
|
||||
mock.patch.object(manager, "_x11_window_xterm_match", return_value=False) as matcher,
|
||||
mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=False) as matcher,
|
||||
mock.patch.object(input_event_manager.debug, "print_tokens"),
|
||||
):
|
||||
manager._on_active_x11_window_changed(screen, None)
|
||||
manager._on_active_x11_window_changed(mock.Mock(), None)
|
||||
|
||||
matcher.assert_called_once_with()
|
||||
activeScript.addKeyGrabs.assert_called_once_with()
|
||||
self.assertIsNone(manager._scriptWithSuspendedGrabsForXterm)
|
||||
|
||||
def test_active_x11_window_uses_ewmh_id_instead_of_stale_wnck_active_window(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
wnck = mock.Mock()
|
||||
screen = mock.Mock()
|
||||
ewmhWindow = object()
|
||||
wnck.Screen.get_default.return_value = screen
|
||||
wnck.Window.get.return_value = ewmhWindow
|
||||
|
||||
with (
|
||||
mock.patch.object(manager, "_get_wnck", return_value=wnck),
|
||||
mock.patch.object(manager, "_ensure_xterm_focus_monitor"),
|
||||
mock.patch.object(manager, "_get_ewmh_active_x11_window_id", return_value=0x1400010),
|
||||
):
|
||||
result = manager._get_active_x11_window()
|
||||
|
||||
self.assertIs(result, ewmhWindow)
|
||||
wnck.Window.get.assert_called_once_with(0x1400010)
|
||||
screen.get_active_window.assert_not_called()
|
||||
|
||||
def test_active_x11_window_does_not_fall_back_to_stale_wnck_window_for_known_ewmh_id(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
wnck = mock.Mock()
|
||||
screen = mock.Mock()
|
||||
wnck.Screen.get_default.return_value = screen
|
||||
wnck.Window.get.return_value = None
|
||||
|
||||
with (
|
||||
mock.patch.object(manager, "_get_wnck", return_value=wnck),
|
||||
mock.patch.object(manager, "_ensure_xterm_focus_monitor"),
|
||||
mock.patch.object(manager, "_get_ewmh_active_x11_window_id", return_value=0x1400010),
|
||||
mock.patch.object(input_event_manager.debug, "print_tokens"),
|
||||
):
|
||||
result = manager._get_active_x11_window()
|
||||
|
||||
self.assertIsNone(result)
|
||||
screen.get_active_window.assert_not_called()
|
||||
|
||||
def test_active_x11_window_falls_back_to_wnck_when_ewmh_is_unavailable(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
wnck = mock.Mock()
|
||||
screen = mock.Mock()
|
||||
fallbackWindow = object()
|
||||
wnck.Screen.get_default.return_value = screen
|
||||
screen.get_active_window.return_value = fallbackWindow
|
||||
|
||||
with (
|
||||
mock.patch.object(manager, "_get_wnck", return_value=wnck),
|
||||
mock.patch.object(manager, "_ensure_xterm_focus_monitor"),
|
||||
mock.patch.object(manager, "_get_ewmh_active_x11_window_id", return_value=None),
|
||||
):
|
||||
result = manager._get_active_x11_window()
|
||||
|
||||
self.assertIs(result, fallbackWindow)
|
||||
|
||||
def test_xterm_match_reuses_cached_metadata_while_ewmh_window_id_is_unchanged(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
activeWindow = object()
|
||||
|
||||
with (
|
||||
mock.patch.object(
|
||||
manager,
|
||||
"_get_ewmh_active_x11_window_id",
|
||||
return_value=0x1400010,
|
||||
),
|
||||
mock.patch.object(
|
||||
manager,
|
||||
"_get_active_x11_window",
|
||||
return_value=activeWindow,
|
||||
) as getActiveWindow,
|
||||
mock.patch.object(
|
||||
manager,
|
||||
"_x11_window_xterm_match",
|
||||
return_value=False,
|
||||
) as matcher,
|
||||
):
|
||||
firstResult = manager._active_x11_window_xterm_match()
|
||||
secondResult = manager._active_x11_window_xterm_match()
|
||||
|
||||
self.assertFalse(firstResult)
|
||||
self.assertFalse(secondResult)
|
||||
getActiveWindow.assert_called_once_with(ewmhWindowId=0x1400010)
|
||||
matcher.assert_called_once_with(activeWindow)
|
||||
|
||||
def test_xterm_focus_change_suspends_grabs_without_keyboard_event(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
activeScript = mock.Mock()
|
||||
scriptManager = mock.Mock()
|
||||
scriptManager.get_active_script.return_value = activeScript
|
||||
|
||||
with (
|
||||
mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager),
|
||||
mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=True) as matcher,
|
||||
mock.patch.object(input_event_manager.debug, "print_tokens"),
|
||||
):
|
||||
manager._on_active_x11_window_changed(mock.Mock(), None)
|
||||
|
||||
matcher.assert_called_once_with()
|
||||
activeScript.removeKeyGrabs.assert_called_once_with()
|
||||
self.assertIs(manager._scriptWithSuspendedGrabsForXterm, activeScript)
|
||||
|
||||
def test_initial_xterm_handoff_suspends_grabs(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
manager._device = object()
|
||||
|
||||
with (
|
||||
mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=True),
|
||||
mock.patch.object(manager, "_suspend_key_grabs_for_xterm") as suspend,
|
||||
mock.patch.object(manager, "_ensure_xterm_recovery_timer") as ensureTimer,
|
||||
mock.patch.object(input_event_manager.debug, "print_tokens"),
|
||||
):
|
||||
manager._initialize_xterm_handoff()
|
||||
|
||||
suspend.assert_called_once_with()
|
||||
ensureTimer.assert_called_once_with()
|
||||
|
||||
def test_xterm_focus_poll_suspends_grabs_after_entering_xterm(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
manager._device = object()
|
||||
|
||||
with (
|
||||
mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=True),
|
||||
mock.patch.object(manager, "_suspend_key_grabs_for_xterm") as suspend,
|
||||
mock.patch.object(manager, "_restore_key_grabs_after_xterm") as restore,
|
||||
mock.patch.object(input_event_manager.debug, "print_tokens"),
|
||||
):
|
||||
result = manager._poll_xterm_grab_recovery()
|
||||
|
||||
self.assertTrue(result)
|
||||
suspend.assert_called_once_with()
|
||||
restore.assert_not_called()
|
||||
|
||||
def test_xterm_focus_poll_restores_grabs_after_leaving_xterm(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
manager._device = object()
|
||||
|
||||
with (
|
||||
mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=False),
|
||||
mock.patch.object(manager, "_suspend_key_grabs_for_xterm") as suspend,
|
||||
mock.patch.object(manager, "_restore_key_grabs_after_xterm") as restore,
|
||||
mock.patch.object(input_event_manager.debug, "print_tokens"),
|
||||
):
|
||||
result = manager._poll_xterm_grab_recovery()
|
||||
|
||||
self.assertTrue(result)
|
||||
restore.assert_called_once_with()
|
||||
suspend.assert_not_called()
|
||||
|
||||
def test_xterm_suppression_does_not_check_x11_without_active_handoff(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
|
||||
with mock.patch.object(manager, "_active_x11_window_xterm_match") as matcher:
|
||||
result = manager.should_suppress_atspi_events_for_xterm(refresh=True)
|
||||
|
||||
self.assertFalse(result)
|
||||
matcher.assert_not_called()
|
||||
|
||||
def test_xterm_suppression_ignores_background_event_without_x11_refresh(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
manager._scriptWithSuspendedGrabsForXterm = object()
|
||||
|
||||
with mock.patch.object(manager, "_active_x11_window_xterm_match") as matcher:
|
||||
result = manager.should_suppress_atspi_events_for_xterm(refresh=False)
|
||||
|
||||
self.assertTrue(result)
|
||||
matcher.assert_not_called()
|
||||
|
||||
def test_xterm_suppression_releases_handoff_for_real_focus_return(self):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
activeScript = mock.Mock()
|
||||
scriptManager = mock.Mock()
|
||||
scriptManager.get_active_script.return_value = activeScript
|
||||
manager._scriptWithSuspendedGrabsForXterm = activeScript
|
||||
|
||||
with (
|
||||
mock.patch.object(input_event_manager.script_manager, "get_manager", return_value=scriptManager),
|
||||
mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=False),
|
||||
mock.patch.object(input_event_manager.debug, "print_tokens"),
|
||||
):
|
||||
result = manager.should_suppress_atspi_events_for_xterm(refresh=True)
|
||||
|
||||
self.assertFalse(result)
|
||||
activeScript.addKeyGrabs.assert_called_once_with()
|
||||
self.assertIsNone(manager._scriptWithSuspendedGrabsForXterm)
|
||||
|
||||
@@ -550,14 +731,13 @@ class InputEventManagerX11FocusRegressionTests(unittest.TestCase):
|
||||
manager = input_event_manager.InputEventManager()
|
||||
manager._device = object()
|
||||
manager._scriptWithSuspendedGrabsForXterm = object()
|
||||
screen = mock.Mock()
|
||||
screen.get_active_window.side_effect = RuntimeError("focus unavailable")
|
||||
|
||||
with (
|
||||
mock.patch.object(manager, "_active_x11_window_xterm_match", return_value=None),
|
||||
mock.patch.object(input_event_manager.GLib, "timeout_add", return_value=23),
|
||||
mock.patch.object(input_event_manager.debug, "print_message"),
|
||||
mock.patch.object(input_event_manager.debug, "print_tokens"),
|
||||
):
|
||||
manager._on_active_x11_window_changed(screen, None)
|
||||
manager._on_active_x11_window_changed(mock.Mock(), None)
|
||||
|
||||
self.assertEqual(manager._xtermRecoverySourceId, 23)
|
||||
|
||||
@@ -619,6 +799,9 @@ class InputEventManagerX11FocusRegressionTests(unittest.TestCase):
|
||||
manager._xtermFocusHandlerId = 17
|
||||
manager._xtermRecoverySourceId = 23
|
||||
manager._scriptWithSuspendedGrabsForXterm = object()
|
||||
x11Display = mock.Mock()
|
||||
manager._x11Display = x11Display
|
||||
manager._didAttemptX11Display = True
|
||||
|
||||
with (
|
||||
mock.patch.object(input_event_manager.GLib, "source_remove") as sourceRemove,
|
||||
@@ -632,6 +815,8 @@ class InputEventManagerX11FocusRegressionTests(unittest.TestCase):
|
||||
self.assertEqual(manager._xtermFocusHandlerId, 0)
|
||||
self.assertEqual(manager._xtermRecoverySourceId, 0)
|
||||
self.assertIsNone(manager._scriptWithSuspendedGrabsForXterm)
|
||||
x11Display.close.assert_called_once_with()
|
||||
self.assertFalse(manager._didAttemptX11Display)
|
||||
|
||||
def test_identifier_is_xterm_matches_exact_xterm_only(self):
|
||||
self.assertTrue(input_event_manager.InputEventManager._identifier_is_xterm("xterm"))
|
||||
|
||||
@@ -80,6 +80,10 @@ class RuntimeStateSnapshotTests(unittest.TestCase):
|
||||
manager._grabbed_bindings = {10: object(), 11: object()}
|
||||
manager._paused = True
|
||||
manager._scriptWithSuspendedGrabsForXterm = object()
|
||||
manager._xtermFocusHandlerId = 17
|
||||
manager._xtermRecoverySourceId = 23
|
||||
manager._lastEwmhActiveWindowId = 0x1400010
|
||||
manager._lastEwmhXtermMatch = False
|
||||
manager._last_input_event = object()
|
||||
manager._last_non_modifier_key_event = None
|
||||
|
||||
@@ -91,6 +95,10 @@ class RuntimeStateSnapshotTests(unittest.TestCase):
|
||||
self.assertEqual(1, snapshot["mapped_keysyms"])
|
||||
self.assertEqual(2, snapshot["grabbed_bindings"])
|
||||
self.assertTrue(snapshot["suspended_xterm_script_present"])
|
||||
self.assertTrue(snapshot["xterm_focus_monitor_active"])
|
||||
self.assertTrue(snapshot["xterm_recovery_timer_active"])
|
||||
self.assertEqual("0x1400010", snapshot["last_ewmh_active_window_id"])
|
||||
self.assertFalse(snapshot["last_ewmh_xterm_match"])
|
||||
self.assertFalse(snapshot["last_non_modifier_key_event_present"])
|
||||
|
||||
def test_script_manager_snapshot_reports_cache_counts(self) -> None:
|
||||
|
||||
@@ -177,5 +177,137 @@ class CheckedStateRoutingContractTests(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
class ExpandedStateRoutingContractTests(unittest.TestCase):
|
||||
def test_shared_web_owns_expanded_state_without_default_fallback(self):
|
||||
for toolkit_script in (chromium_script, gecko_script):
|
||||
with self.subTest(toolkit=toolkit_script.__name__):
|
||||
test_script = toolkit_script.Script.__new__(toolkit_script.Script)
|
||||
test_script._eventRouter = WebEventRouter()
|
||||
event = object()
|
||||
with (
|
||||
mock.patch.object(
|
||||
web.Script,
|
||||
"onExpandedChanged",
|
||||
return_value=True,
|
||||
) as web_handler,
|
||||
mock.patch.object(
|
||||
default.Script,
|
||||
"onExpandedChanged",
|
||||
) as default_handler,
|
||||
mock.patch(
|
||||
"cthulhu.scripts.web.event_router.debug.printMessage"
|
||||
) as print_message,
|
||||
):
|
||||
toolkit_script.Script.onExpandedChanged(test_script, event)
|
||||
|
||||
web_handler.assert_called_once_with(test_script, event)
|
||||
default_handler.assert_not_called()
|
||||
messages = [call.args[1] for call in print_message.call_args_list]
|
||||
self.assertIn(
|
||||
"WEB EVENT ROUTER: SHARED_WEB -> HANDLED",
|
||||
messages,
|
||||
)
|
||||
|
||||
def test_unhandled_expanded_state_reaches_default_once(self):
|
||||
for toolkit_script in (chromium_script, gecko_script):
|
||||
with self.subTest(toolkit=toolkit_script.__name__):
|
||||
test_script = toolkit_script.Script.__new__(toolkit_script.Script)
|
||||
test_script._eventRouter = WebEventRouter()
|
||||
event = object()
|
||||
with (
|
||||
mock.patch.object(
|
||||
web.Script,
|
||||
"onExpandedChanged",
|
||||
return_value=False,
|
||||
) as web_handler,
|
||||
mock.patch.object(
|
||||
default.Script,
|
||||
"onExpandedChanged",
|
||||
) as default_handler,
|
||||
mock.patch(
|
||||
"cthulhu.scripts.web.event_router.debug.printMessage"
|
||||
) as print_message,
|
||||
):
|
||||
toolkit_script.Script.onExpandedChanged(test_script, event)
|
||||
|
||||
web_handler.assert_called_once_with(test_script, event)
|
||||
default_handler.assert_called_once_with(test_script, event)
|
||||
messages = [call.args[1] for call in print_message.call_args_list]
|
||||
self.assertIn(
|
||||
"WEB EVENT ROUTER: DEFAULT -> HANDLED",
|
||||
messages,
|
||||
)
|
||||
|
||||
|
||||
class TableReorderRoutingContractTests(unittest.TestCase):
|
||||
def test_shared_web_owns_table_reorder_without_default_fallback(self):
|
||||
for toolkit_script in (chromium_script, gecko_script):
|
||||
for handler_name in ("onColumnReordered", "onRowReordered"):
|
||||
with self.subTest(
|
||||
toolkit=toolkit_script.__name__,
|
||||
handler=handler_name,
|
||||
):
|
||||
test_script = toolkit_script.Script.__new__(toolkit_script.Script)
|
||||
test_script._eventRouter = WebEventRouter()
|
||||
event = object()
|
||||
with (
|
||||
mock.patch.object(
|
||||
web.Script,
|
||||
handler_name,
|
||||
return_value=True,
|
||||
) as web_handler,
|
||||
mock.patch.object(
|
||||
default.Script,
|
||||
handler_name,
|
||||
) as default_handler,
|
||||
mock.patch(
|
||||
"cthulhu.scripts.web.event_router.debug.printMessage"
|
||||
) as print_message,
|
||||
):
|
||||
getattr(toolkit_script.Script, handler_name)(test_script, event)
|
||||
|
||||
web_handler.assert_called_once_with(test_script, event)
|
||||
default_handler.assert_not_called()
|
||||
messages = [call.args[1] for call in print_message.call_args_list]
|
||||
self.assertIn(
|
||||
"WEB EVENT ROUTER: SHARED_WEB -> HANDLED",
|
||||
messages,
|
||||
)
|
||||
|
||||
def test_unhandled_table_reorder_reaches_default_once(self):
|
||||
for toolkit_script in (chromium_script, gecko_script):
|
||||
for handler_name in ("onColumnReordered", "onRowReordered"):
|
||||
with self.subTest(
|
||||
toolkit=toolkit_script.__name__,
|
||||
handler=handler_name,
|
||||
):
|
||||
test_script = toolkit_script.Script.__new__(toolkit_script.Script)
|
||||
test_script._eventRouter = WebEventRouter()
|
||||
event = object()
|
||||
with (
|
||||
mock.patch.object(
|
||||
web.Script,
|
||||
handler_name,
|
||||
return_value=False,
|
||||
) as web_handler,
|
||||
mock.patch.object(
|
||||
default.Script,
|
||||
handler_name,
|
||||
) as default_handler,
|
||||
mock.patch(
|
||||
"cthulhu.scripts.web.event_router.debug.printMessage"
|
||||
) as print_message,
|
||||
):
|
||||
getattr(toolkit_script.Script, handler_name)(test_script, event)
|
||||
|
||||
web_handler.assert_called_once_with(test_script, event)
|
||||
default_handler.assert_called_once_with(test_script, event)
|
||||
messages = [call.args[1] for call in print_message.call_args_list]
|
||||
self.assertIn(
|
||||
"WEB EVENT ROUTER: DEFAULT -> HANDLED",
|
||||
messages,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user