defmodule SimpleshopTheme.Theme.CSSCacheTest do use SimpleshopTheme.DataCase alias SimpleshopTheme.Theme.CSSCache alias SimpleshopTheme.Theme.CSSGenerator alias SimpleshopTheme.Settings.ThemeSettings describe "get/0" do test "returns cached CSS after warm" do # Cache should be pre-warmed on startup assert {:ok, css} = CSSCache.get() assert is_binary(css) assert css =~ ".themed {" end end describe "put/1 and get/0" do test "stores and retrieves CSS" do test_css = "/* test css */" :ok = CSSCache.put(test_css) assert {:ok, ^test_css} = CSSCache.get() # Restore original cache CSSCache.warm() end end describe "invalidate/0" do test "clears cached CSS" do # Ensure cache has something CSSCache.warm() assert {:ok, _} = CSSCache.get() # Invalidate :ok = CSSCache.invalidate() assert :miss = CSSCache.get() # Restore CSSCache.warm() end end describe "warm/0" do test "populates cache from current settings" do CSSCache.invalidate() assert :miss = CSSCache.get() :ok = CSSCache.warm() assert {:ok, css} = CSSCache.get() assert is_binary(css) end end describe "performance" do @tag :benchmark test "cache hit is faster than generation" do # Ensure cache is warm CSSCache.warm() settings = %ThemeSettings{} # Benchmark cache hit (should be microseconds) {cache_time, {:ok, _cached_css}} = :timer.tc(fn -> CSSCache.get() end) # Benchmark CSS generation (should be milliseconds) {gen_time, _generated_css} = :timer.tc(fn -> CSSGenerator.generate(settings) end) # Log results for visibility IO.puts("\n") IO.puts(" Cache hit: #{cache_time} µs") IO.puts(" CSS generate: #{gen_time} µs") IO.puts(" Speedup: #{Float.round(gen_time / max(cache_time, 1), 1)}x faster") # Cache should be faster than generation assert cache_time < gen_time, "Cache (#{cache_time}µs) should be faster than generation (#{gen_time}µs)" end @tag :benchmark test "multiple cache hits are consistent" do CSSCache.warm() times = for _ <- 1..100 do {time, {:ok, _}} = :timer.tc(fn -> CSSCache.get() end) time end avg = Enum.sum(times) / length(times) max_time = Enum.max(times) min_time = Enum.min(times) IO.puts("\n") IO.puts(" 100 cache hits:") IO.puts(" Avg: #{Float.round(avg, 1)} µs") IO.puts(" Min: #{min_time} µs") IO.puts(" Max: #{max_time} µs") # Average should be under 100 microseconds (ETS is fast) assert avg < 100, "Average cache hit (#{avg}µs) should be under 100µs" end end end