Skip to content

Instantly share code, notes, and snippets.

@TylerPachal
Created November 26, 2021 15:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TylerPachal/60f562582e48a5cc15d9bbcf9b2472f3 to your computer and use it in GitHub Desktop.
Save TylerPachal/60f562582e48a5cc15d9bbcf9b2472f3 to your computer and use it in GitHub Desktop.
@doc """
Asserts that the given changeset is invalid, and that the given field is
invalid and contains an error message that contains the asserted_message
substring.
Example usage:
assert_invalid changeset, :people, error_message =~ "tyler is not allowed"
"""
defmacro assert_invalid(changeset, field, assertion_expression) when is_atom(field) do
expr = Macro.to_string(assertion_expression)
quote do
c = unquote(changeset)
keys = Map.keys(c.data)
with {:valid, false} <- {:valid, Map.get(c, :valid?)},
{:known_key, true} <- {:known_key, Enum.member?(keys, unquote(field))},
{:message, {message, _opts}} <- {:message, Keyword.get(c.errors, unquote(field))}
do
var!(error_message) = message
if unquote(assertion_expression) do
assert true
else
flunk("""
Expression did not match error message
#{IO.ANSI.cyan()}error_message:#{IO.ANSI.reset()} #{inspect(message)}
#{IO.ANSI.cyan()}expression:#{IO.ANSI.reset()} #{unquote(expr)}
""")
end
else
{:valid, nil} ->
raise "assert_invalid/3 requires a changeset for the first agrument"
{:valid, true} ->
flunk("#{c.data.__struct__} changeset is valid")
{:known_key, false} ->
raise "field :#{unquote(field)} is not part of #{c.data.__struct__}"
{:message, _} ->
flunk(":#{unquote(field)} field is valid")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment