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
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>
95 lines
3.0 KiB
Python
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()
|