Feature: Digital pet

This commit is contained in:
Sami
2026-06-14 15:18:56 -04:00
parent dac4b88b94
commit d5db0d0e8e
19 changed files with 1612 additions and 968 deletions
+79
View File
@@ -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"