import unittest from unittest import mock from cthulhu import dbus_service class SampleModule: def __init__(self): self.enabled = False self.calls = [] @dbus_service.command def toggle_feature(self, script=None, event=None, notify_user=True): """Toggles the test feature.""" self.calls.append((script, event, notify_user)) return True @dbus_service.command def command_without_notify(self, script=None, event=None): """Runs a command that does not accept notify_user.""" self.calls.append((script, event)) return True @dbus_service.command def list_items(self) -> "list[str]": """Returns a list from a command.""" return ["alpha", "beta"] @dbus_service.parameterized_command def speak_text( self, text: "str", count: "int" = 1, script=None, event=None, notify_user=True, ) -> "str": """Speaks text a number of times.""" self.calls.append((text, count, script, event, notify_user)) return text * count @dbus_service.getter def get_enabled(self) -> "bool": """Returns whether the feature is enabled.""" return self.enabled @dbus_service.setter def set_enabled(self, value: "bool"): """Sets whether the feature is enabled.""" self.enabled = value class NativeInterfaceBuilderTest(unittest.TestCase): def test_registration_groups_decorated_members_by_native_names(self): registration = dbus_service._ModuleRegistration.from_module_instance( "TestModule", SampleModule() ) self.assertIn("ToggleFeature", registration.get_commands()) self.assertIn("SpeakText", registration.get_parameterized_commands()) self.assertIn("Enabled", registration.get_getters()) self.assertIn("Enabled", registration.get_setters()) self.assertEqual(registration.total_member_count(), 6) def test_interface_builder_exposes_methods_and_properties(self): registration = dbus_service._ModuleRegistration.from_module_instance( "TestModule", SampleModule() ) interface_class = dbus_service._InterfaceBuilder.build(registration) self.assertTrue(hasattr(interface_class, "ToggleFeature")) self.assertTrue(hasattr(interface_class, "CommandWithoutNotify")) self.assertTrue(hasattr(interface_class, "ListItems")) self.assertTrue(hasattr(interface_class, "SpeakText")) self.assertIsInstance(interface_class.Enabled, property) self.assertFalse(hasattr(interface_class, "ExecuteCommand")) self.assertIn("org.stormux.Cthulhu1.TestModule", interface_class.__dbus_xml__) def test_generated_command_method_uses_active_or_default_script(self): module = SampleModule() registration = dbus_service._ModuleRegistration.from_module_instance("TestModule", module) interface = dbus_service._InterfaceBuilder.build(registration)() script = mock.Mock() manager = mock.Mock() manager.get_active_script.return_value = None manager.get_default_script.return_value = script event_manager = mock.Mock() event_manager_module = mock.Mock() event_manager_module.get_manager.return_value = event_manager with ( mock.patch.object(dbus_service.script_manager, "get_manager", return_value=manager), mock.patch.object( dbus_service, "_get_input_event_manager", return_value=event_manager_module ), ): self.assertTrue(interface.ToggleFeature(False)) self.assertTrue(interface.CommandWithoutNotify(False)) self.assertEqual(interface.ListItems(False), ["alpha", "beta"]) self.assertEqual(module.calls[0][0], script) self.assertFalse(module.calls[0][2]) self.assertEqual(module.calls[1][0], script) self.assertEqual(event_manager.process_remote_controller_event.call_count, 3) def test_generated_properties_call_getters_and_setters(self): module = SampleModule() registration = dbus_service._ModuleRegistration.from_module_instance("TestModule", module) interface = dbus_service._InterfaceBuilder.build(registration)() self.assertFalse(interface.Enabled) interface.Enabled = True self.assertTrue(module.enabled) self.assertTrue(interface.Enabled) class NativeRemoteControllerTest(unittest.TestCase): def test_controller_uses_versioned_service_name_and_object_path(self): self.assertEqual(dbus_service.CthulhuRemoteController.SERVICE_NAME, "org.stormux.Cthulhu1.Service") self.assertEqual(dbus_service.CthulhuRemoteController.OBJECT_PATH, "/org/stormux/Cthulhu1/Service") if __name__ == "__main__": unittest.main()