Spaces:
Sleeping
Sleeping
File size: 2,104 Bytes
1c66cf8 | 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 | """Regression test for feature_cache content-based keying.
Ensures cache doesn't collide when CPython reuses id() after GC.
"""
from __future__ import annotations
from werewolftown.features.card_value import card_cluster_gain
def test_cache_by_content_not_id(make_state):
"""Cache must key on state content, not id(). Different states must get different results."""
state_a = make_state(
plots=frozenset({4, 5, 6}),
built_on={4: "Happy", 5: "Happy"},
shops=(),
)
state_b = make_state(
plots=frozenset({4, 5, 7}),
built_on={4: "Happy", 5: "Happy"},
shops=("Happy",),
)
gain_a = card_cluster_gain(state_a, "Happy")
gain_b = card_cluster_gain(state_b, "Happy")
# state_a: empty 6 adjacent to Happy 2-cluster, 0 cards → gain=20000
# state_b: empty 7 not adjacent, 1 card already → gain=0
assert gain_a != gain_b, "Cache polluted: different states returned same result"
assert gain_a == 20000
assert gain_b == 0
def test_cache_same_state_reuses(make_state):
"""Same state instance called twice must return cached result (no recompute)."""
state = make_state(
plots=frozenset({4, 5, 6}),
built_on={4: "Happy", 5: "Happy"},
shops=(),
)
# Clear cache first
card_cluster_gain._cache.clear()
gain1 = card_cluster_gain(state, "Happy")
assert len(card_cluster_gain._cache) == 1
gain2 = card_cluster_gain(state, "Happy")
assert gain1 == gain2
assert len(card_cluster_gain._cache) == 1 # No new entry
def test_cache_survives_gc(make_state):
"""Cache must not break when intermediate states are GC'd."""
import gc
state_main = make_state(
plots=frozenset({4, 5, 6}),
built_on={4: "Happy", 5: "Happy"},
shops=(),
)
# Create and discard many states to trigger id reuse
for i in range(100):
_ = make_state(plots=frozenset({i}), round=i)
gc.collect()
# Original state should still return correct result
gain = card_cluster_gain(state_main, "Happy")
assert gain == 20000
|