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