I’m trying to figure out how to best implement this test case and I hit a wall with how I expected the pin operator to work. Here is a simplified version of the test case.
simple_map = %{simple: :data}
MyApp.process_and_dispatch(simple_map)
assert_received {:things_done, ^simple_map}
My issue is that the value sent back does not exactly match simple_map
, but is another map with a bunch of extra stuff added to it that I don’t care about testing right here. I can solve it pretty easily like this:
simple_map = %{simple: :data}
MyApp.process_and_dispatch(simple_map)
assert_received {:things_done, received_map}
assert %{simple: :data} = received_map
but my issue is that I want to repeat this pattern a lot, the simple data actually has quite a few keys, and I don’t want to type out all the match criteria for every case because I expect it would be error prone. I’m trying to figure out a way to pattern match simple_map
as a subset of received_map
.
I see from the below linked mailing list thread that, as of 2016, the pin operator can’t help me here, because it is always doing a full equality check, not a pattern match. Are there any other tools for this case that I’m missing here? The feature I’d want would be something like this:
Kernel.subset?(base_map, extended_map)
def subset?(subset, full) when is_map(subset) and is_map(full) do
Enum.all?(subset, fn {k, v} ->
case Map.fetch(full, k) do
{:ok, full_val} -> full_val == v
:error -> false
end
end)
end