"""Unit tests for storage/cache.py.""" from __future__ import annotations import time import pytest from storage.cache import Cache class TestCache: def test_set_and_get(self): c = Cache(ttl_seconds=60, max_entries=10) c.set("key1", "value1") assert c.get("key1") == "value1" def test_get_missing_key(self): c = Cache() assert c.get("missing") is None def test_ttl_expiration(self): c = Cache(ttl_seconds=1, max_entries=10) c.set("key1", "value1") assert c.get("key1") == "value1" time.sleep(1.2) assert c.get("key1") is None def test_lru_eviction(self): c = Cache(ttl_seconds=60, max_entries=3) c.set("k1", "v1") c.set("k2", "v2") c.set("k3", "v3") # Access k1 to mark it as recently used c.get("k1") # Add k4 — should evict k2 (least recently used) c.set("k4", "v4") assert c.get("k1") == "v1" # still there assert c.get("k2") is None # evicted assert c.get("k3") == "v3" assert c.get("k4") == "v4" def test_invalidate(self): c = Cache() c.set("k1", "v1") assert c.invalidate("k1") is True assert c.get("k1") is None assert c.invalidate("k1") is False # already gone def test_clear(self): c = Cache() c.set("k1", "v1") c.set("k2", "v2") n = c.clear() assert n == 2 assert c.get("k1") is None def test_stats_hit_miss(self): c = Cache() c.set("k1", "v1") c.get("k1") # hit c.get("missing") # miss s = c.stats() assert s["hits"] == 1 assert s["misses"] == 1 assert s["hit_ratio"] == 0.5 def test_stats_evictions(self): c = Cache(ttl_seconds=60, max_entries=2) c.set("k1", "v1") c.set("k2", "v2") c.set("k3", "v3") # should evict k1 s = c.stats() assert s["evictions"] == 1 assert s["entries"] == 2 def test_overwrite_existing_key(self): c = Cache() c.set("k1", "v1") c.set("k1", "v2") assert c.get("k1") == "v2" s = c.stats() assert s["entries"] == 1