Feature: Digital pet
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from digital_pet_import import load_module
|
||||
|
||||
state_mod = load_module("state.py", "digital_pet_state")
|
||||
PetState = state_mod.PetState
|
||||
apply_event = state_mod.apply_event
|
||||
|
||||
|
||||
def at(second: int = 0):
|
||||
return datetime(2026, 1, 1, 12, 0, second, tzinfo=timezone.utc)
|
||||
|
||||
|
||||
def test_click_summons_hidden_pet_deterministically():
|
||||
state = PetState()
|
||||
|
||||
next_state = apply_event("click", state=state, now=at())
|
||||
|
||||
assert next_state.enabled is True
|
||||
assert next_state.mode == "idle"
|
||||
assert next_state.last_mode == "hidden"
|
||||
assert next_state.message == "Station companion online."
|
||||
assert next_state.revision == 1
|
||||
|
||||
|
||||
def test_hover_hold_sends_active_pet_to_sleep():
|
||||
state = apply_event("summon", state=PetState(), now=at())
|
||||
|
||||
next_state = apply_event("hover_hold", state=state, now=at(1))
|
||||
|
||||
assert next_state.enabled is True
|
||||
assert next_state.mode == "sleeping"
|
||||
assert next_state.last_mode == "idle"
|
||||
assert next_state.message == "Going quiet."
|
||||
|
||||
|
||||
def test_sleeping_click_wakes_then_wake_complete_returns_idle():
|
||||
state = apply_event("summon", state=PetState(), now=at())
|
||||
state = apply_event("hover_hold", state=state, now=at(1))
|
||||
|
||||
waking = apply_event("click", state=state, now=at(2))
|
||||
assert waking.mode == "waking"
|
||||
assert waking.message == "Back online."
|
||||
|
||||
idle = apply_event("wake_complete", state=waking, now=at(3))
|
||||
assert idle.mode == "idle"
|
||||
assert idle.message is None
|
||||
|
||||
|
||||
def test_reaction_and_prompt_complete_return_to_idle():
|
||||
state = apply_event("summon", state=PetState(), now=at())
|
||||
reacting = apply_event("click", state=state, now=at(1))
|
||||
assert reacting.mode == "reacting"
|
||||
|
||||
idle = apply_event("reaction_complete", state=reacting, now=at(2))
|
||||
assert idle.mode == "idle"
|
||||
|
||||
idle.prompt_cooldown_until = None
|
||||
prompting = apply_event("prompt_tick", state=idle, now=at(3))
|
||||
assert prompting.mode == "prompting"
|
||||
|
||||
completed = apply_event("prompt_complete", state=prompting, now=at(4))
|
||||
assert completed.mode == "idle"
|
||||
|
||||
|
||||
def test_hidden_and_sleeping_ignore_prompt_and_reacting_completion():
|
||||
hidden = PetState()
|
||||
after_prompt = apply_event("prompt_tick", state=hidden, now=at())
|
||||
after_reaction_complete = apply_event("reaction_complete", state=after_prompt, now=at(1))
|
||||
|
||||
assert after_prompt.mode == "hidden"
|
||||
assert after_reaction_complete.mode == "hidden"
|
||||
|
||||
sleeping = apply_event("sleep", state=PetState(enabled=True, mode="idle"), now=at(2))
|
||||
still_sleeping = apply_event("prompt_tick", state=sleeping, now=at(3))
|
||||
|
||||
assert still_sleeping.mode == "sleeping"
|
||||
Reference in New Issue
Block a user