import pytest from primitives import Effect, get_primitive, primitive_allowed_for_school, primitive_ids, render_effect, school_bias, school_primitives # Verify the fixed primitive vocabulary stays complete. def test_primitive_ids_are_the_locked_thirteen() -> None: assert primitive_ids() == ( "deal", "burn", "bomb", "block", "ward", "weak", "draw", "energy", "initiative", "multi_hit", "vulnerable", "conditional", "scaling", ) # Verify school draft pools match the README. def test_school_primitives_match_spec() -> None: assert school_primitives("fire") == ("deal", "burn", "bomb", "scaling", "draw", "energy", "block", "conditional") assert school_primitives("ice") == ("deal", "initiative", "vulnerable", "multi_hit", "conditional", "draw", "energy", "block") assert school_primitives("earth") == ("deal", "ward", "block", "weak", "scaling", "conditional", "draw", "energy") assert primitive_allowed_for_school("deal", "fire") assert primitive_allowed_for_school("deal", "ice") assert not primitive_allowed_for_school("bomb", "ice") # Verify school bias explains generation weights. def test_school_bias() -> None: assert "immediate Deal" in school_bias("fire") assert "shield charge" in school_bias("earth") # Verify primitive lookup returns the stored schema. def test_get_primitive_returns_spec() -> None: primitive = get_primitive("ward") assert primitive.name == "Ward" assert primitive.category == "defense" @pytest.mark.parametrize( ("effect", "text"), ( (Effect("deal", amount=4), "Deal 4 damage."), (Effect("burn", amount=2, duration=3), "Burn 2 damage for 3 turns."), (Effect("bomb", amount=9, delay=3), "Bomb: deal 9 damage in 3 turns."), (Effect("block", amount=6), "Gain 6 block until your next turn."), (Effect("ward", amount=2), "Gain 2 ward."), (Effect("weak", amount=2), "Opponent deals 2 less damage until your next turn."), (Effect("draw", amount=1), "Draw 1 card."), (Effect("draw", amount=2), "Draw 2 cards."), (Effect("energy", amount=1), "Gain 1 energy this turn."), (Effect("initiative"), "Opponent acts second next round."), (Effect("multi_hit", amount=2, hits=3), "Deal 2 damage 3 times."), (Effect("vulnerable", amount=1, duration=2), "Opponent takes 1 more damage for 2 turns."), (Effect("conditional", amount=6), "Deal up to 6 damage based on opponent's missing HP."), (Effect("scaling", amount=2), "Deal 2 damage plus cards played this turn."), (Effect("scaling", amount=2, condition="shield_charge"), "Deal 2 damage plus your banked shield charge, then empty it."), ), ) # Verify every effect renders to fixed parseable text. def test_render_effect(effect: Effect, text: str) -> None: assert render_effect(effect) == text