import queue import sys import types import unittest from pathlib import Path from types import SimpleNamespace from unittest import mock sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src")) from cthulhu import cthulhu_state from cthulhu import debug stubCthulhu = types.ModuleType("cthulhu.cthulhu") stubCthulhu.cthulhuApp = mock.Mock() sys.modules.setdefault("cthulhu.cthulhu", stubCthulhu) from cthulhu import event_manager from cthulhu.input_event_manager import InputEventManager from cthulhu.plugin_system_manager import PluginSystemManager from cthulhu.script_manager import ScriptManager class RuntimeStateSnapshotTests(unittest.TestCase): def test_formatter_sorts_keys_and_groups_sections(self) -> None: result = debug.format_runtime_state_snapshot({ "event_manager": {"z_count": 2, "a_count": 1}, "speech": {"speech_server_present": False}, }) self.assertEqual( result, "\n".join([ "CTHULHU RUNTIME STATE SNAPSHOT", "[event_manager]", "a_count: 1", "z_count: 2", "[speech]", "speech_server_present: False", ]), ) def test_event_manager_snapshot_reports_core_counters(self) -> None: manager = event_manager.EventManager.__new__(event_manager.EventManager) manager._active = True manager._asyncMode = True manager._eventQueue = queue.Queue() manager._eventQueue.put(object()) manager._prioritizedEvent = object() manager._gidleId = 11 manager._prioritizedIdleId = 12 manager._eventsSuspended = True manager._suspendableEvents = ["object:children-changed:add"] manager._eventsTriggeringSuspension = [object(), object()] manager._ignoredEvents = ["object:bounds-changed"] manager._scriptListenerCounts = {"focus:": 1} manager._parentsOfDefunctDescendants = [object()] manager._cmdlineCache = {123: "app"} manager._relevanceBurstHistory = {("a", "b", "c"): 1.0} manager._churnSuppressed = True manager._prioritizedContextToken = "token" manager._keyHandlingActive = True manager._inputEventManager = object() snapshot = manager.get_debug_snapshot() self.assertEqual(1, snapshot["event_queue_size"]) self.assertTrue(snapshot["prioritized_event_present"]) self.assertEqual(11, snapshot["idle_source_id"]) self.assertEqual(2, snapshot["events_triggering_suspension"]) self.assertEqual(1, snapshot["cmdline_cache_size"]) self.assertTrue(snapshot["prioritized_context_token_present"]) def test_input_event_manager_snapshot_reports_grab_state(self) -> None: manager = InputEventManager() manager._device = object() manager._pointer_moved_id = 42 manager._mapped_keycodes = [1, 2] manager._mapped_keysyms = [3] manager._grabbed_bindings = {10: object(), 11: object()} manager._paused = True manager._scriptWithSuspendedGrabsForXterm = object() manager._last_input_event = object() manager._last_non_modifier_key_event = None snapshot = manager.get_debug_snapshot() self.assertTrue(snapshot["device_active"]) self.assertTrue(snapshot["pointer_watcher_active"]) self.assertEqual(2, snapshot["mapped_keycodes"]) self.assertEqual(1, snapshot["mapped_keysyms"]) self.assertEqual(2, snapshot["grabbed_bindings"]) self.assertTrue(snapshot["suspended_xterm_script_present"]) self.assertFalse(snapshot["last_non_modifier_key_event_present"]) def test_script_manager_snapshot_reports_cache_counts(self) -> None: activeScript = SimpleNamespace(app=None) oldActiveScript = cthulhu_state.activeScript cthulhu_state.activeScript = activeScript try: manager = ScriptManager.__new__(ScriptManager) manager._active = True manager._defaultScript = object() manager.appScripts = {"app": object()} manager.toolkitScripts = {"app": {"toolkit": object()}} manager.customScripts = {"app": {"role": object(), "other": object()}} manager._sleepModeScripts = {"app": object()} snapshot = manager.get_debug_snapshot() finally: cthulhu_state.activeScript = oldActiveScript self.assertTrue(snapshot["active"]) self.assertEqual("SimpleNamespace", snapshot["active_script"]) self.assertTrue(snapshot["default_script_present"]) self.assertEqual(1, snapshot["app_scripts"]) self.assertEqual(1, snapshot["toolkit_scripts"]) self.assertEqual(2, snapshot["custom_scripts"]) self.assertEqual(1, snapshot["sleep_mode_scripts"]) def test_plugin_system_manager_snapshot_reports_plugin_counts(self) -> None: manager = PluginSystemManager.__new__(PluginSystemManager) manager._plugins = { "Loaded": SimpleNamespace(loaded=True, builtin=False, hidden=False), "Builtin": SimpleNamespace(loaded=True, builtin=True, hidden=False), "Hidden": SimpleNamespace(loaded=False, builtin=False, hidden=True), } manager._active_plugins = ["Loaded", "Builtin"] manager._plugin_keybindings = {"Loaded": [object(), object()]} manager._global_bindings = [object()] manager._last_active_script = object() manager.plugin_manager = mock.Mock() manager.plugin_manager.get_plugins.return_value = [object(), object()] snapshot = manager.get_debug_snapshot() self.assertEqual(3, snapshot["scanned_plugins"]) self.assertEqual(2, snapshot["active_plugins"]) self.assertEqual(2, snapshot["loaded_plugins"]) self.assertEqual(1, snapshot["builtin_plugins"]) self.assertEqual(1, snapshot["hidden_plugins"]) self.assertEqual(2, snapshot["plugin_keybindings"]) self.assertEqual(1, snapshot["global_keybindings"]) self.assertEqual(2, snapshot["pluggy_registered_plugins"]) if __name__ == "__main__": unittest.main()