"""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