Rely on stacktraces to get the file and line of last failure

This commit is contained in:
Uku Taht
2016-03-07 15:36:18 +02:00
committed by Felipe Sere
parent 95e4d5a182
commit cd8e02c68a

View File

@@ -7,7 +7,7 @@ defmodule Display do
IO.puts("Now meditate upon #{display_module(module)}")
IO.puts("---------------------------------------")
IO.puts(format_cyan(display_failed_assertion(module, expr)))
IO.puts(format_cyan(last_failure_location))
IO.puts(display_koan(name))
IO.puts(format_red(Macro.to_string(expr)))
end
@@ -23,9 +23,20 @@ defmodule Display do
end
end
def display_failed_assertion(module, expr) do
file = source_file(module)
"Assertion failed in #{file}:#{line_number(expr, in: file)}"
def last_failure_location do
{file, line} = System.stacktrace
|> Enum.drop_while(&in_ex_unit?/1)
|> List.first
|> extract_file_and_line
"Assertion failed in #{file}:#{line}"
end
defp in_ex_unit?({ExUnit.Assertions, _, _, _}), do: true
defp in_ex_unit?(_), do: false
defp extract_file_and_line({_, _, _, [file: file, line: line]}) do
{file, line}
end
def format_compile_error(error) do
@@ -33,45 +44,6 @@ defmodule Display do
IO.puts(format_red(Exception.format(:error, error, trace)))
end
defp line_number({_, [line: line], _}, in: _), do: line
defp line_number(expr, in: file) do
expr
|> to_s
|> find_in_file(file)
|> interpret
end
defp interpret({:ok, n}), do: n
defp find_in_file(line, file) do
File.open(file, fn(handle) ->
IO.read(handle, :all)
|> String.split("\n")
|> Enum.find_index(fn(candidate) -> String.contains?(candidate, line) end)
|> one_based
end)
end
defp one_based(nil), do: "???"
defp one_based(line), do: line + 1
defp to_s(atom) when is_atom(atom), do: ":#{to_string(atom)}"
defp to_s(tuple) when is_tuple(tuple) do
elements = tuple
|> Tuple.to_list
|> Enum.map(fn(x) -> to_s(x) end)
"{#{Enum.join(elements, ", ")}}"
end
defp to_s(x), do: "\"#{x}\""
defp source_file(module) do
module.__info__(:compile)
|> Dict.get(:source)
|> Path.relative_to(@current_dir)
end
defp format_red(str) do
Enum.join([ANSI.red, str, ANSI.reset], "")
end