From 93470d7e69b68eb0d7b194670cfc608ad65a8222 Mon Sep 17 00:00:00 2001 From: Mat Trudel Date: Tue, 12 Nov 2024 11:58:55 -0500 Subject: [PATCH] Add 'found atom/string key, expected string/atom' mismatch detection to literal map matcher Fixes #40 --- lib/machete/matchers/literal_map_matcher.ex | 30 +++++++++++++++---- .../matchers/literal_map_matcher_test.exs | 8 +++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/machete/matchers/literal_map_matcher.ex b/lib/machete/matchers/literal_map_matcher.ex index d71d71e..cce2e8b 100644 --- a/lib/machete/matchers/literal_map_matcher.ex +++ b/lib/machete/matchers/literal_map_matcher.ex @@ -21,15 +21,35 @@ defmodule Machete.LiteralMapMatcher do a_keys = a |> Map.keys() |> MapSet.new() b_keys = b |> Map.keys() |> MapSet.new() + extra_keys = MapSet.difference(b_keys, a_keys) + missing_keys = MapSet.difference(a_keys, b_keys) + + atom_keys = + extra_keys + |> Enum.filter(&(is_atom(&1) && MapSet.member?(missing_keys, to_string(&1)))) + |> MapSet.new() + + string_keys = + extra_keys + |> Enum.filter( + &(is_binary(&1) && MapSet.member?(missing_keys, String.to_existing_atom(&1))) + ) + |> MapSet.new() + extra_keys = - MapSet.difference(b_keys, a_keys) - |> Enum.flat_map(&mismatch("Unexpected key", &1)) + extra_keys + |> MapSet.difference(atom_keys) + |> MapSet.difference(string_keys) missing_keys = - MapSet.difference(a_keys, b_keys) - |> Enum.flat_map(&mismatch("Missing key", &1)) + missing_keys + |> MapSet.difference(atom_keys |> Enum.map(&Kernel.to_string/1) |> MapSet.new()) + |> MapSet.difference(string_keys |> Enum.map(&String.to_existing_atom/1) |> MapSet.new()) - extra_keys ++ missing_keys + Enum.flat_map(extra_keys, &mismatch("Unexpected key", &1)) ++ + Enum.flat_map(missing_keys, &mismatch("Missing key", &1)) ++ + Enum.flat_map(atom_keys, &mismatch("Found atom key, expected string", &1)) ++ + Enum.flat_map(string_keys, &mismatch("Found string key, expected atom", &1)) end defp mismatched_values(a, b) do diff --git a/test/machete/matchers/literal_map_matcher_test.exs b/test/machete/matchers/literal_map_matcher_test.exs index 489ce5c..56ac554 100644 --- a/test/machete/matchers/literal_map_matcher_test.exs +++ b/test/machete/matchers/literal_map_matcher_test.exs @@ -21,6 +21,14 @@ defmodule LiteralMapMatcherTest do assert %{a: 1} ~>> %{} ~> mismatch("Unexpected key", :a) end + test "produces a useful mismatch on atom entries where strings were expected" do + assert %{a: 1} ~>> %{"a" => 1} ~> mismatch("Found atom key, expected string", :a) + end + + test "produces a useful mismatch on atom entries where atoms were expected" do + assert %{"a" => 1} ~>> %{a: 1} ~> mismatch("Found string key, expected atom", "a") + end + test "produces a useful mismatch on non-maps" do assert 1 ~>> %{} ~> mismatch("Value is not a map") end