import devplacepy.cache as cache_mod
from devplacepy.cache import TTLCache
class FakeClock:
def __init__(self, start=1000.0):
self.now = start
def time(self):
return self.now
def test_get_miss_returns_none():
cache = TTLCache(ttl=60)
assert cache.get("absent") is None
def test_set_and_get_round_trip():
cache = TTLCache(ttl=60)
cache.set("key", "value")
assert cache.get("key") == "value"
def test_entry_expires_after_ttl(monkeypatch):
clock = FakeClock()
monkeypatch.setattr(cache_mod, "time", clock)
cache = TTLCache(ttl=10)
cache.set("key", "value")
clock.now += 11
assert cache.get("key") is None
def test_lru_evicts_oldest_when_over_max_size():
cache = TTLCache(ttl=60, max_size=2)
cache.set("a", 1)
cache.set("b", 2)
cache.set("c", 3)
assert cache.get("a") is None
assert cache.get("b") == 2
assert cache.get("c") == 3
def test_get_promotes_recency():
cache = TTLCache(ttl=60, max_size=2)
cache.set("a", 1)
cache.set("b", 2)
cache.get("a")
cache.set("c", 3)
assert cache.get("a") == 1
assert cache.get("b") is None
assert cache.get("c") == 3
def test_pop_removes_entry():
cache = TTLCache(ttl=60)
cache.set("key", "value")
cache.pop("key")
assert cache.get("key") is None
def test_pop_missing_key_is_noop():
cache = TTLCache(ttl=60)
cache.pop("absent")
def test_clear_empties_cache():
cache = TTLCache(ttl=60)
cache.set("a", 1)
cache.set("b", 2)
cache.clear()
assert cache.get("a") is None
assert cache.get("b") is None
def test_items_excludes_expired_entries(monkeypatch):
clock = FakeClock()
monkeypatch.setattr(cache_mod, "time", clock)
cache = TTLCache(ttl=10)
cache.set("old", 1)
clock.now += 5
cache.set("fresh", 2)
clock.now += 7
items = dict(cache.items())
assert "old" not in items
assert items["fresh"] == 2