80bef6f524
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
90 lines
2.3 KiB
Python
90 lines
2.3 KiB
Python
"""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())
|