Current section
Files
Jump to
Current section
Files
lib/test_match.ex
defmodule TestMatch do
@moduledoc """
Matching function for ExUnit tests
"""
@doc """
Checks if given attributes matches
Returns `true` or raises ExUnit.AssertionError
## Example
The assertion
assert test_match? %{a: 1}, %{a: 1, b: 2}
will match.
assert test_match? %{a: 1, b: 2}, %{a: 1}
will fail with the message:
match (test_match?) failed
left: %{a: 1, b: 2},
right: %{a: 1}
"""
@spec test_match?(any(), any(), list()) :: boolean()
def test_match?(small_map, big_map, options \\ [exactly: true])
def test_match?(small_map, %{__struct__: _} = big_map, options) do
test_match?(small_map, Map.from_struct(big_map), options)
end
def test_match?(%{__struct__: _} = small_map, big_map, options) do
test_match?(Map.from_struct(small_map), big_map, options)
end
def test_match?(small_map, big_map, options) when is_list(big_map) and is_list(small_map) do
small_map
|> Enum.zip(big_map)
|> Enum.all?(fn {small, big} -> test_match?(small, big, options) end)
|> case do
false ->
raise ExUnit.AssertionError,
left: small_map,
right: big_map,
message: "match (test_match?) failed"
true -> true
end
end
def test_match?(small_map, big_map, options) when is_map(big_map) do
small_map
|> Enum.all?(
fn
{_key, :_} -> true
{key, value} when is_map(value) or is_list(value) ->
test_match?(value, big_map[key], options)
{key, value} = item ->
if options[:exactly] do
Enum.member?(big_map, item)
else
value == big_map[key]
end
end
)
|> case do
false ->
raise ExUnit.AssertionError,
left: small_map,
right: big_map,
message: "match (test_match?) failed"
true -> true
end
end
def test_match?(a, a, _), do: true
def test_match?(a, b, _),
do: raise ExUnit.AssertionError,
left: a,
right: b,
message: "match (test_match?) failed"
end