Current section
Files
Jump to
Current section
Files
lib/snapshy.ex
defmodule Snapshy do
defmacro match_snapshot(string) do
%Macro.Env{file: file, function: function, line: line} = __CALLER__
info =
quote do
%{"file" => unquote(file), "function" => unquote(function), "line" => unquote(line)}
end
quote do
Snapshy.match(unquote(string), unquote(info))
end
end
def match(string, %{"function" => function, "file" => file}) do
key = get_key(function)
file = get_file(file)
verify_file_exists(file)
snapshots = get_snapshots(file)
%{
"snapshots" => new_snapshots,
"value" => value
} = get_or_create_snap(snapshots, key, string)
write_if_new(file, snapshots, new_snapshots)
unless value == string do
raise_error([file: file, key: key], value, string)
end
end
defp get_key({function_name, _}) do
function_name
|> Atom.to_string()
|> String.replace(" ", "_")
|> Macro.underscore()
end
defp get_file(file) do
["test/", "__snapshots__/", snapshot_path(file)] |> Path.join()
end
defp snapshot_path(file) do
path = Path.split(file)
path = Enum.drop(path, Enum.find_index(path, fn p -> p === "test" end) + 1)
filename = List.last(path) |> String.replace(".exs", ".snap")
(Enum.drop(path, -1) ++ [filename]) |> Path.join()
end
defp verify_file_exists(file) do
unless File.exists?(file) do
File.mkdir_p(Path.dirname(file))
File.write!(file, "{}", [:write])
end
end
defp get_snapshots(file) do
deserialize(File.read!(file))
end
defp get_or_create_snap(snapshots, key, value) do
snapshots =
unless Map.has_key?(snapshots, key), do: Map.put_new(snapshots, key, value), else: snapshots
%{
"snapshots" => snapshots,
"value" => Map.get(snapshots, key, value)
}
end
defp write_if_new(file, old_snapshots, new_snapshots) do
unless old_snapshots == new_snapshots do
File.write(file, serialize(new_snapshots))
end
end
defp serialize(content) do
Jason.encode!(content)
end
defp deserialize(content) do
Jason.decode!(content)
end
defp raise_error([file: file, key: key], left, right) do
file = snapshot_path(file)
raise ExUnit.AssertionError,
left: left,
right: right,
message: "Received value does not match stored snapshot. (#{file}:#{key})",
expr: "Snapshot == Received"
end
end