Rely on stacktraces to get the file and line of last failure
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user