"""Autonomous wandering. Needs a QApplication, so run with QT_QPA_PLATFORM=offscreen (same as test_controller.py).""" import sys from pathlib import Path import pytest sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from PySide6.QtWidgets import QApplication from bolt_pet import config from bolt_pet.state import PetState from bolt_pet.ui.pet_window import PetWindow @pytest.fixture(scope="module") def qt_app(): app = QApplication.instance() or QApplication([]) yield app @pytest.fixture def pet(qt_app): window = PetWindow() window.set_wander_enabled(True) yield window window.close() def _walk_until_done(pet, max_ticks=2000): for _ in range(max_ticks): pet._wander_tick() if pet._wander_target is None: return True return False def test_wanders_when_idle_and_reaches_its_target(pet, monkeypatch): # Snapping is tested separately; here it would tug the pet off its target # the moment it arrives near an edge. monkeypatch.setattr(config, "PET_EDGE_SNAP", False) pet.wander_now() pet._wander_tick() target = pet._wander_target if target is None: pytest.skip("no usable screen geometry for a stroll on this host") assert _walk_until_done(pet), "pet never reached its wander target" assert pet.pos() == target def test_stays_put_while_talking(pet): pet.set_state(PetState.TALKING) start = pet.pos() pet.wander_now() for _ in range(50): pet._wander_tick() assert pet.pos() == start assert pet._wander_target is None def test_stays_put_while_bubble_is_up(pet): pet.say("hello there", duration_ms=60000) start = pet.pos() pet.wander_now() for _ in range(50): pet._wander_tick() assert pet.pos() == start def test_disabling_wander_stops_movement(pet): pet.set_wander_enabled(False) start = pet.pos() pet.wander_now() for _ in range(50): pet._wander_tick() assert pet.pos() == start def test_stroll_stays_on_screen(pet): geo = pet._screen_geometry() if geo is None: pytest.skip("no usable screen geometry on this host") for _ in range(10): pet.wander_now() pet._wander_tick() assert _walk_until_done(pet) assert geo.contains(pet.geometry())