CI / lint (pull_request) Successful in 53s
CI / test (3.11) (pull_request) Successful in 58s
CI / test (3.13) (pull_request) Successful in 59s
CI / test (3.12) (pull_request) Successful in 1m3s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m12s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m14s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m18s
CI / test-with-coverage (pull_request) Successful in 1m29s
CI / coverage-analysis (pull_request) Successful in 3s
CI / lint (push) Successful in 34s
Docs build and publish / docker (push) Successful in 17s
CI / test (3.11) (push) Canceled after 37s
CI / test (3.12) (push) Canceled after 36s
CI / test (3.13) (push) Canceled after 32s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 31s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 27s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 26s
CI / test-with-coverage (push) Canceled after 22s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 20s
test: update test...
90 lines
3.6 KiB
Python
90 lines
3.6 KiB
Python
import pytest
|
|
|
|
from aare.gui.panels.monochromator_panel import MonochromatorPanel
|
|
|
|
|
|
def test_current_energy_readout(qtbot, daq_status_factory):
|
|
panel = MonochromatorPanel()
|
|
qtbot.addWidget(panel)
|
|
|
|
status = daq_status_factory()
|
|
panel.update_daq_status(status)
|
|
assert panel.current_energy_label.text() == "12.000 keV / 1.0332 Å"
|
|
|
|
|
|
def test_fast_shutter_row(qtbot, daq_status_factory):
|
|
panel = MonochromatorPanel()
|
|
qtbot.addWidget(panel)
|
|
|
|
# Placeholder until the first DAQ tick.
|
|
assert panel.shutter_status_label.text() == "Fast Shutter: —"
|
|
|
|
status = daq_status_factory()
|
|
panel.update_daq_status(status)
|
|
assert "Closed" in panel.shutter_status_label.text()
|
|
|
|
status.bl = status.bl.model_copy(update={"shutter_open": True})
|
|
panel.update_daq_status(status)
|
|
assert "Open" in panel.shutter_status_label.text()
|
|
|
|
# Buttons relay to the same DAQ signals the status-bar menu uses.
|
|
with qtbot.waitSignal(panel.open_shutter, timeout=1000):
|
|
panel.open_shutter_button.click()
|
|
with qtbot.waitSignal(panel.close_shutter, timeout=1000):
|
|
panel.close_shutter_button.click()
|
|
|
|
|
|
def test_energy_spin_placeholder_limits(qtbot):
|
|
# 4-20 keV is a placeholder pending Beamline Scientist confirmation; the
|
|
# tooltip must say so because nothing downstream validates the request.
|
|
panel = MonochromatorPanel()
|
|
qtbot.addWidget(panel)
|
|
assert panel.energy_spin.minimum() == 4.0
|
|
assert panel.energy_spin.maximum() == 20.0
|
|
assert "Beamline Scientist" in panel.energy_spin.toolTip()
|
|
|
|
|
|
def test_energy_spin_motor_move_semantics(qtbot, daq_status_factory):
|
|
# Same protection UX as MotorMoveGroup: the spin stages, only the button
|
|
# sends, and the color walks neutral -> pending -> moving -> neutral.
|
|
panel = MonochromatorPanel()
|
|
qtbot.addWidget(panel)
|
|
box = panel.energy_spin # movestate sits on the spin, not its inner edit
|
|
sent = []
|
|
panel.change_energy.connect(sent.append)
|
|
assert not panel.change_energy_button.isEnabled() # nothing staged yet
|
|
|
|
status = daq_status_factory()
|
|
panel.update_daq_status(status) # readback 12.0 keV syncs the neutral spin
|
|
assert panel.energy_spin.value() == 12.0
|
|
assert not box.property("movestate")
|
|
|
|
panel.energy_spin.setValue(12.4) # user staging
|
|
assert box.property("movestate") == "pending"
|
|
assert panel.change_energy_button.isEnabled()
|
|
|
|
panel.energy_spin.setValue(12.0) # back to the readback cancels
|
|
assert box.property("movestate") == ""
|
|
assert not panel.change_energy_button.isEnabled()
|
|
|
|
panel.energy_spin.setValue(12.4)
|
|
panel.change_energy_button.click()
|
|
assert sent and sent[-1] == pytest.approx(12400.0) # keV -> eV on emit
|
|
assert box.property("movestate") == "moving"
|
|
assert not panel.change_energy_button.isEnabled()
|
|
|
|
# travelling: the spin keeps showing the target, not the readback
|
|
status.diffraction = status.diffraction.model_copy(update={"energy_keV": 12.1})
|
|
panel.update_daq_status(status)
|
|
assert panel.energy_spin.value() == 12.4
|
|
assert box.property("movestate") == "moving"
|
|
|
|
# arrival within tol returns to neutral and readback tracking resumes
|
|
# 12.3995 sits safely inside tol (the 12.399 boundary loses to float
|
|
# error: 12.4-12.399 > 0.001); the spin then rounds to its 3 decimals,
|
|
# hence the loose abs window on the value check.
|
|
status.diffraction = status.diffraction.model_copy(update={"energy_keV": 12.3995})
|
|
panel.update_daq_status(status)
|
|
assert box.property("movestate") == ""
|
|
assert panel.energy_spin.value() == pytest.approx(12.3995, abs=1e-3)
|