bec-widgets 0.99.8__py3-none-any.whl → 0.99.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- CHANGELOG.md +6 -6
- PKG-INFO +1 -1
- {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/METADATA +1 -1
- {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/RECORD +8 -155
- pyproject.toml +6 -1
- docs/Makefile +0 -20
- docs/_static/custom.css +0 -170
- docs/_templates/custom-class-template.rst +0 -34
- docs/_templates/custom-module-template.rst +0 -66
- docs/api_reference/api_reference.md +0 -12
- docs/assets/apps_48dp.svg +0 -1
- docs/assets/display_settings_48dp.svg +0 -1
- docs/assets/index_api.svg +0 -97
- docs/assets/index_contribute.svg +0 -76
- docs/assets/index_getting_started.svg +0 -66
- docs/assets/index_user_guide.svg +0 -67
- docs/assets/rocket_launch_48dp.svg +0 -1
- docs/assets/widget_screenshots/buttons.png +0 -0
- docs/assets/widget_screenshots/device_box.png +0 -0
- docs/assets/widget_screenshots/device_browser.png +0 -0
- docs/assets/widget_screenshots/device_inputs.png +0 -0
- docs/assets/widget_screenshots/dock_area.png +0 -0
- docs/assets/widget_screenshots/figure.png +0 -0
- docs/assets/widget_screenshots/image_widget.png +0 -0
- docs/assets/widget_screenshots/motor_map_widget.png +0 -0
- docs/assets/widget_screenshots/position_indicator.png +0 -0
- docs/assets/widget_screenshots/queue.png +0 -0
- docs/assets/widget_screenshots/ring_progress_bar.png +0 -0
- docs/assets/widget_screenshots/scan_controller.png +0 -0
- docs/assets/widget_screenshots/spinner.gif +0 -0
- docs/assets/widget_screenshots/status_box.png +0 -0
- docs/assets/widget_screenshots/text_box.png +0 -0
- docs/assets/widget_screenshots/toggle.png +0 -0
- docs/assets/widget_screenshots/waveform_widget.png +0 -0
- docs/assets/widget_screenshots/website.png +0 -0
- docs/conf.py +0 -82
- docs/developer/developer.md +0 -52
- docs/developer/introduction/concepts.md +0 -14
- docs/developer/introduction/contributing.md +0 -28
- docs/developer/introduction/introduction.md +0 -16
- docs/developer/introduction/useful_links.md +0 -23
- docs/developer/widget_development/bec_dispatcher.md +0 -143
- docs/developer/widget_development/widget_base_class.md +0 -171
- docs/developer/widget_development/widget_development.md +0 -14
- docs/index.md +0 -74
- docs/introduction/introduction.md +0 -18
- docs/make.bat +0 -35
- docs/requirements.txt +0 -12
- docs/user/api_reference/api_reference.md +0 -11
- docs/user/applications/applications.md +0 -10
- docs/user/customisation.md +0 -123
- docs/user/getting_started/BECDockArea.png +0 -0
- docs/user/getting_started/auto_updates.md +0 -82
- docs/user/getting_started/getting_started.md +0 -15
- docs/user/getting_started/gui_complex_gui.gif +0 -0
- docs/user/getting_started/installation.md +0 -33
- docs/user/getting_started/quick_start.md +0 -110
- docs/user/getting_started/video_tutorials.md +0 -17
- docs/user/user.md +0 -71
- docs/user/widgets/bec_figure/BECFigure.png +0 -0
- docs/user/widgets/bec_figure/bec_figure.md +0 -105
- docs/user/widgets/bec_status_box/bec_status_box.gif +0 -0
- docs/user/widgets/bec_status_box/bec_status_box.md +0 -38
- docs/user/widgets/buttons/buttons.md +0 -90
- docs/user/widgets/buttons/dark_mode_disabled.png +0 -0
- docs/user/widgets/buttons/dark_mode_enabled.png +0 -0
- docs/user/widgets/device_browser/device_browser.md +0 -36
- docs/user/widgets/device_browser/device_browser.png +0 -0
- docs/user/widgets/device_input/device_input.md +0 -100
- docs/user/widgets/dock_area/BECDockArea.png +0 -0
- docs/user/widgets/dock_area/bec_dock_area.md +0 -109
- docs/user/widgets/image/image_plot.gif +0 -0
- docs/user/widgets/image/image_widget.md +0 -84
- docs/user/widgets/motor_map/motor.gif +0 -0
- docs/user/widgets/motor_map/motor_map.md +0 -80
- docs/user/widgets/position_indicator/position_indicator.md +0 -69
- docs/user/widgets/positioner_box/positioner_box.md +0 -63
- docs/user/widgets/progress_bar/progress_bar.gif +0 -0
- docs/user/widgets/progress_bar/ring_progress_bar.md +0 -103
- docs/user/widgets/queue/queue.md +0 -41
- docs/user/widgets/scan_control/hide_scan_control.png +0 -0
- docs/user/widgets/scan_control/scan_control.gif +0 -0
- docs/user/widgets/scan_control/scan_control.md +0 -54
- docs/user/widgets/spinner/spinner.md +0 -68
- docs/user/widgets/text_box/text_box.md +0 -74
- docs/user/widgets/toggle/toggle.md +0 -66
- docs/user/widgets/waveform/bec_figure_dap.gif +0 -0
- docs/user/widgets/waveform/scatter_2D.gif +0 -0
- docs/user/widgets/waveform/w1D.gif +0 -0
- docs/user/widgets/waveform/waveform_widget.md +0 -132
- docs/user/widgets/website/website.md +0 -69
- docs/user/widgets/widgets.md +0 -220
- tests/__init__.py +0 -0
- tests/end-2-end/__init__.py +0 -0
- tests/end-2-end/conftest.py +0 -53
- tests/end-2-end/test_bec_dock_rpc_e2e.py +0 -298
- tests/end-2-end/test_bec_figure_rpc_e2e.py +0 -212
- tests/end-2-end/test_rpc_register_e2e.py +0 -40
- tests/end-2-end/test_scan_control_e2e.py +0 -71
- tests/references/SpinnerWidget/SpinnerWidget_darwin.png +0 -0
- tests/references/SpinnerWidget/SpinnerWidget_linux.png +0 -0
- tests/references/SpinnerWidget/SpinnerWidget_started_darwin.png +0 -0
- tests/references/SpinnerWidget/SpinnerWidget_started_linux.png +0 -0
- tests/unit_tests/__init__.py +0 -0
- tests/unit_tests/client_mocks.py +0 -189
- tests/unit_tests/conftest.py +0 -64
- tests/unit_tests/test_bec_connector.py +0 -80
- tests/unit_tests/test_bec_dispatcher.py +0 -119
- tests/unit_tests/test_bec_dock.py +0 -155
- tests/unit_tests/test_bec_figure.py +0 -270
- tests/unit_tests/test_bec_image.py +0 -63
- tests/unit_tests/test_bec_image_widget.py +0 -217
- tests/unit_tests/test_bec_motor_map.py +0 -282
- tests/unit_tests/test_bec_queue.py +0 -111
- tests/unit_tests/test_bec_status_box.py +0 -123
- tests/unit_tests/test_client_utils.py +0 -76
- tests/unit_tests/test_color_map_selector.py +0 -42
- tests/unit_tests/test_color_validation.py +0 -75
- tests/unit_tests/test_configs/config_device.yaml +0 -33
- tests/unit_tests/test_configs/config_device_no_entry.yaml +0 -27
- tests/unit_tests/test_configs/config_scan.yaml +0 -82
- tests/unit_tests/test_crosshair.py +0 -143
- tests/unit_tests/test_dark_mode_button.py +0 -70
- tests/unit_tests/test_device_browser.py +0 -83
- tests/unit_tests/test_device_input_base.py +0 -76
- tests/unit_tests/test_device_input_widgets.py +0 -178
- tests/unit_tests/test_error_utils.py +0 -63
- tests/unit_tests/test_generate_cli_client.py +0 -123
- tests/unit_tests/test_generate_plugin.py +0 -155
- tests/unit_tests/test_motor_map_widget.py +0 -194
- tests/unit_tests/test_msgs/__init__.py +0 -0
- tests/unit_tests/test_msgs/available_scans_message.py +0 -989
- tests/unit_tests/test_plot_base.py +0 -95
- tests/unit_tests/test_plugin_utils.py +0 -13
- tests/unit_tests/test_positioner_box.py +0 -130
- tests/unit_tests/test_ring_progress_bar.py +0 -337
- tests/unit_tests/test_rpc_register.py +0 -52
- tests/unit_tests/test_rpc_server.py +0 -42
- tests/unit_tests/test_rpc_widget_handler.py +0 -7
- tests/unit_tests/test_scan_control.py +0 -324
- tests/unit_tests/test_scan_control_group_box.py +0 -160
- tests/unit_tests/test_setting_dialog.py +0 -96
- tests/unit_tests/test_spinner.py +0 -31
- tests/unit_tests/test_stop_button.py +0 -27
- tests/unit_tests/test_text_box_widget.py +0 -54
- tests/unit_tests/test_toggle.py +0 -38
- tests/unit_tests/test_vscode_widget.py +0 -75
- tests/unit_tests/test_waveform1d.py +0 -712
- tests/unit_tests/test_waveform_widget.py +0 -462
- tests/unit_tests/test_website_widget.py +0 -25
- tests/unit_tests/test_widget_io.py +0 -90
- tests/unit_tests/test_yaml_dialog.py +0 -163
- {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/WHEEL +0 -0
- {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/licenses/LICENSE +0 -0
tests/unit_tests/client_mocks.py
DELETED
@@ -1,189 +0,0 @@
|
|
1
|
-
# pylint: disable = no-name-in-module,missing-class-docstring, missing-module-docstring
|
2
|
-
from unittest.mock import MagicMock, patch
|
3
|
-
|
4
|
-
import fakeredis
|
5
|
-
import pytest
|
6
|
-
from bec_lib.client import BECClient
|
7
|
-
from bec_lib.device import Positioner, ReadoutPriority
|
8
|
-
from bec_lib.devicemanager import DeviceContainer
|
9
|
-
from bec_lib.redis_connector import RedisConnector
|
10
|
-
|
11
|
-
|
12
|
-
class FakeDevice:
|
13
|
-
"""Fake minimal positioner class for testing."""
|
14
|
-
|
15
|
-
def __init__(self, name, enabled=True, readout_priority=ReadoutPriority.MONITORED):
|
16
|
-
self.name = name
|
17
|
-
self.enabled = enabled
|
18
|
-
self.signals = {self.name: {"value": 1.0}}
|
19
|
-
self.description = {self.name: {"source": self.name, "dtype": "number", "shape": []}}
|
20
|
-
self.readout_priority = readout_priority
|
21
|
-
self._config = {
|
22
|
-
"readoutPriority": "baseline",
|
23
|
-
"deviceClass": "ophyd_devices.SimPositioner",
|
24
|
-
"deviceConfig": {
|
25
|
-
"delay": 1,
|
26
|
-
"limits": [-50, 50],
|
27
|
-
"tolerance": 0.01,
|
28
|
-
"update_frequency": 400,
|
29
|
-
},
|
30
|
-
"deviceTags": ["user motors"],
|
31
|
-
"enabled": enabled,
|
32
|
-
"readOnly": False,
|
33
|
-
"name": self.name,
|
34
|
-
}
|
35
|
-
|
36
|
-
def __contains__(self, item):
|
37
|
-
return item == self.name
|
38
|
-
|
39
|
-
@property
|
40
|
-
def _hints(self):
|
41
|
-
return [self.name]
|
42
|
-
|
43
|
-
def set_value(self, fake_value: float = 1.0) -> None:
|
44
|
-
"""
|
45
|
-
Setup fake value for device readout
|
46
|
-
Args:
|
47
|
-
fake_value(float): Desired fake value
|
48
|
-
"""
|
49
|
-
self.signals[self.name]["value"] = fake_value
|
50
|
-
|
51
|
-
def describe(self) -> dict:
|
52
|
-
"""
|
53
|
-
Get the description of the device
|
54
|
-
Returns:
|
55
|
-
dict: Description of the device
|
56
|
-
"""
|
57
|
-
return self.description
|
58
|
-
|
59
|
-
|
60
|
-
class FakePositioner(FakeDevice):
|
61
|
-
def __init__(
|
62
|
-
self,
|
63
|
-
name,
|
64
|
-
enabled=True,
|
65
|
-
limits=None,
|
66
|
-
read_value=1.0,
|
67
|
-
readout_priority=ReadoutPriority.MONITORED,
|
68
|
-
):
|
69
|
-
super().__init__(name, enabled, readout_priority)
|
70
|
-
self.limits = limits if limits is not None else [0, 0]
|
71
|
-
self.read_value = read_value
|
72
|
-
self.name = name
|
73
|
-
|
74
|
-
@property
|
75
|
-
def precision(self):
|
76
|
-
return 3
|
77
|
-
|
78
|
-
def set_read_value(self, value):
|
79
|
-
self.read_value = value
|
80
|
-
|
81
|
-
def read(self):
|
82
|
-
return {
|
83
|
-
self.name: {"value": self.read_value},
|
84
|
-
f"{self.name}_setpoint": {"value": self.read_value},
|
85
|
-
f"{self.name}_motor_is_moving": {"value": 0},
|
86
|
-
}
|
87
|
-
|
88
|
-
def set_limits(self, limits):
|
89
|
-
self.limits = limits
|
90
|
-
|
91
|
-
def move(self, value, relative=False):
|
92
|
-
"""Simulates moving the device to a new position."""
|
93
|
-
if relative:
|
94
|
-
self.read_value += value
|
95
|
-
else:
|
96
|
-
self.read_value = value
|
97
|
-
# Respect the limits
|
98
|
-
self.read_value = max(min(self.read_value, self.limits[1]), self.limits[0])
|
99
|
-
|
100
|
-
@property
|
101
|
-
def readback(self):
|
102
|
-
return MagicMock(get=MagicMock(return_value=self.read_value))
|
103
|
-
|
104
|
-
|
105
|
-
class Positioner(FakePositioner):
|
106
|
-
"""just placeholder for testing embedded isinstance check in DeviceCombobox"""
|
107
|
-
|
108
|
-
def __init__(self, name="test", limits=None, read_value=1.0):
|
109
|
-
super().__init__(name, limits, read_value)
|
110
|
-
|
111
|
-
|
112
|
-
class Device(FakeDevice):
|
113
|
-
"""just placeholder for testing embedded isinstance check in DeviceCombobox"""
|
114
|
-
|
115
|
-
def __init__(self, name, enabled=True):
|
116
|
-
super().__init__(name, enabled)
|
117
|
-
|
118
|
-
|
119
|
-
class DMMock:
|
120
|
-
def __init__(self):
|
121
|
-
self.devices = DeviceContainer()
|
122
|
-
|
123
|
-
def add_devives(self, devices: list):
|
124
|
-
for device in devices:
|
125
|
-
self.devices[device.name] = device
|
126
|
-
|
127
|
-
|
128
|
-
DEVICES = [
|
129
|
-
FakePositioner("samx", limits=[-10, 10], read_value=2.0),
|
130
|
-
FakePositioner("samy", limits=[-5, 5], read_value=3.0),
|
131
|
-
FakePositioner("samz", limits=[-8, 8], read_value=4.0),
|
132
|
-
FakePositioner("aptrx", limits=None, read_value=4.0),
|
133
|
-
FakePositioner("aptry", limits=None, read_value=5.0),
|
134
|
-
FakeDevice("gauss_bpm"),
|
135
|
-
FakeDevice("gauss_adc1"),
|
136
|
-
FakeDevice("gauss_adc2"),
|
137
|
-
FakeDevice("gauss_adc3"),
|
138
|
-
FakeDevice("bpm4i"),
|
139
|
-
FakeDevice("bpm3a"),
|
140
|
-
FakeDevice("bpm3i"),
|
141
|
-
FakeDevice("eiger"),
|
142
|
-
FakeDevice("async_device", readout_priority=ReadoutPriority.ASYNC),
|
143
|
-
Positioner("test", limits=[-10, 10], read_value=2.0),
|
144
|
-
Device("test_device"),
|
145
|
-
]
|
146
|
-
|
147
|
-
|
148
|
-
def fake_redis_server(host, port):
|
149
|
-
redis = fakeredis.FakeRedis()
|
150
|
-
return redis
|
151
|
-
|
152
|
-
|
153
|
-
@pytest.fixture(scope="function")
|
154
|
-
def mocked_client(bec_dispatcher):
|
155
|
-
connector = RedisConnector("localhost:1", redis_cls=fake_redis_server)
|
156
|
-
# Create a MagicMock object
|
157
|
-
client = MagicMock() # TODO change to real BECClient
|
158
|
-
|
159
|
-
# Shutdown the original client
|
160
|
-
bec_dispatcher.client.shutdown()
|
161
|
-
# Mock the connector attribute
|
162
|
-
bec_dispatcher.client = client
|
163
|
-
|
164
|
-
# Mock the device_manager.devices attribute
|
165
|
-
client.connector = connector
|
166
|
-
client.device_manager = DMMock()
|
167
|
-
client.device_manager.add_devives(DEVICES)
|
168
|
-
|
169
|
-
def mock_mv(*args, relative=False):
|
170
|
-
# Extracting motor and value pairs
|
171
|
-
for i in range(0, len(args), 2):
|
172
|
-
motor = args[i]
|
173
|
-
value = args[i + 1]
|
174
|
-
motor.move(value, relative=relative)
|
175
|
-
return MagicMock(wait=MagicMock())
|
176
|
-
|
177
|
-
client.scans = MagicMock(mv=mock_mv)
|
178
|
-
|
179
|
-
# Ensure isinstance check for Positioner passes
|
180
|
-
original_isinstance = isinstance
|
181
|
-
|
182
|
-
def isinstance_mock(obj, class_info):
|
183
|
-
if class_info == Positioner and isinstance(obj, FakePositioner):
|
184
|
-
return True
|
185
|
-
return original_isinstance(obj, class_info)
|
186
|
-
|
187
|
-
with patch("builtins.isinstance", new=isinstance_mock):
|
188
|
-
yield client
|
189
|
-
connector.shutdown() # TODO change to real BECClient
|
tests/unit_tests/conftest.py
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
import pytest
|
2
|
-
from pytestqt.exceptions import TimeoutError as QtBotTimeoutError
|
3
|
-
from qtpy.QtWidgets import QApplication
|
4
|
-
|
5
|
-
from bec_widgets.cli.rpc_register import RPCRegister
|
6
|
-
from bec_widgets.qt_utils import error_popups
|
7
|
-
from bec_widgets.utils import bec_dispatcher as bec_dispatcher_module
|
8
|
-
|
9
|
-
|
10
|
-
@pytest.fixture(autouse=True)
|
11
|
-
def qapplication(qtbot): # pylint: disable=unused-argument
|
12
|
-
yield
|
13
|
-
|
14
|
-
qapp = QApplication.instance()
|
15
|
-
# qapp.quit()
|
16
|
-
qapp.processEvents()
|
17
|
-
try:
|
18
|
-
qtbot.waitUntil(lambda: qapp.topLevelWidgets() == [])
|
19
|
-
except QtBotTimeoutError as exc:
|
20
|
-
raise TimeoutError(f"Failed to close all widgets: {qapp.topLevelWidgets()}") from exc
|
21
|
-
|
22
|
-
|
23
|
-
@pytest.fixture(autouse=True)
|
24
|
-
def rpc_register():
|
25
|
-
yield RPCRegister()
|
26
|
-
RPCRegister.reset_singleton()
|
27
|
-
|
28
|
-
|
29
|
-
@pytest.fixture(autouse=True)
|
30
|
-
def bec_dispatcher(threads_check): # pylint: disable=unused-argument
|
31
|
-
bec_dispatcher = bec_dispatcher_module.BECDispatcher()
|
32
|
-
yield bec_dispatcher
|
33
|
-
bec_dispatcher.disconnect_all()
|
34
|
-
# clean BEC client
|
35
|
-
bec_dispatcher.client.shutdown()
|
36
|
-
# reinitialize singleton for next test
|
37
|
-
bec_dispatcher_module.BECDispatcher.reset_singleton()
|
38
|
-
|
39
|
-
|
40
|
-
@pytest.fixture(autouse=True)
|
41
|
-
def clean_singleton():
|
42
|
-
error_popups._popup_utility_instance = None
|
43
|
-
|
44
|
-
|
45
|
-
def create_widget(qtbot, widget, *args, **kwargs):
|
46
|
-
"""
|
47
|
-
Create a widget and add it to the qtbot for testing. This is a helper function that
|
48
|
-
should be used in all tests that require a widget to be created.
|
49
|
-
DO NOT CREATE WIDGETS DIRECTLY IN A FIXTURE!
|
50
|
-
|
51
|
-
Args:
|
52
|
-
qtbot (fixture): pytest-qt fixture
|
53
|
-
widget (QWidget): widget class to be created
|
54
|
-
*args: positional arguments for the widget
|
55
|
-
**kwargs: keyword arguments for the widget
|
56
|
-
|
57
|
-
Returns:
|
58
|
-
QWidget: the created widget
|
59
|
-
|
60
|
-
"""
|
61
|
-
widget = widget(*args, **kwargs)
|
62
|
-
qtbot.addWidget(widget)
|
63
|
-
qtbot.waitExposed(widget)
|
64
|
-
return widget
|
@@ -1,80 +0,0 @@
|
|
1
|
-
# pylint: disable = no-name-in-module,missing-class-docstring, missing-module-docstring
|
2
|
-
import time
|
3
|
-
|
4
|
-
import pytest
|
5
|
-
from qtpy.QtWidgets import QApplication
|
6
|
-
|
7
|
-
from bec_widgets.qt_utils.error_popups import SafeSlot as Slot
|
8
|
-
from bec_widgets.utils import BECConnector, ConnectionConfig
|
9
|
-
|
10
|
-
from .client_mocks import mocked_client
|
11
|
-
|
12
|
-
|
13
|
-
@pytest.fixture
|
14
|
-
def bec_connector(mocked_client):
|
15
|
-
connector = BECConnector(client=mocked_client)
|
16
|
-
return connector
|
17
|
-
|
18
|
-
|
19
|
-
def test_bec_connector_init(bec_connector):
|
20
|
-
assert bec_connector is not None
|
21
|
-
assert bec_connector.client is not None
|
22
|
-
assert isinstance(bec_connector, BECConnector)
|
23
|
-
assert bec_connector.config.widget_class == "BECConnector"
|
24
|
-
|
25
|
-
|
26
|
-
def test_bec_connector_init_with_gui_id(mocked_client):
|
27
|
-
bc = BECConnector(client=mocked_client, gui_id="test_gui_id")
|
28
|
-
assert bc.config.gui_id == "test_gui_id"
|
29
|
-
assert bc.gui_id == "test_gui_id"
|
30
|
-
|
31
|
-
|
32
|
-
def test_bec_connector_set_gui_id(bec_connector):
|
33
|
-
bec_connector.set_gui_id("test_gui_id")
|
34
|
-
assert bec_connector.config.gui_id == "test_gui_id"
|
35
|
-
|
36
|
-
|
37
|
-
def test_bec_connector_change_config(bec_connector):
|
38
|
-
bec_connector.on_config_update({"gui_id": "test_gui_id"})
|
39
|
-
assert bec_connector.config.gui_id == "test_gui_id"
|
40
|
-
|
41
|
-
|
42
|
-
def test_bec_connector_get_obj_by_id(bec_connector):
|
43
|
-
bec_connector.set_gui_id("test_gui_id")
|
44
|
-
assert bec_connector.get_obj_by_id("test_gui_id") == bec_connector
|
45
|
-
assert bec_connector.get_obj_by_id("test_gui_id_2") is None
|
46
|
-
|
47
|
-
|
48
|
-
def test_bec_connector_update_client(bec_connector, mocked_client):
|
49
|
-
client_new = mocked_client
|
50
|
-
bec_connector.update_client(client_new)
|
51
|
-
assert bec_connector.client == client_new
|
52
|
-
assert bec_connector.dev is not None
|
53
|
-
assert bec_connector.scans is not None
|
54
|
-
assert bec_connector.queue is not None
|
55
|
-
assert bec_connector.scan_storage is not None
|
56
|
-
assert bec_connector.dap is not None
|
57
|
-
|
58
|
-
|
59
|
-
def test_bec_connector_get_config(bec_connector):
|
60
|
-
assert bec_connector.get_config(dict_output=False) == bec_connector.config
|
61
|
-
assert bec_connector.get_config() == bec_connector.config.model_dump()
|
62
|
-
|
63
|
-
|
64
|
-
def test_bec_connector_submit_task(bec_connector):
|
65
|
-
def test_func():
|
66
|
-
time.sleep(2)
|
67
|
-
print("done")
|
68
|
-
|
69
|
-
completed = False
|
70
|
-
|
71
|
-
@Slot()
|
72
|
-
def complete_func():
|
73
|
-
nonlocal completed
|
74
|
-
completed = True
|
75
|
-
|
76
|
-
bec_connector.submit_task(test_func, on_complete=complete_func)
|
77
|
-
assert not completed
|
78
|
-
while not completed:
|
79
|
-
QApplication.processEvents()
|
80
|
-
time.sleep(0.1)
|
@@ -1,119 +0,0 @@
|
|
1
|
-
# pylint: disable = no-name-in-module,missing-class-docstring, missing-module-docstring
|
2
|
-
import threading
|
3
|
-
import time
|
4
|
-
from unittest import mock
|
5
|
-
|
6
|
-
import pytest
|
7
|
-
import redis
|
8
|
-
from bec_lib.connector import MessageObject
|
9
|
-
from bec_lib.messages import ScanMessage
|
10
|
-
from bec_lib.redis_connector import RedisConnector
|
11
|
-
from bec_lib.serialization import MsgpackSerialization
|
12
|
-
|
13
|
-
from bec_widgets.utils.bec_dispatcher import QtRedisConnector
|
14
|
-
|
15
|
-
|
16
|
-
@pytest.fixture
|
17
|
-
def bec_dispatcher_w_connector(bec_dispatcher, topics_msg_list, send_msg_event):
|
18
|
-
def pubsub_msg_generator():
|
19
|
-
send_msg_event.wait()
|
20
|
-
for topic, msg in topics_msg_list:
|
21
|
-
yield {"channel": topic.encode(), "pattern": None, "data": msg}
|
22
|
-
while True:
|
23
|
-
time.sleep(0.2)
|
24
|
-
yield StopIteration
|
25
|
-
|
26
|
-
with mock.patch("redis.Redis"):
|
27
|
-
pubsub = redis.Redis().pubsub()
|
28
|
-
messages = pubsub_msg_generator()
|
29
|
-
pubsub.get_message.side_effect = lambda timeout: next(messages)
|
30
|
-
connector = QtRedisConnector("localhost:1")
|
31
|
-
bec_dispatcher.client.connector = connector
|
32
|
-
yield bec_dispatcher
|
33
|
-
|
34
|
-
|
35
|
-
dummy_msg = MsgpackSerialization.dumps(ScanMessage(point_id=0, scan_id="0", data={}))
|
36
|
-
|
37
|
-
|
38
|
-
@pytest.fixture
|
39
|
-
def send_msg_event():
|
40
|
-
return threading.Event()
|
41
|
-
|
42
|
-
|
43
|
-
@pytest.mark.parametrize(
|
44
|
-
"topics_msg_list", [(("topic1", dummy_msg), ("topic2", dummy_msg), ("topic3", dummy_msg))]
|
45
|
-
)
|
46
|
-
def test_dispatcher_disconnect_all(bec_dispatcher_w_connector, qtbot, send_msg_event):
|
47
|
-
bec_dispatcher = bec_dispatcher_w_connector
|
48
|
-
cb1 = mock.Mock(spec=[])
|
49
|
-
cb2 = mock.Mock(spec=[])
|
50
|
-
|
51
|
-
bec_dispatcher.connect_slot(cb1, "topic1")
|
52
|
-
bec_dispatcher.connect_slot(cb1, "topic2")
|
53
|
-
bec_dispatcher.connect_slot(cb2, "topic2")
|
54
|
-
bec_dispatcher.connect_slot(cb2, "topic3")
|
55
|
-
assert len(bec_dispatcher.client.connector._topics_cb) == 3
|
56
|
-
send_msg_event.set()
|
57
|
-
qtbot.wait(10)
|
58
|
-
assert cb1.call_count == 2
|
59
|
-
assert cb2.call_count == 2
|
60
|
-
|
61
|
-
bec_dispatcher.disconnect_all()
|
62
|
-
|
63
|
-
assert len(bec_dispatcher.client.connector._topics_cb) == 0
|
64
|
-
|
65
|
-
|
66
|
-
@pytest.mark.parametrize("topics_msg_list", [(("topic1", dummy_msg), ("topic2", dummy_msg))])
|
67
|
-
def test_dispatcher_disconnect_one(bec_dispatcher_w_connector, qtbot, send_msg_event):
|
68
|
-
# test for BEC issue #276
|
69
|
-
bec_dispatcher = bec_dispatcher_w_connector
|
70
|
-
cb1 = mock.Mock(spec=[])
|
71
|
-
cb2 = mock.Mock(spec=[])
|
72
|
-
|
73
|
-
bec_dispatcher.connect_slot(cb1, "topic1")
|
74
|
-
bec_dispatcher.connect_slot(cb2, "topic2")
|
75
|
-
assert len(bec_dispatcher.client.connector._topics_cb) == 2
|
76
|
-
bec_dispatcher.disconnect_slot(cb1, "topic1")
|
77
|
-
assert len(bec_dispatcher.client.connector._topics_cb) == 1
|
78
|
-
|
79
|
-
send_msg_event.set()
|
80
|
-
qtbot.wait(10)
|
81
|
-
assert cb1.call_count == 0
|
82
|
-
cb2.assert_called_once()
|
83
|
-
|
84
|
-
|
85
|
-
@pytest.mark.parametrize("topics_msg_list", [(("topic1", dummy_msg),)])
|
86
|
-
def test_dispatcher_2_cb_same_topic(bec_dispatcher_w_connector, qtbot, send_msg_event):
|
87
|
-
# test for BEC issue #276
|
88
|
-
bec_dispatcher = bec_dispatcher_w_connector
|
89
|
-
cb1 = mock.Mock(spec=[])
|
90
|
-
cb2 = mock.Mock(spec=[])
|
91
|
-
|
92
|
-
bec_dispatcher.connect_slot(cb1, "topic1")
|
93
|
-
bec_dispatcher.connect_slot(cb2, "topic1")
|
94
|
-
assert len(bec_dispatcher.client.connector._topics_cb) == 1
|
95
|
-
assert len(bec_dispatcher._slots) == 2
|
96
|
-
bec_dispatcher.disconnect_slot(cb1, "topic1")
|
97
|
-
assert len(bec_dispatcher._slots) == 1
|
98
|
-
|
99
|
-
send_msg_event.set()
|
100
|
-
qtbot.wait(10)
|
101
|
-
assert cb1.call_count == 0
|
102
|
-
cb2.assert_called_once()
|
103
|
-
|
104
|
-
|
105
|
-
@pytest.mark.parametrize("topics_msg_list", [(("topic1", dummy_msg), ("topic2", dummy_msg))])
|
106
|
-
def test_dispatcher_2_topic_same_cb(bec_dispatcher_w_connector, qtbot, send_msg_event):
|
107
|
-
# test for BEC issue #276
|
108
|
-
bec_dispatcher = bec_dispatcher_w_connector
|
109
|
-
cb1 = mock.Mock(spec=[])
|
110
|
-
|
111
|
-
bec_dispatcher.connect_slot(cb1, "topic1")
|
112
|
-
bec_dispatcher.connect_slot(cb1, "topic2")
|
113
|
-
assert len(bec_dispatcher.client.connector._topics_cb) == 2
|
114
|
-
bec_dispatcher.disconnect_slot(cb1, "topic1")
|
115
|
-
assert len(bec_dispatcher.client.connector._topics_cb) == 1
|
116
|
-
|
117
|
-
send_msg_event.set()
|
118
|
-
qtbot.wait(10)
|
119
|
-
cb1.assert_called_once()
|
@@ -1,155 +0,0 @@
|
|
1
|
-
# pylint: disable=missing-function-docstring, missing-module-docstring, unused-import
|
2
|
-
from unittest.mock import MagicMock, patch
|
3
|
-
|
4
|
-
import pytest
|
5
|
-
|
6
|
-
from bec_widgets.widgets.dock import BECDock, BECDockArea
|
7
|
-
|
8
|
-
from .client_mocks import mocked_client
|
9
|
-
|
10
|
-
|
11
|
-
@pytest.fixture
|
12
|
-
def bec_dock_area(qtbot, mocked_client):
|
13
|
-
widget = BECDockArea(client=mocked_client)
|
14
|
-
qtbot.addWidget(widget)
|
15
|
-
qtbot.waitExposed(widget)
|
16
|
-
yield widget
|
17
|
-
|
18
|
-
|
19
|
-
def test_bec_dock_area_init(bec_dock_area):
|
20
|
-
assert bec_dock_area is not None
|
21
|
-
assert bec_dock_area.client is not None
|
22
|
-
assert isinstance(bec_dock_area, BECDockArea)
|
23
|
-
assert bec_dock_area.config.widget_class == "BECDockArea"
|
24
|
-
|
25
|
-
|
26
|
-
def test_bec_dock_area_add_remove_dock(bec_dock_area, qtbot):
|
27
|
-
initial_count = len(bec_dock_area.dock_area.docks)
|
28
|
-
|
29
|
-
# Adding 3 docks
|
30
|
-
d0 = bec_dock_area.add_dock()
|
31
|
-
d1 = bec_dock_area.add_dock()
|
32
|
-
d2 = bec_dock_area.add_dock()
|
33
|
-
|
34
|
-
# Check if the docks were added
|
35
|
-
assert len(bec_dock_area.dock_area.docks) == initial_count + 3
|
36
|
-
assert d0.name() in dict(bec_dock_area.dock_area.docks)
|
37
|
-
assert d1.name() in dict(bec_dock_area.dock_area.docks)
|
38
|
-
assert d2.name() in dict(bec_dock_area.dock_area.docks)
|
39
|
-
assert bec_dock_area.dock_area.docks[d0.name()].config.widget_class == "BECDock"
|
40
|
-
assert bec_dock_area.dock_area.docks[d1.name()].config.widget_class == "BECDock"
|
41
|
-
assert bec_dock_area.dock_area.docks[d2.name()].config.widget_class == "BECDock"
|
42
|
-
|
43
|
-
# Check panels API for getting docks to CLI
|
44
|
-
assert bec_dock_area.panels == dict(bec_dock_area.dock_area.docks)
|
45
|
-
|
46
|
-
# Remove docks
|
47
|
-
d0_name = d0.name()
|
48
|
-
bec_dock_area.remove_dock(d0_name)
|
49
|
-
qtbot.wait(200)
|
50
|
-
d1.remove()
|
51
|
-
qtbot.wait(200)
|
52
|
-
|
53
|
-
assert len(bec_dock_area.dock_area.docks) == initial_count + 1
|
54
|
-
assert d0.name() not in dict(bec_dock_area.dock_area.docks)
|
55
|
-
assert d1.name() not in dict(bec_dock_area.dock_area.docks)
|
56
|
-
assert d2.name() in dict(bec_dock_area.dock_area.docks)
|
57
|
-
|
58
|
-
|
59
|
-
def test_add_remove_bec_figure_to_dock(bec_dock_area):
|
60
|
-
d0 = bec_dock_area.add_dock()
|
61
|
-
fig = d0.add_widget("BECFigure")
|
62
|
-
plt = fig.plot(x_name="samx", y_name="bpm4i")
|
63
|
-
im = fig.image("eiger")
|
64
|
-
mm = fig.motor_map("samx", "samy")
|
65
|
-
|
66
|
-
assert len(bec_dock_area.dock_area.docks) == 1
|
67
|
-
assert len(d0.widgets) == 1
|
68
|
-
assert len(d0.widget_list) == 1
|
69
|
-
assert len(fig.widgets) == 3
|
70
|
-
|
71
|
-
assert fig.config.widget_class == "BECFigure"
|
72
|
-
assert plt.config.widget_class == "BECWaveform"
|
73
|
-
assert im.config.widget_class == "BECImageShow"
|
74
|
-
assert mm.config.widget_class == "BECMotorMap"
|
75
|
-
|
76
|
-
|
77
|
-
def test_close_docks(bec_dock_area, qtbot):
|
78
|
-
d0 = bec_dock_area.add_dock(name="dock_0")
|
79
|
-
d1 = bec_dock_area.add_dock(name="dock_1")
|
80
|
-
d2 = bec_dock_area.add_dock(name="dock_2")
|
81
|
-
|
82
|
-
bec_dock_area.clear_all()
|
83
|
-
qtbot.wait(200)
|
84
|
-
assert len(bec_dock_area.dock_area.docks) == 0
|
85
|
-
|
86
|
-
|
87
|
-
def test_undock_and_dock_docks(bec_dock_area, qtbot):
|
88
|
-
d0 = bec_dock_area.add_dock(name="dock_0")
|
89
|
-
d1 = bec_dock_area.add_dock(name="dock_1")
|
90
|
-
d2 = bec_dock_area.add_dock(name="dock_4")
|
91
|
-
d3 = bec_dock_area.add_dock(name="dock_3")
|
92
|
-
|
93
|
-
d0.detach()
|
94
|
-
bec_dock_area.detach_dock("dock_1")
|
95
|
-
d2.detach()
|
96
|
-
|
97
|
-
assert len(bec_dock_area.dock_area.docks) == 4
|
98
|
-
assert len(bec_dock_area.dock_area.tempAreas) == 3
|
99
|
-
|
100
|
-
d0.attach()
|
101
|
-
assert len(bec_dock_area.dock_area.docks) == 4
|
102
|
-
assert len(bec_dock_area.dock_area.tempAreas) == 2
|
103
|
-
|
104
|
-
bec_dock_area.attach_all()
|
105
|
-
assert len(bec_dock_area.dock_area.docks) == 4
|
106
|
-
assert len(bec_dock_area.dock_area.tempAreas) == 0
|
107
|
-
|
108
|
-
|
109
|
-
###################################
|
110
|
-
# Toolbar Actions
|
111
|
-
###################################
|
112
|
-
def test_toolbar_add_plot_waveform(bec_dock_area):
|
113
|
-
bec_dock_area.toolbar.widgets["menu_plots"].widgets["waveform"].trigger()
|
114
|
-
assert "waveform_1" in bec_dock_area.panels
|
115
|
-
assert bec_dock_area.panels["waveform_1"].widgets[0].config.widget_class == "BECWaveformWidget"
|
116
|
-
|
117
|
-
|
118
|
-
def test_toolbar_add_plot_image(bec_dock_area):
|
119
|
-
bec_dock_area.toolbar.widgets["menu_plots"].widgets["image"].trigger()
|
120
|
-
assert "image_1" in bec_dock_area.panels
|
121
|
-
assert bec_dock_area.panels["image_1"].widgets[0].config.widget_class == "BECImageWidget"
|
122
|
-
|
123
|
-
|
124
|
-
def test_toolbar_add_plot_motor_map(bec_dock_area):
|
125
|
-
bec_dock_area.toolbar.widgets["menu_plots"].widgets["motor_map"].trigger()
|
126
|
-
assert "motor_map_1" in bec_dock_area.panels
|
127
|
-
assert bec_dock_area.panels["motor_map_1"].widgets[0].config.widget_class == "BECMotorMapWidget"
|
128
|
-
|
129
|
-
|
130
|
-
def test_toolbar_add_device_positioner_box(bec_dock_area):
|
131
|
-
bec_dock_area.toolbar.widgets["menu_devices"].widgets["positioner_box"].trigger()
|
132
|
-
assert "positioner_box_1" in bec_dock_area.panels
|
133
|
-
assert (
|
134
|
-
bec_dock_area.panels["positioner_box_1"].widgets[0].config.widget_class == "PositionerBox"
|
135
|
-
)
|
136
|
-
|
137
|
-
|
138
|
-
def test_toolbar_add_utils_queue(bec_dock_area):
|
139
|
-
bec_dock_area.toolbar.widgets["menu_utils"].widgets["queue"].trigger()
|
140
|
-
assert "queue_1" in bec_dock_area.panels
|
141
|
-
assert bec_dock_area.panels["queue_1"].widgets[0].config.widget_class == "BECQueue"
|
142
|
-
|
143
|
-
|
144
|
-
def test_toolbar_add_utils_status(bec_dock_area):
|
145
|
-
bec_dock_area.toolbar.widgets["menu_utils"].widgets["status"].trigger()
|
146
|
-
assert "status_1" in bec_dock_area.panels
|
147
|
-
assert bec_dock_area.panels["status_1"].widgets[0].config.widget_class == "BECStatusBox"
|
148
|
-
|
149
|
-
|
150
|
-
def test_toolbar_add_utils_progress_bar(bec_dock_area):
|
151
|
-
bec_dock_area.toolbar.widgets["menu_utils"].widgets["progress_bar"].trigger()
|
152
|
-
assert "progress_bar_1" in bec_dock_area.panels
|
153
|
-
assert (
|
154
|
-
bec_dock_area.panels["progress_bar_1"].widgets[0].config.widget_class == "RingProgressBar"
|
155
|
-
)
|