How can you assert that a map in a variable matches another map that is a superset?

pattern-matching
testing

#21

Okay, my fault, it is passed in as @demo_map, comes out as @demo_map and then gets expanded to %{a: 1}, still, your macros shouldn’t be necessary…


#22

You’re right - the macro seemed superfluous - I just didn’t know in what way … so this works:

defmodule Demo do
  @demo_map %{a: 1}

  def subset?(super_map) do
    case super_map do
      @demo_map ->
        true
      _ ->
        false
    end
  end

  def subset2?(super_map) do
    try do
      @demo_map = super_map
      true
    catch
      :error, {:badmatch, _} ->
        false
    end
  end

  def subset3?(@demo_map = _super_map), do: true
  def subset3?(_), do: false

  def a,
    do: @demo_map

  def with_fun(subset) do
    fn {k,v} ->
      IO.puts("a ⊆ #{Atom.to_string(k)}: #{subset.(v)}")
    end
  end

  def with_fun({title, list}, fun) do
    IO.puts(title)
    Enum.each(list, with_fun(fun))
  end
end

check_list = [a: Demo.a, b: %{a: 1, b: 2}, c: %{c: 3}, e: %{}]

Demo.with_fun({"--- subset? ", check_list}, &Demo.subset?/1)
Demo.with_fun({"--- subset2? ", check_list}, &Demo.subset2?/1)
Demo.with_fun({"--- subset3? ", check_list}, &Demo.subset3?/1)

#23

this works for me (with a little help of runtime code evaluation)

iex(13)> map1 = %{a: 1}     
%{a: 1}
iex(14)> map2 = %{a: 1, b: 2}
%{a: 1, b: 2}
iex(15)> quote(do: unquote(Macro.escape(map1)) = unquote(Macro.escape(map2))) |> Code.eval_quoted() 
{%{a: 1, b: 2}, []}
iex(16)> map1 = %{a: 1, c: 3}                                                                       
%{a: 1, c: 3}
iex(17)> quote(do: unquote(Macro.escape(map1)) = unquote(Macro.escape(map2))) |> Code.eval_quoted() 
** (MatchError) no match of right hand side value: %{a: 1, b: 2}
    (stdlib) :erl_eval.expr/3
    (elixir) lib/code.ex:493: Code.eval_quoted/3
iex(17)> map2 = %{a: 1, b: 2, c: 3}                                                                 
%{a: 1, b: 2, c: 3}
iex(18)> quote(do: unquote(Macro.escape(map1)) = unquote(Macro.escape(map2))) |> Code.eval_quoted() 
{%{a: 1, b: 2, c: 3}, []}