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.
Files changed (155) hide show
  1. CHANGELOG.md +6 -6
  2. PKG-INFO +1 -1
  3. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/METADATA +1 -1
  4. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/RECORD +8 -155
  5. pyproject.toml +6 -1
  6. docs/Makefile +0 -20
  7. docs/_static/custom.css +0 -170
  8. docs/_templates/custom-class-template.rst +0 -34
  9. docs/_templates/custom-module-template.rst +0 -66
  10. docs/api_reference/api_reference.md +0 -12
  11. docs/assets/apps_48dp.svg +0 -1
  12. docs/assets/display_settings_48dp.svg +0 -1
  13. docs/assets/index_api.svg +0 -97
  14. docs/assets/index_contribute.svg +0 -76
  15. docs/assets/index_getting_started.svg +0 -66
  16. docs/assets/index_user_guide.svg +0 -67
  17. docs/assets/rocket_launch_48dp.svg +0 -1
  18. docs/assets/widget_screenshots/buttons.png +0 -0
  19. docs/assets/widget_screenshots/device_box.png +0 -0
  20. docs/assets/widget_screenshots/device_browser.png +0 -0
  21. docs/assets/widget_screenshots/device_inputs.png +0 -0
  22. docs/assets/widget_screenshots/dock_area.png +0 -0
  23. docs/assets/widget_screenshots/figure.png +0 -0
  24. docs/assets/widget_screenshots/image_widget.png +0 -0
  25. docs/assets/widget_screenshots/motor_map_widget.png +0 -0
  26. docs/assets/widget_screenshots/position_indicator.png +0 -0
  27. docs/assets/widget_screenshots/queue.png +0 -0
  28. docs/assets/widget_screenshots/ring_progress_bar.png +0 -0
  29. docs/assets/widget_screenshots/scan_controller.png +0 -0
  30. docs/assets/widget_screenshots/spinner.gif +0 -0
  31. docs/assets/widget_screenshots/status_box.png +0 -0
  32. docs/assets/widget_screenshots/text_box.png +0 -0
  33. docs/assets/widget_screenshots/toggle.png +0 -0
  34. docs/assets/widget_screenshots/waveform_widget.png +0 -0
  35. docs/assets/widget_screenshots/website.png +0 -0
  36. docs/conf.py +0 -82
  37. docs/developer/developer.md +0 -52
  38. docs/developer/introduction/concepts.md +0 -14
  39. docs/developer/introduction/contributing.md +0 -28
  40. docs/developer/introduction/introduction.md +0 -16
  41. docs/developer/introduction/useful_links.md +0 -23
  42. docs/developer/widget_development/bec_dispatcher.md +0 -143
  43. docs/developer/widget_development/widget_base_class.md +0 -171
  44. docs/developer/widget_development/widget_development.md +0 -14
  45. docs/index.md +0 -74
  46. docs/introduction/introduction.md +0 -18
  47. docs/make.bat +0 -35
  48. docs/requirements.txt +0 -12
  49. docs/user/api_reference/api_reference.md +0 -11
  50. docs/user/applications/applications.md +0 -10
  51. docs/user/customisation.md +0 -123
  52. docs/user/getting_started/BECDockArea.png +0 -0
  53. docs/user/getting_started/auto_updates.md +0 -82
  54. docs/user/getting_started/getting_started.md +0 -15
  55. docs/user/getting_started/gui_complex_gui.gif +0 -0
  56. docs/user/getting_started/installation.md +0 -33
  57. docs/user/getting_started/quick_start.md +0 -110
  58. docs/user/getting_started/video_tutorials.md +0 -17
  59. docs/user/user.md +0 -71
  60. docs/user/widgets/bec_figure/BECFigure.png +0 -0
  61. docs/user/widgets/bec_figure/bec_figure.md +0 -105
  62. docs/user/widgets/bec_status_box/bec_status_box.gif +0 -0
  63. docs/user/widgets/bec_status_box/bec_status_box.md +0 -38
  64. docs/user/widgets/buttons/buttons.md +0 -90
  65. docs/user/widgets/buttons/dark_mode_disabled.png +0 -0
  66. docs/user/widgets/buttons/dark_mode_enabled.png +0 -0
  67. docs/user/widgets/device_browser/device_browser.md +0 -36
  68. docs/user/widgets/device_browser/device_browser.png +0 -0
  69. docs/user/widgets/device_input/device_input.md +0 -100
  70. docs/user/widgets/dock_area/BECDockArea.png +0 -0
  71. docs/user/widgets/dock_area/bec_dock_area.md +0 -109
  72. docs/user/widgets/image/image_plot.gif +0 -0
  73. docs/user/widgets/image/image_widget.md +0 -84
  74. docs/user/widgets/motor_map/motor.gif +0 -0
  75. docs/user/widgets/motor_map/motor_map.md +0 -80
  76. docs/user/widgets/position_indicator/position_indicator.md +0 -69
  77. docs/user/widgets/positioner_box/positioner_box.md +0 -63
  78. docs/user/widgets/progress_bar/progress_bar.gif +0 -0
  79. docs/user/widgets/progress_bar/ring_progress_bar.md +0 -103
  80. docs/user/widgets/queue/queue.md +0 -41
  81. docs/user/widgets/scan_control/hide_scan_control.png +0 -0
  82. docs/user/widgets/scan_control/scan_control.gif +0 -0
  83. docs/user/widgets/scan_control/scan_control.md +0 -54
  84. docs/user/widgets/spinner/spinner.md +0 -68
  85. docs/user/widgets/text_box/text_box.md +0 -74
  86. docs/user/widgets/toggle/toggle.md +0 -66
  87. docs/user/widgets/waveform/bec_figure_dap.gif +0 -0
  88. docs/user/widgets/waveform/scatter_2D.gif +0 -0
  89. docs/user/widgets/waveform/w1D.gif +0 -0
  90. docs/user/widgets/waveform/waveform_widget.md +0 -132
  91. docs/user/widgets/website/website.md +0 -69
  92. docs/user/widgets/widgets.md +0 -220
  93. tests/__init__.py +0 -0
  94. tests/end-2-end/__init__.py +0 -0
  95. tests/end-2-end/conftest.py +0 -53
  96. tests/end-2-end/test_bec_dock_rpc_e2e.py +0 -298
  97. tests/end-2-end/test_bec_figure_rpc_e2e.py +0 -212
  98. tests/end-2-end/test_rpc_register_e2e.py +0 -40
  99. tests/end-2-end/test_scan_control_e2e.py +0 -71
  100. tests/references/SpinnerWidget/SpinnerWidget_darwin.png +0 -0
  101. tests/references/SpinnerWidget/SpinnerWidget_linux.png +0 -0
  102. tests/references/SpinnerWidget/SpinnerWidget_started_darwin.png +0 -0
  103. tests/references/SpinnerWidget/SpinnerWidget_started_linux.png +0 -0
  104. tests/unit_tests/__init__.py +0 -0
  105. tests/unit_tests/client_mocks.py +0 -189
  106. tests/unit_tests/conftest.py +0 -64
  107. tests/unit_tests/test_bec_connector.py +0 -80
  108. tests/unit_tests/test_bec_dispatcher.py +0 -119
  109. tests/unit_tests/test_bec_dock.py +0 -155
  110. tests/unit_tests/test_bec_figure.py +0 -270
  111. tests/unit_tests/test_bec_image.py +0 -63
  112. tests/unit_tests/test_bec_image_widget.py +0 -217
  113. tests/unit_tests/test_bec_motor_map.py +0 -282
  114. tests/unit_tests/test_bec_queue.py +0 -111
  115. tests/unit_tests/test_bec_status_box.py +0 -123
  116. tests/unit_tests/test_client_utils.py +0 -76
  117. tests/unit_tests/test_color_map_selector.py +0 -42
  118. tests/unit_tests/test_color_validation.py +0 -75
  119. tests/unit_tests/test_configs/config_device.yaml +0 -33
  120. tests/unit_tests/test_configs/config_device_no_entry.yaml +0 -27
  121. tests/unit_tests/test_configs/config_scan.yaml +0 -82
  122. tests/unit_tests/test_crosshair.py +0 -143
  123. tests/unit_tests/test_dark_mode_button.py +0 -70
  124. tests/unit_tests/test_device_browser.py +0 -83
  125. tests/unit_tests/test_device_input_base.py +0 -76
  126. tests/unit_tests/test_device_input_widgets.py +0 -178
  127. tests/unit_tests/test_error_utils.py +0 -63
  128. tests/unit_tests/test_generate_cli_client.py +0 -123
  129. tests/unit_tests/test_generate_plugin.py +0 -155
  130. tests/unit_tests/test_motor_map_widget.py +0 -194
  131. tests/unit_tests/test_msgs/__init__.py +0 -0
  132. tests/unit_tests/test_msgs/available_scans_message.py +0 -989
  133. tests/unit_tests/test_plot_base.py +0 -95
  134. tests/unit_tests/test_plugin_utils.py +0 -13
  135. tests/unit_tests/test_positioner_box.py +0 -130
  136. tests/unit_tests/test_ring_progress_bar.py +0 -337
  137. tests/unit_tests/test_rpc_register.py +0 -52
  138. tests/unit_tests/test_rpc_server.py +0 -42
  139. tests/unit_tests/test_rpc_widget_handler.py +0 -7
  140. tests/unit_tests/test_scan_control.py +0 -324
  141. tests/unit_tests/test_scan_control_group_box.py +0 -160
  142. tests/unit_tests/test_setting_dialog.py +0 -96
  143. tests/unit_tests/test_spinner.py +0 -31
  144. tests/unit_tests/test_stop_button.py +0 -27
  145. tests/unit_tests/test_text_box_widget.py +0 -54
  146. tests/unit_tests/test_toggle.py +0 -38
  147. tests/unit_tests/test_vscode_widget.py +0 -75
  148. tests/unit_tests/test_waveform1d.py +0 -712
  149. tests/unit_tests/test_waveform_widget.py +0 -462
  150. tests/unit_tests/test_website_widget.py +0 -25
  151. tests/unit_tests/test_widget_io.py +0 -90
  152. tests/unit_tests/test_yaml_dialog.py +0 -163
  153. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/WHEEL +0 -0
  154. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/entry_points.txt +0 -0
  155. {bec_widgets-0.99.8.dist-info → bec_widgets-0.99.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,282 +0,0 @@
1
- import numpy as np
2
- import pytest
3
- from bec_lib.messages import DeviceMessage
4
-
5
- from bec_widgets.widgets.figure import BECFigure
6
- from bec_widgets.widgets.figure.plots.motor_map.motor_map import BECMotorMap, MotorMapConfig
7
- from bec_widgets.widgets.figure.plots.waveform.waveform_curve import SignalData
8
-
9
- from .client_mocks import mocked_client
10
- from .conftest import create_widget
11
-
12
-
13
- def test_motor_map_init(qtbot, mocked_client):
14
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
15
- default_config = MotorMapConfig(widget_class="BECMotorMap")
16
-
17
- mm = bec_figure.motor_map(config=default_config.model_dump())
18
- default_config.gui_id = mm.gui_id
19
-
20
- assert mm.config == default_config
21
-
22
-
23
- def test_motor_map_change_motors(qtbot, mocked_client):
24
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
25
- mm = bec_figure.motor_map("samx", "samy")
26
-
27
- assert mm.motor_x == "samx"
28
- assert mm.motor_y == "samy"
29
- assert mm.config.signals.x == SignalData(name="samx", entry="samx", limits=[-10, 10])
30
- assert mm.config.signals.y == SignalData(name="samy", entry="samy", limits=[-5, 5])
31
-
32
- mm.change_motors("samx", "samz")
33
-
34
- assert mm.config.signals.x == SignalData(name="samx", entry="samx", limits=[-10, 10])
35
- assert mm.config.signals.y == SignalData(name="samz", entry="samz", limits=[-8, 8])
36
-
37
-
38
- def test_motor_map_get_limits(qtbot, mocked_client):
39
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
40
- mm = bec_figure.motor_map("samx", "samy")
41
- expected_limits = {"samx": [-10, 10], "samy": [-5, 5]}
42
-
43
- for motor_name, expected_limit in expected_limits.items():
44
- actual_limit = mm._get_motor_limit(motor_name)
45
- assert actual_limit == expected_limit
46
-
47
-
48
- def test_motor_map_get_init_position(qtbot, mocked_client):
49
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
50
- mm = bec_figure.motor_map("samx", "samy")
51
- mm.set_precision(2)
52
-
53
- motor_map_dev = mm.client.device_manager.devices
54
-
55
- expected_positions = {
56
- ("samx", "samx"): motor_map_dev["samx"].read()["samx"]["value"],
57
- ("samy", "samy"): motor_map_dev["samy"].read()["samy"]["value"],
58
- }
59
-
60
- for (motor_name, entry), expected_position in expected_positions.items():
61
- actual_position = mm._get_motor_init_position(motor_name, entry, 2)
62
- assert actual_position == expected_position
63
-
64
-
65
- def test_motor_movement_updates_position_and_database(qtbot, mocked_client):
66
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
67
- mm = bec_figure.motor_map("samx", "samy")
68
- motor_map_dev = mm.client.device_manager.devices
69
-
70
- init_positions = {
71
- "samx": [motor_map_dev["samx"].read()["samx"]["value"]],
72
- "samy": [motor_map_dev["samy"].read()["samy"]["value"]],
73
- }
74
-
75
- mm.change_motors("samx", "samy")
76
-
77
- assert mm.database_buffer["x"] == init_positions["samx"]
78
- assert mm.database_buffer["y"] == init_positions["samy"]
79
-
80
- # Simulate motor movement for 'samx' only
81
- new_position_samx = 4.0
82
- msg = DeviceMessage(signals={"samx": {"value": new_position_samx}}, metadata={})
83
- mm.on_device_readback(msg.content, msg.metadata)
84
-
85
- init_positions["samx"].append(new_position_samx)
86
- init_positions["samy"].append(init_positions["samy"][-1])
87
- # Verify database update for 'samx'
88
- assert mm.database_buffer["x"] == init_positions["samx"]
89
-
90
- # Verify 'samy' retains its last known position
91
- assert mm.database_buffer["y"] == init_positions["samy"]
92
-
93
-
94
- def test_scatter_plot_rendering(qtbot, mocked_client):
95
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
96
- mm = bec_figure.motor_map("samx", "samy")
97
- motor_map_dev = mm.client.device_manager.devices
98
-
99
- init_positions = {
100
- "samx": [motor_map_dev["samx"].read()["samx"]["value"]],
101
- "samy": [motor_map_dev["samy"].read()["samy"]["value"]],
102
- }
103
-
104
- mm.change_motors("samx", "samy")
105
-
106
- # Simulate motor movement for 'samx' only
107
- new_position_samx = 4.0
108
- msg = DeviceMessage(signals={"samx": {"value": new_position_samx}}, metadata={})
109
- mm.on_device_readback(msg.content, msg.metadata)
110
- mm._update_plot()
111
-
112
- # Get the scatter plot item
113
- scatter_plot_item = mm.plot_components["scatter"]
114
-
115
- # Check the scatter plot item properties
116
- assert len(scatter_plot_item.data) > 0, "Scatter plot data is empty"
117
- x_data = scatter_plot_item.data["x"]
118
- y_data = scatter_plot_item.data["y"]
119
- assert x_data[-1] == new_position_samx, "Scatter plot X data not updated correctly"
120
- assert (
121
- y_data[-1] == init_positions["samy"][-1]
122
- ), "Scatter plot Y data should retain last known position"
123
-
124
-
125
- def test_plot_visualization_consistency(qtbot, mocked_client):
126
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
127
- mm = bec_figure.motor_map("samx", "samy")
128
- mm.change_motors("samx", "samy")
129
- # Simulate updating the plot with new data
130
- msg = DeviceMessage(signals={"samx": {"value": 5}}, metadata={})
131
- mm.on_device_readback(msg.content, msg.metadata)
132
- msg = DeviceMessage(signals={"samy": {"value": 9}}, metadata={})
133
- mm.on_device_readback(msg.content, msg.metadata)
134
- mm._update_plot()
135
-
136
- scatter_plot_item = mm.plot_components["scatter"]
137
-
138
- # Check if the scatter plot reflects the new data correctly
139
- assert (
140
- scatter_plot_item.data["x"][-1] == 5 and scatter_plot_item.data["y"][-1] == 9
141
- ), "Plot not updated correctly with new data"
142
-
143
-
144
- def test_change_background_value(qtbot, mocked_client):
145
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
146
- mm = bec_figure.motor_map("samx", "samy")
147
-
148
- assert mm.config.background_value == 25
149
- assert np.all(mm.plot_components["limit_map"].image == 25.0)
150
-
151
- mm.set_background_value(50)
152
- qtbot.wait(200)
153
-
154
- assert mm.config.background_value == 50
155
- assert np.all(mm.plot_components["limit_map"].image == 50.0)
156
-
157
-
158
- def test_motor_map_init_from_config(qtbot, mocked_client):
159
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
160
- config = {
161
- "widget_class": "BECMotorMap",
162
- "gui_id": "mm_id",
163
- "parent_id": bec_figure.gui_id,
164
- "row": 0,
165
- "col": 0,
166
- "axis": {
167
- "title": "Motor position: (-0.0, 0.0)",
168
- "title_size": None,
169
- "x_label": "Motor X (samx)",
170
- "x_label_size": None,
171
- "y_label": "Motor Y (samy)",
172
- "y_label_size": None,
173
- "legend_label_size": None,
174
- "x_scale": "linear",
175
- "y_scale": "linear",
176
- "x_lim": None,
177
- "y_lim": None,
178
- "x_grid": True,
179
- "y_grid": True,
180
- },
181
- "signals": {
182
- "source": "device_readback",
183
- "x": {
184
- "name": "samx",
185
- "entry": "samx",
186
- "unit": None,
187
- "modifier": None,
188
- "limits": [-10.0, 10.0],
189
- },
190
- "y": {
191
- "name": "samy",
192
- "entry": "samy",
193
- "unit": None,
194
- "modifier": None,
195
- "limits": [-5.0, 5.0],
196
- },
197
- "z": None,
198
- "dap": None,
199
- },
200
- "color": (255, 255, 255, 255),
201
- "scatter_size": 5,
202
- "max_points": 50,
203
- "num_dim_points": 10,
204
- "precision": 5,
205
- "background_value": 50,
206
- }
207
- mm = bec_figure.motor_map(config=config)
208
- config["gui_id"] = mm.gui_id
209
-
210
- assert mm._config_dict == config
211
-
212
-
213
- def test_motor_map_set_scatter_size(qtbot, mocked_client):
214
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
215
- mm = bec_figure.motor_map("samx", "samy")
216
-
217
- assert mm.config.scatter_size == 5
218
- assert mm.plot_components["scatter"].opts["size"] == 5
219
-
220
- mm.set_scatter_size(10)
221
- qtbot.wait(200)
222
-
223
- assert mm.config.scatter_size == 10
224
- assert mm.plot_components["scatter"].opts["size"] == 10
225
-
226
-
227
- def test_motor_map_change_precision(qtbot, mocked_client):
228
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
229
- mm = bec_figure.motor_map("samx", "samy")
230
-
231
- assert mm.config.precision == 2
232
- mm.set_precision(10)
233
- assert mm.config.precision == 10
234
-
235
-
236
- def test_motor_map_set_color(qtbot, mocked_client):
237
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
238
- mm = bec_figure.motor_map("samx", "samy")
239
-
240
- assert mm.config.color == (255, 255, 255, 255)
241
-
242
- mm.set_color((0, 0, 0, 255))
243
- qtbot.wait(200)
244
- assert mm.config.color == (0, 0, 0, 255)
245
-
246
-
247
- def test_motor_map_get_data_max_points(qtbot, mocked_client):
248
- bec_figure = create_widget(qtbot, BECFigure, client=mocked_client)
249
- mm = bec_figure.motor_map("samx", "samy")
250
- motor_map_dev = mm.client.device_manager.devices
251
-
252
- init_positions = {
253
- "samx": [motor_map_dev["samx"].read()["samx"]["value"]],
254
- "samy": [motor_map_dev["samy"].read()["samy"]["value"]],
255
- }
256
- msg = DeviceMessage(signals={"samx": {"value": 5.0}}, metadata={})
257
- mm.on_device_readback(msg.content, msg.metadata)
258
- msg = DeviceMessage(signals={"samy": {"value": 9.0}}, metadata={})
259
- mm.on_device_readback(msg.content, msg.metadata)
260
- msg = DeviceMessage(signals={"samx": {"value": 6.0}}, metadata={})
261
- mm.on_device_readback(msg.content, msg.metadata)
262
- msg = DeviceMessage(signals={"samy": {"value": 7.0}}, metadata={})
263
- mm.on_device_readback(msg.content, msg.metadata)
264
-
265
- expected_x = [init_positions["samx"][-1], 5.0, 5.0, 6.0, 6.0]
266
- expected_y = [init_positions["samy"][-1], init_positions["samy"][-1], 9.0, 9.0, 7.0]
267
- get_data = mm.get_data()
268
-
269
- assert mm.database_buffer["x"] == expected_x
270
- assert mm.database_buffer["y"] == expected_y
271
- assert get_data["x"] == expected_x
272
- assert get_data["y"] == expected_y
273
-
274
- mm.set_max_points(3)
275
- qtbot.wait(200)
276
- get_data = mm.get_data()
277
- assert len(get_data["x"]) == 3
278
- assert len(get_data["y"]) == 3
279
- assert get_data["x"] == expected_x[-3:]
280
- assert get_data["y"] == expected_y[-3:]
281
- assert mm.database_buffer["x"] == expected_x[-3:]
282
- assert mm.database_buffer["y"] == expected_y[-3:]
@@ -1,111 +0,0 @@
1
- import pytest
2
- from bec_lib import messages
3
-
4
- from bec_widgets.widgets.bec_queue.bec_queue import BECQueue
5
-
6
- from .client_mocks import mocked_client
7
-
8
-
9
- @pytest.fixture
10
- def bec_queue_msg_full():
11
- content = {
12
- "primary": {
13
- "info": [
14
- {
15
- "active_request_block": None,
16
- "is_scan": [True],
17
- "queue_id": "600163fc-5e56-4901-af25-14e9ee76817c",
18
- "request_blocks": [
19
- {
20
- "RID": "89a76021-28c0-4297-828e-74ae40b941e5",
21
- "content": {
22
- "parameter": {
23
- "args": {"samx": [-0.1, 0.1]},
24
- "kwargs": {
25
- "exp_time": 0.5,
26
- "relative": True,
27
- "steps": 20,
28
- "system_config": {
29
- "file_directory": None,
30
- "file_suffix": None,
31
- },
32
- },
33
- },
34
- "queue": "primary",
35
- "scan_type": "line_scan",
36
- },
37
- "is_scan": True,
38
- "metadata": {
39
- "RID": "89a76021-28c0-4297-828e-74ae40b941e5",
40
- "file_directory": None,
41
- "file_suffix": None,
42
- "user_metadata": {"sample_name": "testA"},
43
- },
44
- "msg": messages.ScanQueueMessage(
45
- metadata={
46
- "file_suffix": None,
47
- "file_directory": None,
48
- "user_metadata": {"sample_name": "testA"},
49
- "RID": "89a76021-28c0-4297-828e-74ae40b941e5",
50
- },
51
- scan_type="line_scan",
52
- parameter={
53
- "args": {"samx": [-0.1, 0.1]},
54
- "kwargs": {
55
- "steps": 20,
56
- "exp_time": 0.5,
57
- "relative": True,
58
- "system_config": {
59
- "file_suffix": None,
60
- "file_directory": None,
61
- },
62
- },
63
- },
64
- queue="primary",
65
- ),
66
- "readout_priority": {
67
- "async": [],
68
- "baseline": [],
69
- "monitored": ["samx"],
70
- "on_request": [],
71
- },
72
- "report_instructions": [{"scan_progress": 20}],
73
- "scan_id": "2d704cc3-c172-404c-866d-608ce09fce40",
74
- "scan_motors": ["samx"],
75
- "scan_number": 1289,
76
- }
77
- ],
78
- "scan_id": ["2d704cc3-c172-404c-866d-608ce09fce40"],
79
- "scan_number": [1289],
80
- "status": "COMPLETED",
81
- }
82
- ],
83
- "status": "RUNNING",
84
- }
85
- }
86
- msg = messages.ScanQueueStatusMessage(metadata={}, queue=content)
87
- return msg
88
-
89
-
90
- @pytest.fixture
91
- def bec_queue(qtbot, mocked_client):
92
- widget = BECQueue(client=mocked_client)
93
- qtbot.addWidget(widget)
94
- qtbot.waitExposed(widget)
95
- yield widget
96
-
97
-
98
- def test_bec_queue(bec_queue, bec_queue_msg_full):
99
- bec_queue.update_queue(bec_queue_msg_full.content, {})
100
- assert bec_queue.table.rowCount() == 1
101
- assert bec_queue.table.item(0, 0).text() == "1289"
102
- assert bec_queue.table.item(0, 1).text() == "line_scan"
103
- assert bec_queue.table.item(0, 2).text() == "COMPLETED"
104
-
105
-
106
- def test_bec_queue_empty(bec_queue):
107
- bec_queue.update_queue({}, {})
108
- assert bec_queue.table.rowCount() == 1
109
- assert bec_queue.table.item(0, 0).text() == ""
110
- assert bec_queue.table.item(0, 1).text() == ""
111
- assert bec_queue.table.item(0, 2).text() == ""
@@ -1,123 +0,0 @@
1
- # pylint: skip-file
2
- from unittest import mock
3
-
4
- import pytest
5
- from bec_lib.messages import BECStatus, ServiceMetricMessage, StatusMessage
6
-
7
- from bec_widgets.widgets.bec_status_box.bec_status_box import BECServiceInfoContainer, BECStatusBox
8
-
9
- from .client_mocks import mocked_client
10
-
11
-
12
- @pytest.fixture
13
- def service_status_fixture():
14
- yield mock.MagicMock()
15
-
16
-
17
- @pytest.fixture
18
- def status_box(qtbot, mocked_client, service_status_fixture):
19
- widget = BECStatusBox(client=mocked_client, bec_service_status_mixin=service_status_fixture)
20
- qtbot.addWidget(widget)
21
- qtbot.waitExposed(widget)
22
- yield widget
23
-
24
-
25
- def test_update_top_item(status_box):
26
- assert status_box.tree.children()[0].children()[0].config.status == "IDLE"
27
- name = status_box.box_name
28
- status_box.update_top_item_status(status="RUNNING")
29
- assert status_box.status_container[name]["info"].status == "RUNNING"
30
- assert status_box.tree.children()[0].children()[0].config.status == "RUNNING"
31
-
32
-
33
- def test_create_status_widget(status_box):
34
- name = "test_service"
35
- status = BECStatus.IDLE
36
- info = {"test": "test"}
37
- metrics = {"metric": "test_metric"}
38
- item = status_box._create_status_widget(name, status, info, metrics)
39
- assert item.config.service_name == name
40
- assert item.config.status == status.name
41
- assert item.config.info == info
42
- assert item.config.metrics == metrics
43
-
44
-
45
- def test_bec_service_container(status_box):
46
- name = "test_service"
47
- status = BECStatus.IDLE
48
- info = {"test": "test"}
49
- metrics = {"metric": "test_metric"}
50
- expected_return = BECServiceInfoContainer(
51
- service_name=name, status=status.name, info=info, metrics=metrics
52
- )
53
- assert status_box.box_name in status_box.status_container
54
- assert len(status_box.status_container) == 1
55
- status_box._update_status_container(name, status, info, metrics)
56
- assert len(status_box.status_container) == 2
57
- assert status_box.status_container[name]["info"] == expected_return
58
-
59
-
60
- def test_add_tree_item(status_box):
61
- name = "test_service"
62
- status = BECStatus.IDLE
63
- info = {"test": "test"}
64
- metrics = {"metric": "test_metric"}
65
- assert len(status_box.tree.children()[0].children()) == 1
66
- status_box.add_tree_item(name, status, info, metrics)
67
- assert len(status_box.tree.children()[0].children()) == 2
68
- assert name in status_box.status_container
69
-
70
-
71
- def test_update_service_status(status_box):
72
- """Also checks check redundant tree items"""
73
- name = "test_service"
74
- status = BECStatus.IDLE
75
- info = {"test": "test"}
76
- metrics = {"metric": "test_metric"}
77
- status_box.add_tree_item(name, status, info, {})
78
- not_connected_name = "invalid_service"
79
- status_box.add_tree_item(not_connected_name, status, info, metrics)
80
-
81
- services_status = {name: StatusMessage(name=name, status=status, info=info)}
82
- services_metrics = {name: ServiceMetricMessage(name=name, metrics=metrics)}
83
-
84
- with mock.patch.object(status_box, "update_core_services", return_value=services_status):
85
- assert not_connected_name in status_box.status_container
86
- status_box.update_service_status(services_status, services_metrics)
87
- assert status_box.status_container[name]["widget"].config.metrics == metrics
88
- assert not_connected_name not in status_box.status_container
89
-
90
-
91
- def test_update_core_services(status_box):
92
- status_box.CORE_SERVICES = ["test_service"]
93
- name = "test_service"
94
- status = BECStatus.RUNNING
95
- info = {"test": "test"}
96
- metrics = {"metric": "test_metric"}
97
- services_status = {name: StatusMessage(name=name, status=status, info=info)}
98
- services_metrics = {name: ServiceMetricMessage(name=name, metrics=metrics)}
99
-
100
- status_box.update_core_services(services_status, services_metrics)
101
- assert status_box.tree.children()[0].children()[0].config.status == "RUNNING"
102
- assert status_box.status_container[name]["widget"].config.metrics == metrics
103
-
104
- status = BECStatus.IDLE
105
- services_status = {name: StatusMessage(name=name, status=status, info=info)}
106
- services_metrics = {name: ServiceMetricMessage(name=name, metrics=metrics)}
107
- status_box.update_core_services(services_status, services_metrics)
108
- assert status_box.tree.children()[0].children()[0].config.status == status.name
109
- assert status_box.status_container[name]["widget"].config.metrics == metrics
110
-
111
-
112
- def test_double_click_item(status_box):
113
- name = "test_service"
114
- status = BECStatus.IDLE
115
- info = {"test": "test"}
116
- metrics = {"MyData": "This should be shown nicely"}
117
- status_box.add_tree_item(name, status, info, metrics)
118
- container = status_box.status_container[name]
119
- item = container["item"]
120
- status_item = container["widget"]
121
- with mock.patch.object(status_item, "show_popup") as mock_show_popup:
122
- status_box.tree.itemDoubleClicked.emit(item, 0)
123
- assert mock_show_popup.call_count == 1
@@ -1,76 +0,0 @@
1
- from unittest import mock
2
-
3
- import pytest
4
-
5
- from bec_widgets.cli.client import BECFigure
6
- from bec_widgets.cli.client_utils import BECGuiClientMixin, _start_plot_process
7
-
8
- from .client_mocks import FakeDevice
9
-
10
-
11
- @pytest.fixture
12
- def cli_figure():
13
- fig = BECFigure(gui_id="test")
14
- with mock.patch.object(fig, "_run_rpc") as mock_rpc_call:
15
- with mock.patch.object(fig, "gui_is_alive", return_value=True):
16
- yield fig, mock_rpc_call
17
-
18
-
19
- def test_rpc_call_plot(cli_figure):
20
- fig, mock_rpc_call = cli_figure
21
- fig.plot(x_name="samx", y_name="bpm4i")
22
- mock_rpc_call.assert_called_with("plot", x_name="samx", y_name="bpm4i")
23
-
24
-
25
- def test_rpc_call_accepts_device_as_input(cli_figure):
26
- dev1 = FakeDevice("samx")
27
- dev2 = FakeDevice("bpm4i")
28
- fig, mock_rpc_call = cli_figure
29
- fig.plot(x_name=dev1, y_name=dev2)
30
- mock_rpc_call.assert_called_with("plot", x_name="samx", y_name="bpm4i")
31
-
32
-
33
- @pytest.mark.parametrize(
34
- "config, call_config",
35
- [
36
- (None, None),
37
- ("/path/to/config.yml", "/path/to/config.yml"),
38
- ({"key": "value"}, '{"key": "value"}'),
39
- ],
40
- )
41
- def test_client_utils_start_plot_process(config, call_config):
42
- with mock.patch("bec_widgets.cli.client_utils.subprocess.Popen") as mock_popen:
43
- _start_plot_process("gui_id", BECFigure, config)
44
- command = ["bec-gui-server", "--id", "gui_id", "--gui_class", "BECFigure"]
45
- if call_config:
46
- command.extend(["--config", call_config])
47
- mock_popen.assert_called_once_with(
48
- command,
49
- text=True,
50
- start_new_session=True,
51
- stdout=mock.ANY,
52
- stderr=mock.ANY,
53
- env=mock.ANY,
54
- )
55
-
56
-
57
- def test_client_utils_passes_client_config_to_server(bec_dispatcher):
58
- """
59
- Test that the client config is passed to the server. This ensures that
60
- changes to the client config (either through config files or plugins) are
61
- reflected in the server.
62
- """
63
- mixin = BECGuiClientMixin()
64
- mixin._client = bec_dispatcher.client
65
- mixin._gui_id = "gui_id"
66
- mixin.gui_is_alive = mock.MagicMock()
67
- mixin.gui_is_alive.side_effect = [True]
68
-
69
- with mock.patch("bec_widgets.cli.client_utils._start_plot_process") as mock_start_plot:
70
- with mock.patch.object(mixin, "_start_update_script") as mock_start_update:
71
- mock_start_plot.return_value = [mock.MagicMock(), mock.MagicMock()]
72
- mixin.show()
73
- mock_start_plot.assert_called_once_with(
74
- "gui_id", BECGuiClientMixin, mixin._client._service_config.config
75
- )
76
- mock_start_update.assert_called_once()
@@ -1,42 +0,0 @@
1
- import pyqtgraph as pg
2
- import pytest
3
-
4
- from bec_widgets.widgets.colormap_selector.colormap_selector import ColormapSelector
5
-
6
-
7
- @pytest.fixture
8
- def color_map_selector(qtbot):
9
- widget = ColormapSelector()
10
- qtbot.addWidget(widget)
11
- qtbot.waitExposed(widget)
12
- yield widget
13
-
14
-
15
- def test_color_map_selector_init(color_map_selector):
16
- assert color_map_selector is not None
17
- assert isinstance(color_map_selector, ColormapSelector)
18
-
19
- all_maps = pg.colormap.listMaps()
20
- loaded_maps = [
21
- color_map_selector.combo.itemText(i) for i in range(color_map_selector.combo.count())
22
- ]
23
- assert len(loaded_maps) > 0
24
- assert all_maps == loaded_maps
25
-
26
-
27
- def test_color_map_selector_add_color_maps(color_map_selector):
28
- color_map_selector.add_color_maps(["cividis", "viridis"])
29
- assert color_map_selector.combo.count() == 2
30
- assert color_map_selector.combo.itemText(0) == "cividis"
31
- assert color_map_selector.combo.itemText(1) == "viridis"
32
- assert color_map_selector.combo.itemText(2) != "cividis"
33
- assert color_map_selector.combo.itemText(2) != "viridis"
34
-
35
-
36
- def test_colormap_add_maps_by_property(color_map_selector):
37
- color_map_selector.colormaps = ["cividis", "viridis"]
38
- assert color_map_selector.combo.count() == 2
39
- assert color_map_selector.combo.itemText(0) == "cividis"
40
- assert color_map_selector.combo.itemText(1) == "viridis"
41
- assert color_map_selector.combo.itemText(2) != "cividis"
42
- assert color_map_selector.combo.itemText(2) != "viridis"