"""Win at three catches; lose when the bench runs out of patience.""" import config from witnessbox.contradictions import CatchResult from witnessbox.state import GameState, Phase from witnessbox.witness import PLANTED_LIES def _catch_for(lie): return CatchResult(lie=lie, score=1.0, matched_groups={"x": "y"}, is_catch=True) def test_win_at_three_catches(): gs = GameState() gs.begin() for lie in PLANTED_LIES: ev = gs.apply_turn(examiner_text="q", witness_text="a", stance_tier="NEUTRAL", catch=_catch_for(lie)) assert gs.phase == Phase.WON and ev.won and gs.catches == 3 def test_witness_tier_escalates_with_catches(): gs = GameState() gs.begin() assert gs.witness_tier() == "composed" gs.apply_turn(examiner_text="q", witness_text="a", stance_tier="NEUTRAL", catch=_catch_for(PLANTED_LIES[0])) assert gs.witness_tier() == "rattled" def test_lose_when_credibility_hits_zero(): gs = GameState() gs.begin() ev = None # enough whiffs to drain credibility (no catch each turn) for _ in range(config.CREDIBILITY_START // abs(config.CREDIBILITY_ON_WHIFF) + 1): ev = gs.apply_turn(examiner_text="q", witness_text="a", stance_tier="NEUTRAL", catch=None) if gs.is_over: break assert gs.phase == Phase.LOST and ev.lost def test_status_shape(): gs = GameState() s = gs.status() assert s["catches_to_win"] == config.CATCHES_TO_WIN assert 0 <= s["credibility"] <= 100 and 0 <= s["composure"] <= 100