defmodule Microprints.MicroprintCacheTest do use ExUnit.Case, async: false alias Microprints.MicroprintCache @fixture_path Path.expand("../support/fixtures/sample.ex", __DIR__) setup do # Start a fresh test PubSub server with a unique name pubsub_name = Module.concat(Microprints.TestPubSub, inspect(System.unique_integer([:positive]))) child_spec = Phoenix.PubSub.child_spec(name: pubsub_name, adapter: Phoenix.PubSub.PG2) {:ok, sup_pid} = Supervisor.start_link([child_spec], strategy: :one_for_one) Process.put(:test_pubsub_supervisor, sup_pid) # Stop any existing cache first if pid = GenServer.whereis(MicroprintCache) do GenServer.stop(pid, :normal, 5000) end # Start fresh cache for this test {:ok, _pid} = MicroprintCache.start_link(pubsub: pubsub_name) on_exit(fn -> if sup_pid = Process.get(:test_pubsub_supervisor) do Supervisor.stop(sup_pid) Process.delete(:test_pubsub_supervisor) end end) %{pubsub_name: pubsub_name} end describe "get_microprint/1" do test "returns microprint for valid file" do assert {:ok, microprint} = MicroprintCache.get_microprint(@fixture_path) assert is_map(microprint) assert is_list(microprint.lines) end test "caches microprint on first access" do # First call generates and caches {:ok, mp1} = MicroprintCache.get_microprint(@fixture_path) # Second call should return cached version (same reference) {:ok, mp2} = MicroprintCache.get_microprint(@fixture_path) assert mp1 == mp2 end test "returns error for missing file" do assert {:error, :enoent} = MicroprintCache.get_microprint("/nonexistent/file.ex") end end describe "invalidate/1" do test "removes cached entry for path" do # Cache a microprint {:ok, _} = MicroprintCache.get_microprint(@fixture_path) # Invalidate it MicroprintCache.invalidate(@fixture_path) # The ETS table should not have this entry anymore # (We verify by checking it's regenerated on next access) {:ok, mp} = MicroprintCache.get_microprint(@fixture_path) assert is_map(mp) end end describe "clear_all/0" do test "removes all cached entries" do # Cache a microprint {:ok, _} = MicroprintCache.get_microprint(@fixture_path) # Clear all MicroprintCache.clear_all() # Should still work (regenerates) {:ok, mp} = MicroprintCache.get_microprint(@fixture_path) assert is_map(mp) end end describe "PubSub integration" do test "invalidates cache on live_reload message", %{pubsub_name: pubsub_name} do # Cache a microprint {:ok, _} = MicroprintCache.get_microprint(@fixture_path) # Simulate LiveReload notification Phoenix.PubSub.broadcast( pubsub_name, "dev_tools_files", {:phoenix_live_reload, "dev_tools_files", @fixture_path} ) # Give the GenServer time to process Process.sleep(10) # The cache entry should have been invalidated # (We can't directly check ETS, but the behavior is verified by the flow) {:ok, mp} = MicroprintCache.get_microprint(@fixture_path) assert is_map(mp) end end end