Files
AareDAQ/tests/unit/gui/test_wheel_value_guard.py
T
duan_jandClaude Fable 5.1 90f653386a
CI / lint (pull_request) Successful in 1m9s
CI / test (3.12) (pull_request) Successful in 1m3s
CI / test (3.14) (pull_request) Successful in 1m11s
CI / test-with-beamline-plugins (pxi_bec) (pull_request) Successful in 1m14s
CI / test-with-beamline-plugins (pxii_bec) (pull_request) Successful in 1m16s
CI / test-with-coverage (pull_request) Successful in 1m40s
CI / coverage-analysis (pull_request) Successful in 3s
CI / test (3.13) (pull_request) Successful in 58s
CI / test-with-beamline-plugins (pxiii_bec) (pull_request) Successful in 1m14s
Docs build and publish / docker (push) Successful in 14s
CI / lint (push) Successful in 35s
CI / test (3.12) (push) Canceled after 42s
CI / test (3.13) (push) Canceled after 37s
CI / test (3.14) (push) Canceled after 37s
CI / test-with-beamline-plugins (pxi_bec) (push) Canceled after 32s
CI / test-with-beamline-plugins (pxii_bec) (push) Canceled after 32s
CI / test-with-beamline-plugins (pxiii_bec) (push) Canceled after 27s
CI / test-with-coverage (push) Canceled after 27s
CI / coverage-analysis (push) Canceled after 0s
Build and Publish / release (push) Successful in 26s
fix(gui): app-level event filters tolerate PySide's stray QWidgetItem
CI (3.12, PR 232) failed test_font_zoom_keeps_frozen_column_aligned_and_reautosizes
with a pytest-qt CALL ERROR: PySide 6.9 handed both app-level filters a
QWidgetItem instead of a QEvent during layout teardown, and event.type()
raised. The wheel guard now keys on isinstance(event, QWheelEvent) and
returns False itself instead of super().eventFilter() (which type-checks
its arguments and would raise the same way); the cursor filter ignores
anything that is not a QEvent. Regression test for each.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 21:12:55 +02:00

91 lines
2.4 KiB
Python

"""The wheel guard is motor protection: a bare wheel over a value widget must
never change the value (it scrolls the page instead); adjusting requires the
deliberate right-button + wheel gesture."""
import pytest
from PySide6.QtCore import QPoint, QPointF, Qt
from PySide6.QtGui import QWheelEvent
from PySide6.QtWidgets import (
QApplication,
QScrollArea,
QSlider,
QSpinBox,
QVBoxLayout,
QWidget,
QWidgetItem,
)
from aare.gui.widgets.wheel_value_guard import WheelValueGuard
@pytest.fixture
def guard(qapp):
guard = WheelValueGuard()
qapp.installEventFilter(guard)
yield guard
qapp.removeEventFilter(guard)
def _wheel(buttons):
return QWheelEvent(
QPointF(5, 5),
QPointF(5, 5),
QPoint(0, 0),
QPoint(0, 120),
buttons,
Qt.KeyboardModifier.NoModifier,
Qt.ScrollPhase.NoScrollPhase,
False,
)
def test_bare_wheel_does_not_adjust(guard, qtbot):
slider = QSlider(Qt.Orientation.Horizontal)
qtbot.addWidget(slider)
slider.setRange(0, 100)
slider.setValue(50)
QApplication.sendEvent(slider, _wheel(Qt.MouseButton.NoButton))
assert slider.value() == 50
def test_right_button_wheel_adjusts(guard, qtbot):
slider = QSlider(Qt.Orientation.Horizontal)
qtbot.addWidget(slider)
slider.setRange(0, 100)
slider.setValue(50)
QApplication.sendEvent(slider, _wheel(Qt.MouseButton.RightButton))
assert slider.value() != 50
def test_bare_wheel_scrolls_the_enclosing_area(guard, qtbot):
area = QScrollArea()
qtbot.addWidget(area)
content = QWidget()
layout = QVBoxLayout(content)
spin = QSpinBox()
spin.setRange(0, 100)
spin.setValue(50)
layout.addWidget(spin)
# Tall filler so the area has something to scroll.
filler = QWidget()
filler.setFixedHeight(2000)
layout.addWidget(filler)
area.setWidget(content)
area.resize(200, 200)
area.show()
bar = area.verticalScrollBar()
bar.setValue(bar.maximum() // 2)
before = bar.value()
QApplication.sendEvent(spin, _wheel(Qt.MouseButton.NoButton))
assert spin.value() == 50
assert bar.value() != before
def test_a_non_event_argument_is_ignored(guard, qtbot):
# PySide 6.9 can hand an app-level filter a QWidgetItem instead of a
# QEvent during layout teardown; raising there fails a random test.
widget = QWidget()
qtbot.addWidget(widget)
assert guard.eventFilter(widget, QWidgetItem(widget)) is False