78 lines
2.3 KiB
Elixir
78 lines
2.3 KiB
Elixir
defmodule Microwaveprop.CacheTest do
|
|
use ExUnit.Case, async: false
|
|
|
|
alias Microwaveprop.Cache
|
|
|
|
setup do
|
|
Cache.clear()
|
|
:ok
|
|
end
|
|
|
|
describe "fetch_or_store/3" do
|
|
test "invokes the function and returns the value on a cold cache" do
|
|
assert Cache.fetch_or_store(:the_key, 1_000, fn -> 42 end) == 42
|
|
end
|
|
|
|
test "returns the cached value without invoking the function on a warm hit" do
|
|
Cache.fetch_or_store(:the_key, 1_000, fn -> 42 end)
|
|
assert Cache.fetch_or_store(:the_key, 1_000, fn -> raise "should not run" end) == 42
|
|
end
|
|
|
|
test "re-invokes the function once the TTL expires" do
|
|
Cache.put(:the_key, 1, -1)
|
|
assert Cache.fetch_or_store(:the_key, 1_000, fn -> 2 end) == 2
|
|
end
|
|
|
|
test "isolates values by key" do
|
|
assert Cache.fetch_or_store(:a, 1_000, fn -> 1 end) == 1
|
|
assert Cache.fetch_or_store(:b, 1_000, fn -> 2 end) == 2
|
|
assert Cache.fetch_or_store(:a, 1_000, fn -> raise "no" end) == 1
|
|
assert Cache.fetch_or_store(:b, 1_000, fn -> raise "no" end) == 2
|
|
end
|
|
end
|
|
|
|
describe "put/3 and invalidate/1" do
|
|
test "put/3 stores a value with the given TTL" do
|
|
Cache.put(:k, "hello", 1_000)
|
|
assert Cache.fetch_or_store(:k, 1_000, fn -> "other" end) == "hello"
|
|
end
|
|
|
|
test "invalidate/1 removes an entry, forcing the next fetch to recompute" do
|
|
Cache.put(:k, "stale", 60_000)
|
|
Cache.invalidate(:k)
|
|
assert Cache.fetch_or_store(:k, 1_000, fn -> "fresh" end) == "fresh"
|
|
end
|
|
end
|
|
|
|
describe "sweep/0" do
|
|
test "removes expired entries" do
|
|
Cache.put(:expired, "old", 1)
|
|
Process.sleep(5)
|
|
|
|
assert Cache.sweep() >= 1
|
|
assert :ets.lookup(:microwaveprop_cache, :expired) == []
|
|
end
|
|
|
|
test "leaves unexpired entries in place" do
|
|
Cache.put(:fresh, "new", 60_000)
|
|
|
|
_ = Cache.sweep()
|
|
|
|
assert [{:fresh, "new", _}] = :ets.lookup(:microwaveprop_cache, :fresh)
|
|
end
|
|
|
|
test "handles a mix of expired and unexpired entries" do
|
|
Cache.put(:expired_a, 1, 1)
|
|
Cache.put(:expired_b, 2, 1)
|
|
Cache.put(:fresh, 3, 60_000)
|
|
Process.sleep(5)
|
|
|
|
deleted = Cache.sweep()
|
|
assert deleted >= 2
|
|
|
|
assert :ets.lookup(:microwaveprop_cache, :expired_a) == []
|
|
assert :ets.lookup(:microwaveprop_cache, :expired_b) == []
|
|
assert [{:fresh, 3, _}] = :ets.lookup(:microwaveprop_cache, :fresh)
|
|
end
|
|
end
|
|
end
|