From 6aa74c3ff16604aeba853c34cd525c6b7f46b33f Mon Sep 17 00:00:00 2001 From: German Velasco Date: Thu, 27 May 2021 16:37:54 -0400 Subject: [PATCH] Turn some test helpers from macros -> functions (#604) 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 most of 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 | 81 +++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 52 deletions(-) diff --git a/lib/bamboo/test.ex b/lib/bamboo/test.ex index 77c90f17..98ce5a5e 100644 --- a/lib/bamboo/test.ex +++ b/lib/bamboo/test.ex @@ -157,18 +157,10 @@ 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, opts \\ []) do - quote do - import ExUnit.Assertions - email = Bamboo.Test.normalize_for_testing(unquote(email)) - timeout = Bamboo.Test.get_timeout(unquote(opts)) - - assert_receive( - {:delivered_email, ^email}, - timeout, - Bamboo.Test.flunk_with_email_list(email) - ) - end + def assert_delivered_email(email, opts \\ []) do + email = normalize_for_testing(email) + timeout = get_timeout(opts) + assert_receive({:delivered_email, ^email}, timeout, flunk_with_email_list(email)) end @doc """ @@ -227,17 +219,14 @@ 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, opts \\ []) do - quote bind_quoted: [email_params: email_params, opts: opts] do - import ExUnit.Assertions - timeout = Bamboo.Test.get_timeout(opts) - assert_receive({:delivered_email, email}, timeout, Bamboo.Test.flunk_no_emails_received()) + def assert_email_delivered_with(email_params, opts \\ []) do + timeout = get_timeout(opts) + assert_receive({:delivered_email, email}, timeout, 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 """ @@ -274,43 +263,35 @@ defmodule Bamboo.Test do Bamboo.Email.new_email(subject: "something") |> MyApp.Mailer.deliver() refute_email_delivered_with([subject: "something else"], timeout: 100) """ - defmacro refute_email_delivered_with(email_params, opts \\ []) do - quote bind_quoted: [email_params: email_params, opts: opts] do - import ExUnit.Assertions - - received_email_params = - receive do - {:delivered_email, email} -> Map.from_struct(email) - after - Bamboo.Test.refute_timeout(opts) -> [] - 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, opts \\ []) do + received_email_params = + receive do + {:delivered_email, email} -> Map.from_struct(email) + after + refute_timeout(opts) -> [] 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 @@ -328,8 +309,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. @@ -344,8 +324,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. @@ -359,8 +338,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. @@ -485,8 +463,7 @@ defmodule Bamboo.Test do !!Application.get_env(:bamboo, :shared_test_process) end - @doc false - def normalize_for_testing(email) do + defp normalize_for_testing(email) do email |> Bamboo.Mailer.normalize_addresses() |> Bamboo.TestAdapter.clean_assigns()