bec-widgets 0.79.3__py3-none-any.whl → 0.82.0__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.
- .gitlab-ci.yml +0 -1
- .pylintrc +1 -1
- CHANGELOG.md +52 -62
- PKG-INFO +1 -4
- README.md +2 -2
- bec_widgets/cli/client.py +3 -2
- bec_widgets/cli/generate_cli.py +11 -10
- bec_widgets/cli/rpc_wigdet_handler.py +1 -1
- bec_widgets/examples/__init__.py +0 -9
- bec_widgets/utils/bec_connector.py +2 -1
- bec_widgets/utils/bec_dispatcher.py +3 -3
- bec_widgets/utils/bec_widget.py +2 -0
- bec_widgets/utils/entry_validator.py +1 -1
- bec_widgets/utils/plugin_utils.py +80 -10
- bec_widgets/utils/ui_loader.py +85 -26
- bec_widgets/widgets/{device_inputs → base_classes}/device_input_base.py +2 -0
- bec_widgets/widgets/color_button/color_button.py +36 -0
- bec_widgets/widgets/{buttons/color_button → color_button}/color_button_plugin.py +1 -1
- bec_widgets/widgets/{buttons/color_button → color_button}/register_color_button.py +1 -1
- bec_widgets/widgets/device_combobox/assets/device_combobox_icon.png +0 -0
- bec_widgets/widgets/{device_inputs/device_combobox → device_combobox}/device_combobox.py +2 -2
- bec_widgets/widgets/device_combobox/device_combobox.pyproject +3 -0
- bec_widgets/widgets/{device_inputs/device_combobox → device_combobox}/device_combobox_plugin.py +6 -3
- bec_widgets/widgets/{device_inputs/device_combobox → device_combobox}/register_device_combobox.py +1 -3
- bec_widgets/widgets/device_line_edit/assets/line_edit_icon.png +0 -0
- bec_widgets/widgets/{device_inputs/device_line_edit → device_line_edit}/device_line_edit.py +2 -2
- bec_widgets/widgets/device_line_edit/device_line_edit.pyproject +3 -0
- bec_widgets/widgets/{device_inputs/device_line_edit → device_line_edit}/device_line_edit_plugin.py +6 -3
- bec_widgets/widgets/{device_inputs/device_line_edit → device_line_edit}/register_device_line_edit.py +1 -3
- bec_widgets/widgets/figure/plots/waveform/waveform.py +8 -2
- bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_settings.py +1 -1
- bec_widgets/widgets/motor_map/motor_map_dialog/motor_map_toolbar.py +1 -1
- bec_widgets/widgets/motor_map/motor_map_widget.py +0 -12
- bec_widgets/widgets/scan_control/scan_control.py +1 -1
- bec_widgets/widgets/scan_control/scan_group_box.py +1 -1
- bec_widgets/widgets/stop_button/assets/stop.png +0 -0
- bec_widgets/widgets/stop_button/register_stop_button.py +15 -0
- bec_widgets/widgets/{buttons/stop_button → stop_button}/stop_button.py +5 -12
- bec_widgets/widgets/stop_button/stop_button.pyproject +1 -0
- bec_widgets/widgets/stop_button/stop_button_plugin.py +57 -0
- bec_widgets/widgets/toggle/register_toggle_switch.py +15 -0
- bec_widgets/widgets/toggle/toggle.py +149 -0
- bec_widgets/widgets/toggle/toggle_switch.pyproject +1 -0
- bec_widgets/widgets/toggle/toggle_switch_plugin.py +54 -0
- {bec_widgets-0.79.3.dist-info → bec_widgets-0.82.0.dist-info}/METADATA +1 -4
- {bec_widgets-0.79.3.dist-info → bec_widgets-0.82.0.dist-info}/RECORD +66 -74
- docs/introduction/introduction.md +1 -1
- docs/user/getting_started/installation.md +2 -2
- pyproject.toml +1 -2
- tests/unit_tests/test_device_input_base.py +1 -1
- tests/unit_tests/test_device_input_widgets.py +2 -2
- tests/unit_tests/test_generate_cli_client.py +41 -17
- tests/unit_tests/test_plugin_utils.py +2 -3
- tests/unit_tests/test_stop_button.py +5 -2
- tests/unit_tests/test_toggle.py +38 -0
- bec_widgets/examples/motor_movement/__init__.py +0 -9
- bec_widgets/examples/motor_movement/motor_control_compilations.py +0 -250
- bec_widgets/examples/motor_movement/motor_controller.ui +0 -926
- bec_widgets/widgets/buttons/__init__.py +0 -1
- bec_widgets/widgets/buttons/color_button/color_button.py +0 -17
- bec_widgets/widgets/device_inputs/__init__.py +0 -2
- bec_widgets/widgets/device_inputs/device_combobox/device_combobox.pyproject +0 -4
- bec_widgets/widgets/device_inputs/device_combobox/launch_device_combobox.py +0 -11
- bec_widgets/widgets/device_inputs/device_line_edit/device_line_edit.pyproject +0 -4
- bec_widgets/widgets/device_inputs/device_line_edit/launch_device_line_edit.py +0 -11
- bec_widgets/widgets/motor_control/motor_control.py +0 -252
- bec_widgets/widgets/motor_control/motor_table/motor_table.py +0 -484
- bec_widgets/widgets/motor_control/motor_table/motor_table.ui +0 -113
- bec_widgets/widgets/motor_control/movement_absolute/__init__.py +0 -0
- bec_widgets/widgets/motor_control/movement_absolute/movement_absolute.py +0 -159
- bec_widgets/widgets/motor_control/movement_absolute/movement_absolute.ui +0 -149
- bec_widgets/widgets/motor_control/movement_relative/__init__.py +0 -0
- bec_widgets/widgets/motor_control/movement_relative/movement_relative.py +0 -230
- bec_widgets/widgets/motor_control/movement_relative/movement_relative.ui +0 -298
- bec_widgets/widgets/motor_control/selection/__init__.py +0 -0
- bec_widgets/widgets/motor_control/selection/selection.py +0 -110
- bec_widgets/widgets/motor_control/selection/selection.ui +0 -69
- tests/unit_tests/test_motor_control.py +0 -588
- /bec_widgets/widgets/{buttons/color_button → base_classes}/__init__.py +0 -0
- /bec_widgets/widgets/{buttons/stop_button → color_button}/__init__.py +0 -0
- /bec_widgets/widgets/{buttons/color_button → color_button}/assets/color_button.png +0 -0
- /bec_widgets/widgets/{buttons/color_button → color_button}/color_button.pyproject +0 -0
- /bec_widgets/widgets/{device_inputs/device_combobox → device_combobox}/__init__.py +0 -0
- /bec_widgets/widgets/{device_inputs/device_line_edit → device_line_edit}/__init__.py +0 -0
- /bec_widgets/widgets/{motor_control → stop_button}/__init__.py +0 -0
- /bec_widgets/widgets/{motor_control/motor_table → toggle}/__init__.py +0 -0
- {bec_widgets-0.79.3.dist-info → bec_widgets-0.82.0.dist-info}/WHEEL +0 -0
- {bec_widgets-0.79.3.dist-info → bec_widgets-0.82.0.dist-info}/entry_points.txt +0 -0
- {bec_widgets-0.79.3.dist-info → bec_widgets-0.82.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,588 +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 pytest
|
5
|
-
from bec_lib.devicemanager import DeviceContainer
|
6
|
-
|
7
|
-
from bec_widgets.examples import (
|
8
|
-
MotorControlApp,
|
9
|
-
MotorControlMap,
|
10
|
-
MotorControlPanel,
|
11
|
-
MotorControlPanelAbsolute,
|
12
|
-
MotorControlPanelRelative,
|
13
|
-
)
|
14
|
-
from bec_widgets.widgets.motor_control.motor_control import MotorActions, MotorThread
|
15
|
-
from bec_widgets.widgets.motor_control.motor_table.motor_table import MotorCoordinateTable
|
16
|
-
from bec_widgets.widgets.motor_control.movement_absolute.movement_absolute import (
|
17
|
-
MotorControlAbsolute,
|
18
|
-
)
|
19
|
-
from bec_widgets.widgets.motor_control.movement_relative.movement_relative import (
|
20
|
-
MotorControlRelative,
|
21
|
-
)
|
22
|
-
from bec_widgets.widgets.motor_control.selection.selection import MotorControlSelection
|
23
|
-
|
24
|
-
from .client_mocks import mocked_client
|
25
|
-
|
26
|
-
CONFIG_DEFAULT = {
|
27
|
-
"motor_control": {
|
28
|
-
"motor_x": "samx",
|
29
|
-
"motor_y": "samy",
|
30
|
-
"step_size_x": 3,
|
31
|
-
"step_size_y": 3,
|
32
|
-
"precision": 4,
|
33
|
-
"step_x_y_same": False,
|
34
|
-
"move_with_arrows": False,
|
35
|
-
},
|
36
|
-
"plot_settings": {
|
37
|
-
"colormap": "Greys",
|
38
|
-
"scatter_size": 5,
|
39
|
-
"max_points": 1000,
|
40
|
-
"num_dim_points": 100,
|
41
|
-
"precision": 2,
|
42
|
-
"num_columns": 1,
|
43
|
-
"background_value": 25,
|
44
|
-
},
|
45
|
-
"motors": [
|
46
|
-
{
|
47
|
-
"plot_name": "Motor Map",
|
48
|
-
"x_label": "Motor X",
|
49
|
-
"y_label": "Motor Y",
|
50
|
-
"signals": {
|
51
|
-
"x": [{"name": "samx", "entry": "samx"}],
|
52
|
-
"y": [{"name": "samy", "entry": "samy"}],
|
53
|
-
},
|
54
|
-
}
|
55
|
-
],
|
56
|
-
}
|
57
|
-
|
58
|
-
|
59
|
-
#######################################################
|
60
|
-
# Motor Thread
|
61
|
-
#######################################################
|
62
|
-
@pytest.fixture
|
63
|
-
def motor_thread(mocked_client):
|
64
|
-
"""Fixture for MotorThread with a mocked client."""
|
65
|
-
return MotorThread(client=mocked_client)
|
66
|
-
|
67
|
-
|
68
|
-
def test_motor_thread_initialization(mocked_client):
|
69
|
-
motor_thread = MotorThread(client=mocked_client)
|
70
|
-
assert motor_thread.client == mocked_client
|
71
|
-
assert isinstance(motor_thread.dev, DeviceContainer)
|
72
|
-
|
73
|
-
|
74
|
-
def test_get_all_motors_names(mocked_client):
|
75
|
-
motor_thread = MotorThread(client=mocked_client)
|
76
|
-
motor_names = motor_thread.get_all_motors_names()
|
77
|
-
expected_names = ["samx", "samy", "samz", "aptrx", "aptry"]
|
78
|
-
assert sorted(motor_names) == sorted(expected_names)
|
79
|
-
assert all(name in motor_names for name in expected_names)
|
80
|
-
assert len(motor_names) == len(expected_names) # Ensure only these motors are returned
|
81
|
-
|
82
|
-
|
83
|
-
def test_get_coordinates(mocked_client):
|
84
|
-
motor_thread = MotorThread(client=mocked_client)
|
85
|
-
motor_x, motor_y = "samx", "samy"
|
86
|
-
x, y = motor_thread.get_coordinates(motor_x, motor_y)
|
87
|
-
|
88
|
-
assert x == mocked_client.device_manager.devices[motor_x].readback.get()
|
89
|
-
assert y == mocked_client.device_manager.devices[motor_y].readback.get()
|
90
|
-
|
91
|
-
|
92
|
-
def test_move_motor_absolute_by_run(mocked_client):
|
93
|
-
motor_thread = MotorThread(client=mocked_client)
|
94
|
-
motor_thread.motor_x = "samx"
|
95
|
-
motor_thread.motor_y = "samy"
|
96
|
-
motor_thread.target_coordinates = (5.0, -3.0)
|
97
|
-
motor_thread.action = MotorActions.MOVE_ABSOLUTE
|
98
|
-
motor_thread.run()
|
99
|
-
|
100
|
-
assert mocked_client.device_manager.devices["samx"].read_value == 5.0
|
101
|
-
assert mocked_client.device_manager.devices["samy"].read_value == -3.0
|
102
|
-
|
103
|
-
|
104
|
-
def test_move_motor_relative_by_run(mocked_client):
|
105
|
-
motor_thread = MotorThread(client=mocked_client)
|
106
|
-
|
107
|
-
initial_value = motor_thread.dev["samx"].read()["samx"]["value"]
|
108
|
-
move_value = 2.0
|
109
|
-
expected_value = initial_value + move_value
|
110
|
-
motor_thread.motor = "samx"
|
111
|
-
motor_thread.value = move_value
|
112
|
-
motor_thread.action = MotorActions.MOVE_RELATIVE
|
113
|
-
motor_thread.run()
|
114
|
-
|
115
|
-
assert mocked_client.device_manager.devices["samx"].read_value == expected_value
|
116
|
-
|
117
|
-
|
118
|
-
def test_motor_thread_move_absolute(motor_thread):
|
119
|
-
motor_x = "samx"
|
120
|
-
motor_y = "samy"
|
121
|
-
target_x = 5.0
|
122
|
-
target_y = -3.0
|
123
|
-
|
124
|
-
motor_thread.move_absolute(motor_x, motor_y, (target_x, target_y))
|
125
|
-
motor_thread.wait()
|
126
|
-
|
127
|
-
assert motor_thread.dev[motor_x].read()["samx"]["value"] == target_x
|
128
|
-
assert motor_thread.dev[motor_y].read()["samy"]["value"] == target_y
|
129
|
-
|
130
|
-
|
131
|
-
def test_motor_thread_move_relative(motor_thread):
|
132
|
-
motor_name = "samx"
|
133
|
-
move_value = 2.0
|
134
|
-
|
135
|
-
initial_value = motor_thread.dev[motor_name].read()["samx"]["value"]
|
136
|
-
motor_thread.move_relative(motor_name, move_value)
|
137
|
-
motor_thread.wait()
|
138
|
-
|
139
|
-
expected_value = initial_value + move_value
|
140
|
-
assert motor_thread.dev[motor_name].read()["samx"]["value"] == expected_value
|
141
|
-
|
142
|
-
|
143
|
-
#######################################################
|
144
|
-
# Motor Control Widgets - MotorControlSelection
|
145
|
-
#######################################################
|
146
|
-
@pytest.fixture(scope="function")
|
147
|
-
def motor_selection_widget(qtbot, mocked_client, motor_thread):
|
148
|
-
"""Fixture for creating a MotorControlSelection widget with a mocked client."""
|
149
|
-
widget = MotorControlSelection(
|
150
|
-
client=mocked_client, config=CONFIG_DEFAULT, motor_thread=motor_thread
|
151
|
-
)
|
152
|
-
qtbot.addWidget(widget)
|
153
|
-
qtbot.waitExposed(widget)
|
154
|
-
return widget
|
155
|
-
|
156
|
-
|
157
|
-
def test_initialization_and_population(motor_selection_widget):
|
158
|
-
assert motor_selection_widget.comboBox_motor_x.count() == 5
|
159
|
-
assert motor_selection_widget.comboBox_motor_x.itemText(0) == "samx"
|
160
|
-
assert motor_selection_widget.comboBox_motor_y.itemText(1) == "samy"
|
161
|
-
assert motor_selection_widget.comboBox_motor_y.itemText(2) == "samz"
|
162
|
-
assert motor_selection_widget.comboBox_motor_x.itemText(3) == "aptrx"
|
163
|
-
assert motor_selection_widget.comboBox_motor_y.itemText(4) == "aptry"
|
164
|
-
|
165
|
-
|
166
|
-
def test_selection_and_signal_emission(motor_selection_widget):
|
167
|
-
# Connect signal to a custom slot to capture the emitted values
|
168
|
-
emitted_values = []
|
169
|
-
|
170
|
-
def capture_emitted_values(motor_x, motor_y):
|
171
|
-
emitted_values.append((motor_x, motor_y))
|
172
|
-
|
173
|
-
motor_selection_widget.selected_motors_signal.connect(capture_emitted_values)
|
174
|
-
|
175
|
-
# Select motors
|
176
|
-
motor_selection_widget.comboBox_motor_x.setCurrentIndex(0) # Select 'samx'
|
177
|
-
motor_selection_widget.comboBox_motor_y.setCurrentIndex(1) # Select 'samy'
|
178
|
-
motor_selection_widget.pushButton_connecMotors.click() # Emit the signal
|
179
|
-
|
180
|
-
# Verify the emitted signal
|
181
|
-
assert emitted_values == [
|
182
|
-
("samx", "samy")
|
183
|
-
], "The emitted signal did not match the expected values"
|
184
|
-
|
185
|
-
|
186
|
-
def test_configuration_update(motor_selection_widget):
|
187
|
-
new_config = {"motor_control": {"motor_x": "samy", "motor_y": "samx"}}
|
188
|
-
motor_selection_widget.on_config_update(new_config)
|
189
|
-
assert motor_selection_widget.comboBox_motor_x.currentText() == "samy"
|
190
|
-
assert motor_selection_widget.comboBox_motor_y.currentText() == "samx"
|
191
|
-
|
192
|
-
|
193
|
-
def test_enable_motor_controls(motor_selection_widget):
|
194
|
-
motor_selection_widget.enable_motor_controls(False)
|
195
|
-
assert not motor_selection_widget.comboBox_motor_x.isEnabled()
|
196
|
-
assert not motor_selection_widget.comboBox_motor_y.isEnabled()
|
197
|
-
|
198
|
-
motor_selection_widget.enable_motor_controls(True)
|
199
|
-
assert motor_selection_widget.comboBox_motor_x.isEnabled()
|
200
|
-
assert motor_selection_widget.comboBox_motor_y.isEnabled()
|
201
|
-
|
202
|
-
|
203
|
-
#######################################################
|
204
|
-
# Motor Control Widgets - MotorControlAbsolute
|
205
|
-
#######################################################
|
206
|
-
|
207
|
-
|
208
|
-
@pytest.fixture(scope="function")
|
209
|
-
def motor_absolute_widget(qtbot, mocked_client, motor_thread):
|
210
|
-
widget = MotorControlAbsolute(
|
211
|
-
client=mocked_client, config=CONFIG_DEFAULT, motor_thread=motor_thread
|
212
|
-
)
|
213
|
-
qtbot.addWidget(widget)
|
214
|
-
qtbot.waitExposed(widget)
|
215
|
-
return widget
|
216
|
-
|
217
|
-
|
218
|
-
def test_absolute_initialization(motor_absolute_widget):
|
219
|
-
motor_absolute_widget.change_motors("samx", "samy")
|
220
|
-
motor_absolute_widget.on_config_update(CONFIG_DEFAULT)
|
221
|
-
assert motor_absolute_widget.motor_x == "samx", "Motor X not initialized correctly"
|
222
|
-
assert motor_absolute_widget.motor_y == "samy", "Motor Y not initialized correctly"
|
223
|
-
assert motor_absolute_widget.precision == CONFIG_DEFAULT["motor_control"]["precision"]
|
224
|
-
|
225
|
-
|
226
|
-
def test_absolute_save_current_coordinates(motor_absolute_widget):
|
227
|
-
motor_x_value = motor_absolute_widget.client.device_manager.devices["samx"].read()["samx"][
|
228
|
-
"value"
|
229
|
-
]
|
230
|
-
motor_y_value = motor_absolute_widget.client.device_manager.devices["samy"].read()["samy"][
|
231
|
-
"value"
|
232
|
-
]
|
233
|
-
motor_absolute_widget.change_motors("samx", "samy")
|
234
|
-
|
235
|
-
emitted_coordinates = []
|
236
|
-
|
237
|
-
def capture_emit(x_y):
|
238
|
-
emitted_coordinates.append(x_y)
|
239
|
-
|
240
|
-
motor_absolute_widget.coordinates_signal.connect(capture_emit)
|
241
|
-
|
242
|
-
# Trigger saving current coordinates
|
243
|
-
motor_absolute_widget.ui.pushButton_save.click()
|
244
|
-
|
245
|
-
assert emitted_coordinates == [(motor_x_value, motor_y_value)]
|
246
|
-
|
247
|
-
|
248
|
-
def test_absolute_set_absolute_coordinates(motor_absolute_widget):
|
249
|
-
motor_absolute_widget.ui.spinBox_absolute_x.setValue(5)
|
250
|
-
motor_absolute_widget.ui.spinBox_absolute_y.setValue(10)
|
251
|
-
|
252
|
-
# Connect to the coordinates_signal to capture emitted values
|
253
|
-
emitted_values = []
|
254
|
-
|
255
|
-
def capture_coordinates(x_y):
|
256
|
-
emitted_values.append(x_y)
|
257
|
-
|
258
|
-
motor_absolute_widget.coordinates_signal.connect(capture_coordinates)
|
259
|
-
|
260
|
-
# Simulate button click for absolute movement
|
261
|
-
motor_absolute_widget.ui.pushButton_set.click()
|
262
|
-
|
263
|
-
assert emitted_values == [(5, 10)]
|
264
|
-
|
265
|
-
|
266
|
-
def test_absolute_go_absolute_coordinates(motor_absolute_widget):
|
267
|
-
motor_absolute_widget.change_motors("samx", "samy")
|
268
|
-
|
269
|
-
motor_absolute_widget.ui.spinBox_absolute_x.setValue(5)
|
270
|
-
motor_absolute_widget.ui.spinBox_absolute_y.setValue(10)
|
271
|
-
|
272
|
-
with patch(
|
273
|
-
"bec_widgets.widgets.motor_control.motor_control.MotorThread.move_absolute",
|
274
|
-
new_callable=MagicMock,
|
275
|
-
) as mock_move_absolute:
|
276
|
-
motor_absolute_widget.ui.pushButton_go_absolute.click()
|
277
|
-
mock_move_absolute.assert_called_once_with("samx", "samy", (5, 10))
|
278
|
-
|
279
|
-
|
280
|
-
def test_change_motor_absolute(motor_absolute_widget):
|
281
|
-
motor_absolute_widget.change_motors("aptrx", "aptry")
|
282
|
-
|
283
|
-
assert motor_absolute_widget.motor_x == "aptrx"
|
284
|
-
assert motor_absolute_widget.motor_y == "aptry"
|
285
|
-
|
286
|
-
motor_absolute_widget.change_motors("samx", "samy")
|
287
|
-
|
288
|
-
assert motor_absolute_widget.motor_x == "samx"
|
289
|
-
assert motor_absolute_widget.motor_y == "samy"
|
290
|
-
|
291
|
-
|
292
|
-
def test_set_precision(motor_absolute_widget):
|
293
|
-
motor_absolute_widget.on_config_update(CONFIG_DEFAULT)
|
294
|
-
motor_absolute_widget.set_precision(2)
|
295
|
-
|
296
|
-
assert motor_absolute_widget.ui.spinBox_absolute_x.decimals() == 2
|
297
|
-
assert motor_absolute_widget.ui.spinBox_absolute_y.decimals() == 2
|
298
|
-
|
299
|
-
|
300
|
-
#######################################################
|
301
|
-
# Motor Control Widgets - MotorControlRelative
|
302
|
-
#######################################################
|
303
|
-
@pytest.fixture(scope="function")
|
304
|
-
def motor_relative_widget(qtbot, mocked_client, motor_thread):
|
305
|
-
widget = MotorControlRelative(
|
306
|
-
client=mocked_client, config=CONFIG_DEFAULT, motor_thread=motor_thread
|
307
|
-
)
|
308
|
-
qtbot.addWidget(widget)
|
309
|
-
qtbot.waitExposed(widget)
|
310
|
-
return widget
|
311
|
-
|
312
|
-
|
313
|
-
def test_initialization_and_config_update(motor_relative_widget):
|
314
|
-
motor_relative_widget.on_config_update(CONFIG_DEFAULT)
|
315
|
-
|
316
|
-
assert motor_relative_widget.motor_x == CONFIG_DEFAULT["motor_control"]["motor_x"]
|
317
|
-
assert motor_relative_widget.motor_y == CONFIG_DEFAULT["motor_control"]["motor_y"]
|
318
|
-
assert motor_relative_widget.precision == CONFIG_DEFAULT["motor_control"]["precision"]
|
319
|
-
|
320
|
-
# Simulate a configuration update
|
321
|
-
new_config = {
|
322
|
-
"motor_control": {
|
323
|
-
"motor_x": "new_motor_x",
|
324
|
-
"motor_y": "new_motor_y",
|
325
|
-
"precision": 2,
|
326
|
-
"step_size_x": 5,
|
327
|
-
"step_size_y": 5,
|
328
|
-
"step_x_y_same": True,
|
329
|
-
"move_with_arrows": True,
|
330
|
-
}
|
331
|
-
}
|
332
|
-
motor_relative_widget.on_config_update(new_config)
|
333
|
-
|
334
|
-
assert motor_relative_widget.motor_x == "new_motor_x"
|
335
|
-
assert motor_relative_widget.motor_y == "new_motor_y"
|
336
|
-
assert motor_relative_widget.precision == 2
|
337
|
-
|
338
|
-
|
339
|
-
def test_move_motor_relative(motor_relative_widget):
|
340
|
-
motor_relative_widget.on_config_update(CONFIG_DEFAULT)
|
341
|
-
# Set step sizes
|
342
|
-
motor_relative_widget.ui.spinBox_step_x.setValue(1)
|
343
|
-
motor_relative_widget.ui.spinBox_step_y.setValue(1)
|
344
|
-
|
345
|
-
# Mock the move_relative method
|
346
|
-
motor_relative_widget.motor_thread.move_relative = MagicMock()
|
347
|
-
|
348
|
-
# Simulate button clicks
|
349
|
-
motor_relative_widget.ui.toolButton_right.click()
|
350
|
-
motor_relative_widget.motor_thread.move_relative.assert_called_with(
|
351
|
-
motor_relative_widget.motor_x, 1
|
352
|
-
)
|
353
|
-
|
354
|
-
motor_relative_widget.ui.toolButton_left.click()
|
355
|
-
motor_relative_widget.motor_thread.move_relative.assert_called_with(
|
356
|
-
motor_relative_widget.motor_x, -1
|
357
|
-
)
|
358
|
-
|
359
|
-
motor_relative_widget.ui.toolButton_up.click()
|
360
|
-
motor_relative_widget.motor_thread.move_relative.assert_called_with(
|
361
|
-
motor_relative_widget.motor_y, 1
|
362
|
-
)
|
363
|
-
|
364
|
-
motor_relative_widget.ui.toolButton_down.click()
|
365
|
-
motor_relative_widget.motor_thread.move_relative.assert_called_with(
|
366
|
-
motor_relative_widget.motor_y, -1
|
367
|
-
)
|
368
|
-
|
369
|
-
|
370
|
-
def test_precision_update(motor_relative_widget):
|
371
|
-
# Capture emitted precision values
|
372
|
-
emitted_values = []
|
373
|
-
|
374
|
-
def capture_precision(precision):
|
375
|
-
emitted_values.append(precision)
|
376
|
-
|
377
|
-
motor_relative_widget.precision_signal.connect(capture_precision)
|
378
|
-
|
379
|
-
# Update precision
|
380
|
-
motor_relative_widget.ui.spinBox_precision.setValue(1)
|
381
|
-
|
382
|
-
assert emitted_values == [1]
|
383
|
-
assert motor_relative_widget.ui.spinBox_step_x.decimals() == 1
|
384
|
-
assert motor_relative_widget.ui.spinBox_step_y.decimals() == 1
|
385
|
-
|
386
|
-
|
387
|
-
def test_sync_step_sizes(motor_relative_widget):
|
388
|
-
motor_relative_widget.on_config_update(CONFIG_DEFAULT)
|
389
|
-
motor_relative_widget.ui.checkBox_same_xy.setChecked(True)
|
390
|
-
|
391
|
-
# Change step size for X
|
392
|
-
motor_relative_widget.ui.spinBox_step_x.setValue(2)
|
393
|
-
|
394
|
-
assert motor_relative_widget.ui.spinBox_step_y.value() == 2
|
395
|
-
|
396
|
-
|
397
|
-
def test_change_motor_relative(motor_relative_widget):
|
398
|
-
motor_relative_widget.on_config_update(CONFIG_DEFAULT)
|
399
|
-
motor_relative_widget.change_motors("aptrx", "aptry")
|
400
|
-
|
401
|
-
assert motor_relative_widget.motor_x == "aptrx"
|
402
|
-
assert motor_relative_widget.motor_y == "aptry"
|
403
|
-
|
404
|
-
|
405
|
-
#######################################################
|
406
|
-
# Motor Control Widgets - MotorCoordinateTable
|
407
|
-
#######################################################
|
408
|
-
@pytest.fixture(scope="function")
|
409
|
-
def motor_coordinate_table(qtbot, mocked_client, motor_thread):
|
410
|
-
widget = MotorCoordinateTable(
|
411
|
-
client=mocked_client, config=CONFIG_DEFAULT, motor_thread=motor_thread
|
412
|
-
)
|
413
|
-
qtbot.addWidget(widget)
|
414
|
-
qtbot.waitExposed(widget)
|
415
|
-
return widget
|
416
|
-
|
417
|
-
|
418
|
-
def test_delete_selected_row(motor_coordinate_table):
|
419
|
-
# Add a coordinate
|
420
|
-
motor_coordinate_table.add_coordinate((1.0, 2.0))
|
421
|
-
motor_coordinate_table.add_coordinate((3.0, 4.0))
|
422
|
-
|
423
|
-
# Select the row
|
424
|
-
motor_coordinate_table.ui.table.selectRow(0)
|
425
|
-
|
426
|
-
# Delete the selected row
|
427
|
-
motor_coordinate_table.delete_selected_row()
|
428
|
-
assert motor_coordinate_table.ui.table.rowCount() == 1
|
429
|
-
|
430
|
-
|
431
|
-
def test_add_coordinate_and_table_update(motor_coordinate_table):
|
432
|
-
# Disable Warning message popups for test
|
433
|
-
motor_coordinate_table.warning_message = False
|
434
|
-
|
435
|
-
# Add coordinate in Individual mode
|
436
|
-
motor_coordinate_table.add_coordinate((1.0, 2.0))
|
437
|
-
assert motor_coordinate_table.ui.table.rowCount() == 1
|
438
|
-
|
439
|
-
# Check if the coordinates match
|
440
|
-
x_item_individual = motor_coordinate_table.ui.table.cellWidget(
|
441
|
-
0, 3
|
442
|
-
) # Assuming X is in column 3
|
443
|
-
y_item_individual = motor_coordinate_table.ui.table.cellWidget(
|
444
|
-
0, 4
|
445
|
-
) # Assuming Y is in column 4
|
446
|
-
assert float(x_item_individual.text()) == 1.0
|
447
|
-
assert float(y_item_individual.text()) == 2.0
|
448
|
-
|
449
|
-
# Switch to Start/Stop and add coordinates
|
450
|
-
motor_coordinate_table.ui.comboBox_mode.setCurrentIndex(1) # Switch mode
|
451
|
-
|
452
|
-
motor_coordinate_table.add_coordinate((3.0, 4.0))
|
453
|
-
motor_coordinate_table.add_coordinate((5.0, 6.0))
|
454
|
-
assert motor_coordinate_table.ui.table.rowCount() == 1
|
455
|
-
|
456
|
-
|
457
|
-
def test_plot_coordinates_signal(motor_coordinate_table):
|
458
|
-
# Connect to the signal
|
459
|
-
def signal_emitted(coordinates, reference_tag, color):
|
460
|
-
nonlocal received
|
461
|
-
received = True
|
462
|
-
assert len(coordinates) == 1 # Assuming one coordinate was added
|
463
|
-
assert reference_tag in ["Individual", "Start", "Stop"]
|
464
|
-
assert color in ["green", "blue", "red"]
|
465
|
-
|
466
|
-
received = False
|
467
|
-
motor_coordinate_table.plot_coordinates_signal.connect(signal_emitted)
|
468
|
-
|
469
|
-
# Add a coordinate and check signal
|
470
|
-
motor_coordinate_table.add_coordinate((1.0, 2.0))
|
471
|
-
assert received
|
472
|
-
|
473
|
-
|
474
|
-
# def test_move_motor_action(motor_coordinate_table,qtbot):#TODO enable again after table refactor
|
475
|
-
# # Add a coordinate
|
476
|
-
# motor_coordinate_table.add_coordinate((1.0, 2.0))
|
477
|
-
#
|
478
|
-
# # Mock the motor thread move_absolute function
|
479
|
-
# motor_coordinate_table.motor_thread.move_absolute = MagicMock()
|
480
|
-
#
|
481
|
-
# # Trigger the move action
|
482
|
-
# move_button = motor_coordinate_table.table.cellWidget(0, 1)
|
483
|
-
# move_button.click()
|
484
|
-
#
|
485
|
-
# motor_coordinate_table.motor_thread.move_absolute.assert_called_with(
|
486
|
-
# motor_coordinate_table.motor_x, motor_coordinate_table.motor_y, (1.0, 2.0)
|
487
|
-
# )
|
488
|
-
|
489
|
-
|
490
|
-
def test_plot_coordinates_signal_individual(motor_coordinate_table, qtbot):
|
491
|
-
motor_coordinate_table.warning_message = False
|
492
|
-
motor_coordinate_table.set_precision(3)
|
493
|
-
motor_coordinate_table.ui.comboBox_mode.setCurrentIndex(0)
|
494
|
-
|
495
|
-
# This list will store the signals emitted during the test
|
496
|
-
emitted_signals = []
|
497
|
-
|
498
|
-
def signal_emitted(coordinates, reference_tag, color):
|
499
|
-
emitted_signals.append((coordinates, reference_tag, color))
|
500
|
-
|
501
|
-
motor_coordinate_table.plot_coordinates_signal.connect(signal_emitted)
|
502
|
-
|
503
|
-
# Add new coordinates
|
504
|
-
motor_coordinate_table.add_coordinate((1.0, 2.0))
|
505
|
-
qtbot.wait(100)
|
506
|
-
|
507
|
-
# Verify the signals
|
508
|
-
assert len(emitted_signals) > 0, "No signals were emitted."
|
509
|
-
|
510
|
-
for coordinates, reference_tag, color in emitted_signals:
|
511
|
-
assert len(coordinates) > 0, "Coordinates list is empty."
|
512
|
-
assert reference_tag == "Individual"
|
513
|
-
assert color == "green"
|
514
|
-
assert motor_coordinate_table.ui.table.cellWidget(0, 3).text() == "1.000"
|
515
|
-
assert motor_coordinate_table.ui.table.cellWidget(0, 4).text() == "2.000"
|
516
|
-
|
517
|
-
|
518
|
-
#######################################################
|
519
|
-
# MotorControl examples compilations
|
520
|
-
#######################################################
|
521
|
-
@pytest.fixture(scope="function")
|
522
|
-
def motor_app(qtbot, mocked_client):
|
523
|
-
widget = MotorControlApp(config=CONFIG_DEFAULT, client=mocked_client)
|
524
|
-
qtbot.addWidget(widget)
|
525
|
-
qtbot.waitExposed(widget)
|
526
|
-
yield widget
|
527
|
-
|
528
|
-
|
529
|
-
def test_motor_app_initialization(motor_app):
|
530
|
-
assert isinstance(motor_app, MotorControlApp)
|
531
|
-
assert motor_app.client is not None
|
532
|
-
assert motor_app.config == CONFIG_DEFAULT
|
533
|
-
|
534
|
-
|
535
|
-
@pytest.fixture(scope="function")
|
536
|
-
def motor_control_map(qtbot, mocked_client):
|
537
|
-
widget = MotorControlMap(config=CONFIG_DEFAULT, client=mocked_client)
|
538
|
-
qtbot.addWidget(widget)
|
539
|
-
qtbot.waitExposed(widget)
|
540
|
-
yield widget
|
541
|
-
|
542
|
-
|
543
|
-
def test_motor_control_map_initialization(motor_control_map):
|
544
|
-
assert isinstance(motor_control_map, MotorControlMap)
|
545
|
-
assert motor_control_map.client is not None
|
546
|
-
assert motor_control_map.config == CONFIG_DEFAULT
|
547
|
-
|
548
|
-
|
549
|
-
@pytest.fixture(scope="function")
|
550
|
-
def motor_control_panel(qtbot, mocked_client):
|
551
|
-
widget = MotorControlPanel(config=CONFIG_DEFAULT, client=mocked_client)
|
552
|
-
qtbot.addWidget(widget)
|
553
|
-
qtbot.waitExposed(widget)
|
554
|
-
yield widget
|
555
|
-
|
556
|
-
|
557
|
-
def test_motor_control_panel_initialization(motor_control_panel):
|
558
|
-
assert isinstance(motor_control_panel, MotorControlPanel)
|
559
|
-
assert motor_control_panel.client is not None
|
560
|
-
assert motor_control_panel.config == CONFIG_DEFAULT
|
561
|
-
|
562
|
-
|
563
|
-
@pytest.fixture(scope="function")
|
564
|
-
def motor_control_panel_absolute(qtbot, mocked_client):
|
565
|
-
widget = MotorControlPanelAbsolute(config=CONFIG_DEFAULT, client=mocked_client)
|
566
|
-
qtbot.addWidget(widget)
|
567
|
-
qtbot.waitExposed(widget)
|
568
|
-
yield widget
|
569
|
-
|
570
|
-
|
571
|
-
def test_motor_control_panel_absolute_initialization(motor_control_panel_absolute):
|
572
|
-
assert isinstance(motor_control_panel_absolute, MotorControlPanelAbsolute)
|
573
|
-
assert motor_control_panel_absolute.client is not None
|
574
|
-
assert motor_control_panel_absolute.config == CONFIG_DEFAULT
|
575
|
-
|
576
|
-
|
577
|
-
@pytest.fixture(scope="function")
|
578
|
-
def motor_control_panel_relative(qtbot, mocked_client):
|
579
|
-
widget = MotorControlPanelRelative(config=CONFIG_DEFAULT, client=mocked_client)
|
580
|
-
qtbot.addWidget(widget)
|
581
|
-
qtbot.waitExposed(widget)
|
582
|
-
yield widget
|
583
|
-
|
584
|
-
|
585
|
-
def test_motor_control_panel_relative_initialization(motor_control_panel_relative):
|
586
|
-
assert isinstance(motor_control_panel_relative, MotorControlPanelRelative)
|
587
|
-
assert motor_control_panel_relative.client is not None
|
588
|
-
assert motor_control_panel_relative.config == CONFIG_DEFAULT
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|