defmodule ExUnit::Escaper do
  defrecord Flag, as: nil

  defimpl String::Inspect, for: Flag do
    def inspect(record),   do: record.as
    def to_binary(record), do: record.as
  end

  # Replace _ by a record that when inspected prints "_"
  def escape({ :_, _, false }) do
    quote { unquote(Flag).new(as: "_") }
  end

  def escape(expr) when is_tuple(expr) do
    list_to_tuple(escape(tuple_to_list(expr)))
  end

  def escape(expr) when is_list(expr) do
    Enum.map expr, escape(_)
  end

  def escape(expr) do
    expr
  end
end
# In some assertions we need to show a guard clause
# in the exception message. This usually works fine
# except if the clause has a "_", which means that
# we cannot show it because evaluating it would
# generate a "unbound _" error.
#
# For such cases, we can use `ExUnit::Escaper.escape`
# to escape the expression replacing all "_" by a flag
# that when inspected returns "_".
defmodule ExUnit::Escaper do
  defrecord Flag, as: nil

  defimpl String::Inspect, for: Flag do
    def inspect(record),   do: record.as
    def to_binary(record), do: record.as
  end

  # Replace _ by a record that when inspected prints "_"
  def escape({ :_, _, false }) do
    Flag.new(as: "_")
  end

  def escape(expr) when is_tuple(expr) do
    list_to_tuple(escape(tuple_to_list(expr)))
  end

  def escape(expr) when is_list(expr) do
    Enum.map expr, escape(_)
  end

  def escape(expr) do
    expr
  end
end
Add some explanation for ExUnit::Escaper.
Add some explanation for ExUnit::Escaper.

lexmag/elixir,kelvinst/elixir,pedrosnk/elixir,beedub/elixir,joshprice/elixir,beedub/elixir,kimshrier/elixir,lexmag/elixir,ggcampinho/elixir,ggcampinho/elixir,antipax/elixir,kelvinst/elixir,gfvcastro/elixir,michalmuskala/elixir,kimshrier/elixir,gfvcastro/elixir,elixir-lang/elixir,pedrosnk/elixir,antipax/elixir