from clanker_soul import Score from app.autonomy import choose_soothe, maybe_self_soothe, SOOTHE_COOLDOWN def test_no_soothe_when_content(): # neutral/positive mood, full needs → no self-soothe assert choose_soothe([160, 130, 130, 0, 120, 160, 140], {"energy": 100}) is None def test_low_worth_picks_mirror(): assert choose_soothe([130, 130, 130, 0, 120, 90, 140], {"energy": 100}) == "mirror" def test_low_valence_picks_teddy(): assert choose_soothe([95, 130, 130, 0, 120, 130, 140], {"energy": 100}) == "teddy" class _FakeBridge: def __init__(self, mood): self._mood = mood self._meta = {} self.ingested = [] def mood(self): return self._mood def get_meta(self, k, d=""): return self._meta.get(k, d) def set_meta(self, k, v): self._meta[k] = str(v) def ingest(self, s): self.ingested.append(s) def test_self_soothe_fires_then_cools_down(): b = _FakeBridge([90, 130, 130, 0, 120, 100, 140]) # low V and W r1 = maybe_self_soothe(b, {"energy": 100}, now=1000.0) assert r1 and r1["item"] in ("teddy", "mirror") assert len(b.ingested) == 1 # applied a gentle lift # immediately again → on cooldown, no fire assert maybe_self_soothe(b, {"energy": 100}, now=1000.0 + 5) is None assert len(b.ingested) == 1 # after cooldown → fires again r2 = maybe_self_soothe(b, {"energy": 100}, now=1000.0 + SOOTHE_COOLDOWN + 1) assert r2 and len(b.ingested) == 2 def test_self_soothe_effect_is_gentle(): # self-administered teddy is milder than the user-triggered teddy toy from app.toys import toy_score from app.autonomy import _SOOTHE_SCORE assert _SOOTHE_SCORE["teddy"].w < toy_score("teddy").w