0
0
mirror of https://github.com/bec-project/bec_widgets.git synced 2025-07-13 19:21:50 +02:00
Files
bec_widgets/tests/unit_tests/test_positioner_box.py

161 lines
6.1 KiB
Python

from unittest import mock
import pytest
from bec_lib.endpoints import MessageEndpoints
from bec_lib.messages import ScanQueueMessage
from qtpy.QtCore import Qt, QTimer
from qtpy.QtGui import QValidator
from qtpy.QtWidgets import QPushButton
from bec_widgets.widgets.control.device_control.positioner_box.positioner_box import PositionerBox
from bec_widgets.widgets.control.device_control.positioner_box.positioner_control_line import (
PositionerControlLine,
)
from bec_widgets.widgets.control.device_input.device_line_edit.device_line_edit import (
DeviceLineEdit,
)
from .client_mocks import mocked_client
from .conftest import create_widget
@pytest.fixture
def positioner_box(qtbot, mocked_client):
"""Fixture for PositionerBox widget"""
with mock.patch(
"bec_widgets.widgets.control.device_control.positioner_box.positioner_box.uuid.uuid4"
) as mock_uuid:
mock_uuid.return_value = "fake_uuid"
with mock.patch(
"bec_widgets.widgets.control.device_control.positioner_box.positioner_box.PositionerBox._check_device_is_valid",
return_value=True,
):
db = create_widget(qtbot, PositionerBox, device="samx", client=mocked_client)
yield db
def test_positioner_box(positioner_box):
"""Test init of positioner box"""
assert positioner_box.device == "samx"
data = positioner_box.dev["samx"].read()
# Avoid check for Positioner class from BEC in _init_device
setpoint_text = positioner_box.ui.setpoint.text()
# check that the setpoint is taken correctly after init
assert float(setpoint_text) == data["samx_setpoint"]["value"]
# check that the precision is taken correctly after isnit
precision = positioner_box.dev["samx"].precision
assert setpoint_text == f"{data['samx_setpoint']['value']:.{precision}f}"
# check that the step size is set according to the device precision
assert positioner_box.ui.step_size.value() == 10**-precision * 10
def test_positioner_box_update_limits(positioner_box):
"""Test update of limits"""
positioner_box._limits = None
positioner_box.update_limits([0, 10])
assert positioner_box._limits == [0, 10]
assert positioner_box.setpoint_validator.bottom() == 0
assert positioner_box.setpoint_validator.top() == 10
assert positioner_box.setpoint_validator.validate("100", 0) == (
QValidator.State.Intermediate,
"100",
0,
)
positioner_box.update_limits(None)
assert positioner_box._limits is None
assert positioner_box.setpoint_validator.validate("100", 0) == (
QValidator.State.Acceptable,
"100",
0,
)
def test_positioner_box_on_stop(positioner_box):
"""Test on stop button"""
with mock.patch.object(positioner_box.client.connector, "send") as mock_send:
positioner_box.on_stop()
params = {"device": "samx", "rpc_id": "fake_uuid", "func": "stop", "args": [], "kwargs": {}}
msg = ScanQueueMessage(
scan_type="device_rpc",
parameter=params,
queue="emergency",
metadata={"RID": "fake_uuid", "response": False},
)
mock_send.assert_called_once_with(MessageEndpoints.scan_queue_request(), msg)
def test_positioner_box_setpoint_change(positioner_box):
"""Test positioner box setpoint change"""
with mock.patch.object(positioner_box.dev["samx"], "move") as mock_move:
positioner_box.ui.setpoint.setText("100")
positioner_box.on_setpoint_change()
mock_move.assert_called_once_with(100, relative=False)
def test_positioner_box_on_tweak_right(positioner_box):
"""Test tweak right button"""
with mock.patch.object(positioner_box.dev["samx"], "move") as mock_move:
positioner_box.ui.step_size.setValue(0.1)
positioner_box.on_tweak_right()
mock_move.assert_called_once_with(0.1, relative=True)
def test_positioner_box_on_tweak_left(positioner_box):
"""Test tweak left button"""
with mock.patch.object(positioner_box.dev["samx"], "move") as mock_move:
positioner_box.ui.step_size.setValue(0.1)
positioner_box.on_tweak_left()
mock_move.assert_called_once_with(-0.1, relative=True)
def test_positioner_box_setpoint_out_of_range(positioner_box):
"""Test setpoint out of range"""
positioner_box.update_limits([0, 10])
positioner_box.ui.setpoint.setText("100")
positioner_box.on_setpoint_change()
assert positioner_box.ui.setpoint.text() == "100"
assert positioner_box.ui.setpoint.hasAcceptableInput() == False
def test_positioner_control_line(qtbot, mocked_client):
"""Test PositionerControlLine.
Inherits from PositionerBox, but the layout is changed. Check dimensions only
"""
with mock.patch(
"bec_widgets.widgets.control.device_control.positioner_box.positioner_box.uuid.uuid4"
) as mock_uuid:
mock_uuid.return_value = "fake_uuid"
with mock.patch(
"bec_widgets.widgets.control.device_control.positioner_box.positioner_box.PositionerBox._check_device_is_valid",
return_value=True,
):
db = PositionerControlLine(device="samx", client=mocked_client)
qtbot.addWidget(db)
assert db.ui.device_box.height() == 60
assert db.ui.device_box.width() == 600
def test_positioner_box_open_dialog_selection(qtbot, positioner_box):
"""Test open positioner edit"""
# Use a timer to close the dialog after it opens
def close_dialog():
# pylint: disable=protected-access
assert positioner_box._dialog is not None
qtbot.waitUntil(lambda: positioner_box._dialog.isVisible() is True, timeout=1000)
line_edit = positioner_box._dialog.findChild(DeviceLineEdit)
line_edit.setText("samy")
close_button = positioner_box._dialog.findChild(QPushButton)
assert close_button.text() == "Close"
qtbot.mouseClick(close_button, Qt.LeftButton)
# Execute the timer after the dialog opens to close it
QTimer.singleShot(100, close_dialog)
qtbot.mouseClick(positioner_box.ui.tool_button, Qt.LeftButton)
assert positioner_box.device == "samy"