"""Tests for the Mo1BraggAngle class.""" import threading from unittest import mock import ophyd import pytest from ophyd_devices.tests.utils import MockPV, patch_dual_pvs from debye_bec.devices.mo1_bragg.mo1_bragg_angle import Mo1BraggAngle from debye_bec.devices.mo1_bragg.mo1_bragg_devices import Mo1BraggStoppedError # pylint: disable=protected-access @pytest.fixture(scope="function") def mock_bragg() -> Mo1BraggAngle: """Fixture for the Mo1BraggAngle device.""" name = "bragg" prefix = "X01DA-OP-MO1:BRAGG:" with mock.patch.object(ophyd, "cl") as mock_cl: mock_cl.get_pv = MockPV mock_cl.thread_class = threading.Thread dev = Mo1BraggAngle(name=name, prefix=prefix) patch_dual_pvs(dev) yield dev def test_mo1_bragg_angle_init(mock_bragg): """Test the initialization of the Mo1BraggAngle device.""" assert mock_bragg.name == "bragg" assert mock_bragg.prefix == "X01DA-OP-MO1:BRAGG:" assert isinstance(mock_bragg.readback, ophyd.EpicsSignalRO) assert isinstance(mock_bragg.setpoint, ophyd.EpicsSignalWithRBV) assert isinstance(mock_bragg.low_lim, ophyd.EpicsSignalRO) assert isinstance(mock_bragg.high_lim, ophyd.EpicsSignalRO) def test_mo1_bragg_angle_egu(mock_bragg): """Test the engineering unit of the Mo1BraggAngle device.""" assert mock_bragg.egu == "deg" def test_mo1_bragg_angle_limits(mock_bragg): """Test the limits of the Mo1BraggAngle device.""" mock_bragg.low_lim._read_pv.mock_data = -10 mock_bragg.high_lim._read_pv.mock_data = 10 assert mock_bragg.limits == (-10, 10) def test_mo1_bragg_angle_move(mock_bragg): """Test the move method of the Mo1BraggAngle device.""" mock_bragg.setpoint.put(0) mock_bragg.readback._read_pv.mock_data = 0 # EpicsSignalRO # Change PV for motor is moving before starting the move mock_bragg.motor_is_moving._read_pv.mock_data = 0 # EpicsSignalRO status = mock_bragg.move(5) assert status.done is False # Check setpoint is set correctly assert mock_bragg.setpoint.get() == 5 # Update the motor is moving PV to simulate that the move is done mock_bragg.motor_is_moving._read_pv.mock_data = 1 assert mock_bragg.motor_is_moving.get() == 1 status.wait(timeout=5) # If the status does not resolve after 5 seconds, something is wrong assert status.done is True def test_mo1_bragg_angle_stop(mock_bragg): """Test the stop method of the Mo1BraggAngle device.""" assert mock_bragg.stopped is False mock_bragg.stop() assert mock_bragg.stopped is True status = mock_bragg.move(5) assert status.done is False # stopped should be resetted assert mock_bragg.stopped is False with pytest.raises(Mo1BraggStoppedError): mock_bragg.stop() status.wait(timeout=5) # This should raise before due to stop() call