Files
AareDAQ/tests/unit/gui/test_motor_move_group.py
T
duan_jandClaude Fable 5 aa6c226103
CI / lint (push) Skipped
CI / test (3.11) (push) Skipped
CI / test (3.12) (push) Skipped
CI / test (3.13) (push) Skipped
CI / test-with-beamline-plugins (pxi_bec) (push) Skipped
CI / test-with-beamline-plugins (pxii_bec) (push) Skipped
CI / test-with-beamline-plugins (pxiii_bec) (push) Skipped
CI / lint (pull_request) Successful in 1m17s
CI / test (3.11) (pull_request) Successful in 1m44s
CI / test (3.12) (pull_request) Successful in 1m41s
CI / test (3.13) (pull_request) Successful in 2m1s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m57s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 2m0s
CI / test-with-coverage (pull_request) Successful in 2m26s
CI / coverage-analysis (pull_request) Successful in 3s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Failing after 18m13s
test: cover every changed line in the branch diff
Diff coverage vs main now 100 percent from the gui suite alone:
non-staff locked banners and both gated-tab popups, remote-close
bookkeeping in update_daq_status, smargon staged moves, camera More
link and Alt-wheel axis fallback, number box relimits, energy row
emit, and the gui.main() banner/graceful-exit path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-14 09:20:44 +02:00

95 lines
3.0 KiB
Python

"""MotorMoveGroup is motor protection UX: typing must never start a move —
targets are staged (orange), sent only by the Move button (green), and the
box returns to neutral when the motor actually arrives."""
import pytest
from PySide6.QtCore import Qt
from aare.gui.widgets.motor_move_group import MotorMoveGroup
from aare.gui.widgets.number_line_edit import NumberLineEdit
@pytest.fixture
def chi(qtbot):
box = NumberLineEdit(-0.2, 40, decimals=1)
qtbot.addWidget(box)
group = MotorMoveGroup()
group.add_box("chi", box)
return group, box
def _type(qtbot, box, text):
box.clear()
qtbot.keyClicks(box, text)
def test_stage_apply_settle(chi, qtbot):
group, box = chi
sent = []
group.applied.connect(sent.append)
_type(qtbot, box, "25.0")
assert box.property("movestate") == "pending"
assert group.button.isEnabled()
assert not sent # typing (even Enter) must not move the motor
group.button.click()
assert sent == [{"chi": 25.0}]
assert box.property("movestate") == "moving"
assert not group.button.isEnabled()
group.update_actual("chi", 10.0) # still travelling
assert box.property("movestate") == "moving"
assert box.value == 25.0 # box keeps showing the target
group.update_actual("chi", 25.05) # within tol -> arrived
assert box.property("movestate") == ""
group.update_actual("chi", 3.0) # neutral boxes track the actual again
assert box.value == 3.0
def test_edit_back_to_current_cancels_pending(chi, qtbot):
group, box = chi
_type(qtbot, box, "5.0")
assert group.button.isEnabled()
_type(qtbot, box, "0.0") # back to the actual position
assert box.property("movestate") == ""
assert not group.button.isEnabled()
def test_over_max_is_invalid_and_never_sent(chi, qtbot):
group, box = chi
sent = []
group.applied.connect(sent.append)
_type(qtbot, box, "500")
assert box.property("invalid") is True # red via existing validator path
group.button.click()
assert not sent # out-of-range target is never applied
assert box.property("movestate") == "pending"
def test_incomplete_entry_stays_pending(chi, qtbot):
_group, box = chi
_type(qtbot, box, "-") # not a number (yet): no tips, no crash
assert box.property("movestate") == "pending"
# Enter on the incomplete text must be swallowed just as quietly
qtbot.keyClick(box, Qt.Key.Key_Return)
assert box.property("movestate") == "pending"
def test_below_min_enter_hints_but_never_sends(chi, qtbot):
group, box = chi
sent = []
group.applied.connect(sent.append)
_type(qtbot, box, "-5") # below the -0.2 bottom
qtbot.keyClick(box, Qt.Key.Key_Return) # triggers the min-value tooltip path
assert not sent # Enter must never start a move
def test_update_limits_reranges_box(chi, qtbot):
_group, box = chi
box.update_limits(-1.0, 50.0)
assert box.range_validator.bottom() == -1.0
assert box.range_validator.top() == 50.0
assert "50" in box.toolTip()