From aae302cd7cf2a2e8c90b25175488825dccd902d2 Mon Sep 17 00:00:00 2001 From: German Velasco Date: Fri, 21 May 2021 13:17:37 -0400 Subject: [PATCH] Turn some test helpers from macros -> functions What changed? ============ We change three test helpers in `Bamboo.Test` from macros into regular functions: - `assert_delivered_email/1` - `assert_delivered_email_with/1` - `refute_email_delivered_with/1` There are other helpers that are already functions: - `assert_no_emails_delivered/0` - `refute_delivered_email/1` The only macro we leave as a macro (because it needs to be one) is `assert_delivered_email_matches/1` Why? ---- There seems no reason for those functions to be macros, and they only add extra complexity. > Macros should only be used as a last resort - from Elixir's [getting started docs](https://elixir-lang.org/getting-started/meta/macros.html) A side benefit ------------- A side benefit of doing this is that we can make all the private functions truly private with `defp`. With the macros, we had to make them public (to access them from the macros), and we set `@doc false` so they wouldn't show up in docs. --- lib/bamboo/test.ex | 71 ++++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 44 deletions(-) diff --git a/lib/bamboo/test.ex b/lib/bamboo/test.ex index beb92e0c..0ac0901a 100644 --- a/lib/bamboo/test.ex +++ b/lib/bamboo/test.ex @@ -157,12 +157,9 @@ defmodule Bamboo.Test do unsent_email = Bamboo.Email.new_email(subject: "something else") assert_delivered_email(unsent_email) # Will fail """ - defmacro assert_delivered_email(email) do - quote do - import ExUnit.Assertions - email = Bamboo.Test.normalize_for_testing(unquote(email)) - assert_receive({:delivered_email, ^email}, 100, Bamboo.Test.flunk_with_email_list(email)) - end + def assert_delivered_email(email) do + email = normalize_for_testing(email) + assert_receive({:delivered_email, ^email}, 100, flunk_with_email_list(email)) end @doc """ @@ -220,16 +217,13 @@ defmodule Bamboo.Test do assert_email_delivered_with(text_body: ~r/love/) # Will pass assert_email_delivered_with(text_body: ~r/like/) # Will fail """ - defmacro assert_email_delivered_with(email_params) do - quote bind_quoted: [email_params: email_params] do - import ExUnit.Assertions - assert_receive({:delivered_email, email}, 100, Bamboo.Test.flunk_no_emails_received()) + def assert_email_delivered_with(email_params) do + assert_receive({:delivered_email, email}, 100, flunk_no_emails_received()) - received_email_params = email |> Map.from_struct() + received_email_params = email |> Map.from_struct() - assert Enum.all?(email_params, fn {k, v} -> do_match(received_email_params[k], v, k) end), - Bamboo.Test.flunk_attributes_do_not_match(email_params, received_email_params) - end + assert Enum.all?(email_params, fn {k, v} -> do_match(received_email_params[k], v, k) end), + flunk_attributes_do_not_match(email_params, received_email_params) end @doc """ @@ -247,43 +241,35 @@ defmodule Bamboo.Test do email = Bamboo.Email.new_email(subject: "something") |> MyApp.Mailer.deliver refute_email_delivered_with(subject: ~r/some/) # Will fail """ - defmacro refute_email_delivered_with(email_params) do - quote bind_quoted: [email_params: email_params] do - import ExUnit.Assertions - - received_email_params = - receive do - {:delivered_email, email} -> Map.from_struct(email) - after - 100 -> [] - end - - if is_nil(received_email_params) do - refute false - else - refute Enum.any?(email_params, fn {k, v} -> do_match(received_email_params[k], v, k) end), - Bamboo.Test.flunk_attributes_match(email_params, received_email_params) + def refute_email_delivered_with(email_params) do + received_email_params = + receive do + {:delivered_email, email} -> Map.from_struct(email) + after + 100 -> [] end + + if is_nil(received_email_params) do + refute false + else + refute Enum.any?(email_params, fn {k, v} -> do_match(received_email_params[k], v, k) end), + flunk_attributes_match(email_params, received_email_params) end end - @doc false - def do_match(value1, value2 = %Regex{}, _type) do + defp do_match(value1, value2 = %Regex{}, _type) do Regex.match?(value2, value1) end - @doc false - def do_match(value1, value2, type) do + defp do_match(value1, value2, type) do value1 == value2 || value1 == format(value2, type) end - @doc false defp format(record, type) do Bamboo.Formatter.format_email_address(record, %{type: type}) end - @doc false - def flunk_with_email_list(email) do + defp flunk_with_email_list(email) do if Enum.empty?(delivered_emails()) do flunk_no_emails_received() else @@ -301,8 +287,7 @@ defmodule Bamboo.Test do end end - @doc false - def flunk_no_emails_received do + defp flunk_no_emails_received do flunk(""" There were 0 emails delivered to this process. @@ -317,8 +302,7 @@ defmodule Bamboo.Test do """) end - @doc false - def flunk_attributes_do_not_match(params_given, params_received) do + defp flunk_attributes_do_not_match(params_given, params_received) do """ The parameters given do not match. @@ -332,8 +316,7 @@ defmodule Bamboo.Test do """ end - @doc false - def flunk_attributes_match(params_given, params_received) do + defp flunk_attributes_match(params_given, params_received) do """ The parameters given match. @@ -458,7 +441,7 @@ defmodule Bamboo.Test do end @doc false - def normalize_for_testing(email) do + defp normalize_for_testing(email) do email |> Bamboo.Mailer.normalize_addresses() |> Bamboo.TestAdapter.clean_assigns()