LovecaSim / engine /tests /mechanics /test_player_state_slots.py
trioskosmos's picture
Upload folder using huggingface_hub
bb3fbf9 verified
"""
Test to ensure PlayerState slots are complete.
This test prevents the class of bugs where dynamic attributes are lost during state copying
because they aren't declared in __slots__.
"""
import numpy as np
import pytest
from engine.game.player_state import PlayerState
class TestPlayerStateSlotCompleteness:
"""Verify all attributes are properly declared in __slots__."""
def test_no_dynamic_attributes_after_init(self):
"""PlayerState should have no __dict__ (pure __slots__ class)."""
ps = PlayerState(0)
# __slots__ classes should not have __dict__ unless explicitly added
# However, if parent class doesn't use __slots__, __dict__ may exist but be empty
if hasattr(ps, "__dict__"):
assert len(ps.__dict__) == 0, f"PlayerState has dynamic attributes not in __slots__: {ps.__dict__}"
def test_all_slots_have_default_values(self):
"""All slots should be initialized in __init__."""
ps = PlayerState(0)
for slot in PlayerState.__slots__:
assert hasattr(ps, slot), f"Slot '{slot}' not initialized in __init__"
def test_copy_preserves_all_slots(self):
"""copy() should preserve all slot values."""
ps1 = PlayerState(0)
# Modify some values to non-default
ps1.hand = [1, 2, 3]
ps1.tapped_members[0] = True
ps1.rested_members[1] = True
ps1.performance_abilities_processed = True
ps1.revealed_hand = True
ps1.deck_refreshed_this_turn = True
ps1.baton_touch_count = 5
# Copy
ps2 = ps1.copy()
# Verify all values copied
assert ps2.hand == [1, 2, 3]
assert ps2.tapped_members[0] == True
assert ps2.rested_members[1] == True
assert ps2.performance_abilities_processed == True
assert ps2.revealed_hand == True
assert ps2.deck_refreshed_this_turn == True
assert ps2.baton_touch_count == 5
# Verify copies are independent (deep copy for mutable types)
ps2.hand.append(4)
assert ps1.hand == [1, 2, 3], "hand should be deep copied"
ps2.tapped_members[0] = False
assert ps1.tapped_members[0] == True, "numpy arrays should be deep copied"
def test_reset_clears_all_mutable_state(self):
"""_reset() should restore all slots to defaults."""
ps = PlayerState(0)
# Modify state
ps.hand = [1, 2, 3]
ps.performance_abilities_processed = True
ps.revealed_hand = True
ps.rested_members[0] = True
# Reset
ps._reset(0)
# Verify reset
assert ps.hand == []
assert ps.performance_abilities_processed == False
assert ps.revealed_hand == False
assert not np.any(ps.rested_members)
if __name__ == "__main__":
pytest.main([__file__, "-v"])