From 2c4e1f55c68fcb0f227b86a6d423a5947fe52693 Mon Sep 17 00:00:00 2001 From: Felipe Sere Date: Sat, 12 Oct 2019 12:03:27 +0200 Subject: [PATCH 1/2] Remove stacktrace warning --- lib/display/failure.ex | 2 +- lib/execute.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/display/failure.ex b/lib/display/failure.ex index ced1046c..7fe9311d 100644 --- a/lib/display/failure.ex +++ b/lib/display/failure.ex @@ -49,7 +49,7 @@ defmodule Display.Failure do end defp format_error(error) do - trace = System.stacktrace() |> Enum.take(2) + trace = :erlang.get_stacktrace() |> Enum.take(2) Paint.red(Exception.format(:error, error, trace)) end diff --git a/lib/execute.ex b/lib/execute.ex index 485e0c59..2f677470 100644 --- a/lib/execute.ex +++ b/lib/execute.ex @@ -40,7 +40,7 @@ defmodule Execute do defp expand({:error, stacktrace, exception}, module) do {file, line} = - stacktrace + :erlang.get_stacktrace() |> Enum.drop_while(&(!in_koan?(&1, module))) |> List.first() |> extract_file_and_line From 804406c298c637a6500078ddfdd5a34a78ebcd59 Mon Sep 17 00:00:00 2001 From: Felipe Sere Date: Fri, 19 Jun 2020 09:45:17 +0200 Subject: [PATCH 2/2] Extract file/line from koan and make stacktrace obsolete --- lib/display/failure.ex | 3 +-- lib/execute.ex | 26 ++++++++++---------------- lib/koans.ex | 10 +++++----- test/display/failure_test.exs | 22 ++++++++++++++++++++-- test/executor_test.exs | 2 +- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/lib/display/failure.ex b/lib/display/failure.ex index 7fe9311d..6ecf8420 100644 --- a/lib/display/failure.ex +++ b/lib/display/failure.ex @@ -49,8 +49,7 @@ defmodule Display.Failure do end defp format_error(error) do - trace = :erlang.get_stacktrace() |> Enum.take(2) - Paint.red(Exception.format(:error, error, trace)) + Paint.red(Exception.format(:error, error, [])) end def show_compile_error(error) do diff --git a/lib/execute.ex b/lib/execute.ex index 2f677470..c6ae4922 100644 --- a/lib/execute.ex +++ b/lib/execute.ex @@ -31,26 +31,20 @@ defmodule Execute do end defp exec(module, name, args, parent) do - result = apply(module, name, args) - send(parent, expand(result, module)) + case apply(module, name, args) do + :ok -> send(parent, :ok) + err -> send(parent, expand(err)) + end Process.exit(self(), :kill) end - defp expand(:ok, _), do: :ok - - defp expand({:error, stacktrace, exception}, module) do - {file, line} = - :erlang.get_stacktrace() - |> Enum.drop_while(&(!in_koan?(&1, module))) - |> List.first() - |> extract_file_and_line - - %{error: exception, file: file, line: line} + defp expand({:error, error, {:location, file_path, line}}) do + %{error: error, file: make_relative(file_path), line: line} end - defp in_koan?({module, _, _, _}, koan), do: module == koan - - defp extract_file_and_line({_, _, _, [file: file, line: line]}) do - {file, line} + defp make_relative(path) do + path + |> Path.relative_to_cwd() + |> to_string() end end diff --git a/lib/koans.ex b/lib/koans.ex index 5ab03b38..5c42d60a 100644 --- a/lib/koans.ex +++ b/lib/koans.ex @@ -22,7 +22,7 @@ defmodule Koans do unquote(compiled_body) :ok rescue - e -> {:error, __STACKTRACE__, e} + e -> {:error, e, {:location, __ENV__.file, __ENV__.line}} end end end @@ -39,7 +39,7 @@ defmodule Koans do unquote(single_var) :ok rescue - e -> {:error, __STACKTRACE__, e} + e -> {:error, e, {:location, __ENV__.file, __ENV__.line}} end end end @@ -57,7 +57,7 @@ defmodule Koans do unquote(multi_var) :ok rescue - e -> {:error, __STACKTRACE__, e} + e -> {:error, e, {:location, __ENV__.file, __ENV__.line}} end end end @@ -98,8 +98,8 @@ defmodule Koans do end end - defp koans(env) do - env.module + defp koans(%{module: module}) do + module |> Module.get_attribute(:koans) |> Enum.reverse() end diff --git a/test/display/failure_test.exs b/test/display/failure_test.exs index addce2cd..a527e8bb 100644 --- a/test/display/failure_test.exs +++ b/test/display/failure_test.exs @@ -39,13 +39,31 @@ defmodule FailureTests do test "only offending lines are displayed for errors" do [koan] = SingleArity.all_koans() - error = apply(SingleArity, koan, []) |> Tuple.to_list |> List.last |> error + error = apply(SingleArity, koan, []) |> error() assert Failure.format_failure(error) == """ - Assertion failed in some_file.ex:42\nmatch?(:foo, ___) + Assertion failed in some_file.ex:42 + match?(:foo, ___) + """ + end + + test "formats errors such as arity mismatches as such" do + e = error({:error, %FunctionClauseError{args: nil, arity: 1, clauses: nil, function: :chardata_to_string, kind: nil, module: IO}, nil}) + + assert Failure.format_failure(e) == """ + Error in some_file.ex:42 + ** (FunctionClauseError) no function clause matching in IO.chardata_to_string/1 """ end + defp error({:error, error, _}) do + %{ + error: error, + file: "some_file.ex", + line: 42 + } + end + defp error(error) do %{ error: error, diff --git a/test/executor_test.exs b/test/executor_test.exs index d989123d..fd028ea8 100644 --- a/test/executor_test.exs +++ b/test/executor_test.exs @@ -7,7 +7,7 @@ defmodule ExecuteTest do test "stops at the first failing koan" do {:failed, %{file: file, line: line}, SampleKoan, _name} = Execute.run_module(SampleKoan) - assert file == 'test/support/sample_koan.ex' + assert file == "test/support/sample_koan.ex" assert line == 8 end