mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 19:21:50 +02:00
fix(plugins): fixes and tests for auto-gen plugins
This commit is contained in:
@ -47,13 +47,12 @@ class DesignerPluginGenerator:
|
||||
def __init__(self, widget: type):
|
||||
self._excluded = False
|
||||
self.widget = widget
|
||||
self.info = DesignerPluginInfo(widget)
|
||||
if widget.__name__ in EXCLUDED_PLUGINS:
|
||||
|
||||
self._excluded = True
|
||||
return
|
||||
|
||||
self.info = DesignerPluginInfo(widget)
|
||||
|
||||
self.templates = {}
|
||||
self.template_path = os.path.join(
|
||||
os.path.dirname(os.path.abspath(__file__)), "plugin_templates"
|
||||
@ -75,7 +74,7 @@ class DesignerPluginGenerator:
|
||||
|
||||
# Check if the widget class has parent as the first argument. This is a strict requirement of Qt!
|
||||
signature = list(inspect.signature(self.widget.__init__).parameters.values())
|
||||
if signature[1].name != "parent":
|
||||
if len(signature) == 1 or signature[1].name != "parent":
|
||||
raise ValueError(
|
||||
f"Widget class {self.widget.__name__} must have parent as the first argument."
|
||||
)
|
||||
@ -89,20 +88,22 @@ class DesignerPluginGenerator:
|
||||
# Check if the widget class calls the super constructor with parent argument
|
||||
init_source = inspect.getsource(self.widget.__init__)
|
||||
cls_init_found = (
|
||||
bool(init_source.find(f"{base_cls[0].__name__}.__init__(self, parent=parent"))
|
||||
or bool(init_source.find(f"{base_cls[0].__name__}.__init__(self, parent)"))
|
||||
or bool(init_source.find(f"{base_cls[0].__name__}.__init__(self, parent,"))
|
||||
bool(init_source.find(f"{base_cls[0].__name__}.__init__(self, parent=parent") > 0)
|
||||
or bool(init_source.find(f"{base_cls[0].__name__}.__init__(self, parent)") > 0)
|
||||
or bool(init_source.find(f"{base_cls[0].__name__}.__init__(self, parent,") > 0)
|
||||
)
|
||||
super_init_found = (
|
||||
bool(init_source.find(f"super({self.widget.__name__}, self).__init__(parent=parent"))
|
||||
or bool(init_source.find(f"super({self.widget.__name__}, self).__init__(parent,"))
|
||||
or bool(init_source.find(f"super({self.widget.__name__}, self).__init__(parent)"))
|
||||
bool(
|
||||
init_source.find(f"super({base_cls[0].__name__}, self).__init__(parent=parent") > 0
|
||||
)
|
||||
or bool(init_source.find(f"super({base_cls[0].__name__}, self).__init__(parent,") > 0)
|
||||
or bool(init_source.find(f"super({base_cls[0].__name__}, self).__init__(parent)") > 0)
|
||||
)
|
||||
if issubclass(self.widget.__bases__[0], QObject) and super_init_found == -1:
|
||||
if issubclass(self.widget.__bases__[0], QObject) and not super_init_found:
|
||||
super_init_found = (
|
||||
bool(init_source.find("super().__init__(parent=parent"))
|
||||
or bool(init_source.find("super().__init__(parent,"))
|
||||
or bool(init_source.find("super().__init__(parent)"))
|
||||
bool(init_source.find("super().__init__(parent=parent") > 0)
|
||||
or bool(init_source.find("super().__init__(parent,") > 0)
|
||||
or bool(init_source.find("super().__init__(parent)") > 0)
|
||||
)
|
||||
|
||||
if not cls_init_found and not super_init_found:
|
||||
@ -139,7 +140,7 @@ class DesignerPluginGenerator:
|
||||
self.templates[file.split(".")[0]] = f.read()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
# from bec_widgets.widgets.bec_queue.bec_queue import BECQueue
|
||||
from bec_widgets.widgets.dock import BECDockArea
|
||||
|
||||
|
155
tests/unit_tests/test_generate_plugin.py
Normal file
155
tests/unit_tests/test_generate_plugin.py
Normal file
@ -0,0 +1,155 @@
|
||||
import importlib
|
||||
import inspect
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
from bec_widgets.utils.generate_designer_plugin import DesignerPluginGenerator
|
||||
|
||||
|
||||
def load_plugin(dir_path, content, plugin_name="MyWidget"):
|
||||
plugin_path = dir_path.mkdir("plugin").join("plugin.py")
|
||||
plugin_path.write(content)
|
||||
sys.path.append(str(dir_path))
|
||||
plugin = importlib.import_module("plugin.plugin")
|
||||
importlib.reload(plugin)
|
||||
yield getattr(plugin, plugin_name)
|
||||
sys.path.pop()
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
""",
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent=parent)
|
||||
""",
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
""",
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
""",
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super(QWidget, self).__init__(parent)"""
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super(QWidget, self).__init__(parent=parent)
|
||||
""",
|
||||
]
|
||||
)
|
||||
def plugin_with_correct_parent(tmpdir, request):
|
||||
yield from load_plugin(tmpdir, request.param)
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self)
|
||||
""",
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__()
|
||||
""",
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
super(QWidget, self).__init__()
|
||||
""",
|
||||
]
|
||||
)
|
||||
def plugin_with_missing_parent(tmpdir, request):
|
||||
yield from load_plugin(tmpdir, request.param)
|
||||
|
||||
|
||||
def test_generate_plugin(plugin_with_correct_parent):
|
||||
generator = DesignerPluginGenerator(plugin_with_correct_parent)
|
||||
generator.run()
|
||||
assert os.path.exists(f"{generator.info.base_path}/register_my_widget.py")
|
||||
assert os.path.exists(f"{generator.info.base_path}/my_widget_plugin.py")
|
||||
assert os.path.exists(f"{generator.info.base_path}/my_widget.pyproject")
|
||||
|
||||
|
||||
def test_generate_plugin_with_missing_parent(plugin_with_missing_parent):
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
generator = DesignerPluginGenerator(plugin_with_missing_parent)
|
||||
generator.run()
|
||||
assert "Widget class MyWidget must call the super constructor with parent." in str(
|
||||
excinfo.value
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def plugin_with_excluded_widget(tmpdir):
|
||||
content = """
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class BECDock(QWidget):
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
"""
|
||||
yield from load_plugin(tmpdir, content, plugin_name="BECDock")
|
||||
|
||||
|
||||
def test_generate_plugin_with_excluded_widget(plugin_with_excluded_widget, capsys):
|
||||
generator = DesignerPluginGenerator(plugin_with_excluded_widget)
|
||||
generator.run()
|
||||
captured = capsys.readouterr()
|
||||
|
||||
assert "Plugin BECDock is excluded from generation." in captured.out
|
||||
assert not os.path.exists(f"{generator.info.base_path}/register_bec_dock.py")
|
||||
assert not os.path.exists(f"{generator.info.base_path}/bec_dock_plugin.py")
|
||||
assert not os.path.exists(f"{generator.info.base_path}/bec_dock.pyproject")
|
||||
|
||||
|
||||
@pytest.fixture(
|
||||
params=[
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self):
|
||||
QWidget.__init__(self)
|
||||
""",
|
||||
"""
|
||||
from qtpy.QtWidgets import QWidget
|
||||
class MyWidget(QWidget):
|
||||
def __init__(self, config, parent=None):
|
||||
super().__init__()
|
||||
""",
|
||||
]
|
||||
)
|
||||
def plugin_with_no_parent_as_first_arg(tmpdir, request):
|
||||
yield from load_plugin(tmpdir, request.param)
|
||||
|
||||
|
||||
def test_generate_plugin_raises_exception_when_first_argument_is_not_parent(
|
||||
plugin_with_no_parent_as_first_arg,
|
||||
):
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
generator = DesignerPluginGenerator(plugin_with_no_parent_as_first_arg)
|
||||
generator.run()
|
||||
assert "Widget class MyWidget must have parent as the first argument." in str(excinfo.value)
|
Reference in New Issue
Block a user