defmodule Matcher.Utils.Maps do
import Matcher.Errors
def compare_maps(expected, actual, context, allow_unexpected?: allow_unexpected?)
when is_map(expected) and is_map(actual) do
expected_results =
Enum.map(expected, fn {key, matcher} ->
find_value(key, matcher, actual)
end)
unexpected = Map.keys(actual) -- Map.keys(expected)
if Enum.all?(expected_results, fn {_, _, _, match} ->
Matcher.Utils.matched?(match)
end) and (Enum.empty?(unexpected) or allow_unexpected?) do
{:ok, nil}
else
{:error, error(context, [])}
end
end
def compare_maps(e, a, context, _) do
error(context, message: "expected #{expected(e)}, but got #{mismatched(a)}")
end
defp find_value(key, matcher, actual_map) do
actual_value = Map.get(actual_map, key)
match = Matcher.match(matcher, actual_value)
{key, matcher, actual_value, match}
end
end