diff --git a/tests/unit_tests/test_plugin_utils.py b/tests/unit_tests/test_plugin_utils.py index ef9c456e..4537d245 100644 --- a/tests/unit_tests/test_plugin_utils.py +++ b/tests/unit_tests/test_plugin_utils.py @@ -1,4 +1,6 @@ -from bec_widgets.utils.plugin_utils import get_custom_classes +import sys + +from bec_widgets.utils.plugin_utils import get_custom_class_references, get_custom_classes def test_client_generator_classes(): @@ -10,3 +12,13 @@ def test_client_generator_classes(): assert "Waveform" in connector_cls_names assert "MotorMap" in plugins assert "NonExisting" not in plugins + + +def test_get_custom_class_references_avoids_importing_widget_modules(): + target_module = "bec_widgets.widgets.plots.image.image" + sys.modules.pop(target_module, None) + + references = get_custom_class_references("bec_widgets", use_cache=False) + + assert "Image" in [reference.name for reference in references] + assert target_module not in sys.modules diff --git a/tests/unit_tests/test_rpc_widget_handler.py b/tests/unit_tests/test_rpc_widget_handler.py index ed213b8b..cabdf232 100644 --- a/tests/unit_tests/test_rpc_widget_handler.py +++ b/tests/unit_tests/test_rpc_widget_handler.py @@ -1,8 +1,9 @@ +import sys +from types import ModuleType from unittest.mock import patch from bec_widgets.cli.rpc.rpc_widget_handler import RPCWidgetHandler -from bec_widgets.utils.bec_widget import BECWidget -from bec_widgets.utils.plugin_utils import BECClassContainer, BECClassInfo +from bec_widgets.utils.plugin_utils import BECClassReference def test_rpc_widget_handler(): @@ -12,19 +13,38 @@ def test_rpc_widget_handler(): assert "BECDockArea" in handler.widget_classes -class _TestPluginWidget(BECWidget): ... +def test_duplicate_plugins_not_allowed(monkeypatch): + builtin_module = ModuleType("builtin_test_widgets") + plugin_module = ModuleType("plugin_test_widgets") + SharedWidgetBuiltin = type("SharedWidget", (), {}) + SharedWidgetBuiltin.__module__ = builtin_module.__name__ + setattr(builtin_module, "SharedWidget", SharedWidgetBuiltin) -@patch( - "bec_widgets.cli.rpc.rpc_widget_handler.get_all_plugin_widgets", - return_value=BECClassContainer( - [ - BECClassInfo(name="DeviceComboBox", obj=_TestPluginWidget, module="", file=""), - BECClassInfo(name="NewPluginWidget", obj=_TestPluginWidget, module="", file=""), - ] - ), -) -def test_duplicate_plugins_not_allowed(_): - handler = RPCWidgetHandler() - assert handler.widget_classes["DeviceComboBox"] is not _TestPluginWidget - assert handler.widget_classes["NewPluginWidget"] is _TestPluginWidget + SharedWidgetPlugin = type("SharedWidget", (), {}) + SharedWidgetPlugin.__module__ = plugin_module.__name__ + setattr(plugin_module, "SharedWidget", SharedWidgetPlugin) + + NewPluginWidget = type("NewPluginWidget", (), {}) + NewPluginWidget.__module__ = plugin_module.__name__ + setattr(plugin_module, "NewPluginWidget", NewPluginWidget) + + monkeypatch.setitem(sys.modules, builtin_module.__name__, builtin_module) + monkeypatch.setitem(sys.modules, plugin_module.__name__, plugin_module) + + with ( + patch( + "bec_widgets.cli.rpc.rpc_widget_handler.get_all_plugin_widget_references", + return_value=[ + BECClassReference(name="SharedWidget", module=plugin_module.__name__), + BECClassReference(name="NewPluginWidget", module=plugin_module.__name__), + ], + ), + patch( + "bec_widgets.cli.rpc.rpc_widget_handler.get_custom_class_references", + return_value=[BECClassReference(name="SharedWidget", module=builtin_module.__name__)], + ), + ): + handler = RPCWidgetHandler() + assert handler.widget_classes["SharedWidget"].__module__ == builtin_module.__name__ + assert handler.widget_classes["NewPluginWidget"].__module__ == plugin_module.__name__