Spaces:
Sleeping
Sleeping
File size: 2,937 Bytes
bb3fbf9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | """
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"])
|