| """SQLite TTL cache behavior.""" |
|
|
| import time |
|
|
| from app import cache |
|
|
|
|
| def test_set_and_get_roundtrip(): |
| cache.set("key1", {"a": 1, "b": [1, 2]}, ttl_seconds=60) |
| assert cache.get("key1") == {"a": 1, "b": [1, 2]} |
|
|
|
|
| def test_missing_key_returns_none(): |
| assert cache.get("never-set") is None |
|
|
|
|
| def test_expired_entry_returns_none(): |
| cache.set("short", "value", ttl_seconds=-1) |
| assert cache.get("short") is None |
|
|
|
|
| def test_overwrite(): |
| cache.set("key", "old", ttl_seconds=60) |
| cache.set("key", "new", ttl_seconds=60) |
| assert cache.get("key") == "new" |
|
|
|
|
| def test_cached_decorator_calls_function_once(): |
| calls = {"count": 0} |
|
|
| @cache.cached(ttl_seconds=60) |
| def expensive(x): |
| calls["count"] += 1 |
| return x * 2 |
|
|
| assert expensive(21) == 42 |
| assert expensive(21) == 42 |
| assert calls["count"] == 1 |
| |
| assert expensive(10) == 20 |
| assert calls["count"] == 2 |
|
|
|
|
| def test_cached_decorator_skips_none_results(): |
| calls = {"count": 0} |
|
|
| @cache.cached(ttl_seconds=60) |
| def flaky(): |
| calls["count"] += 1 |
| return None |
|
|
| assert flaky() is None |
| assert flaky() is None |
| assert calls["count"] == 2 |
|
|