
- Run mix credo --all to identify possible code optimizations - Resolve most of the errors generated by credo such as: - Numbers larger than 9999 should be written with underscores: 58_127 - Modules should have a @moduledoc tag - Comparison will always return true
58 lines
1.4 KiB
Elixir
58 lines
1.4 KiB
Elixir
defmodule Execute do
|
|
@moduledoc false
|
|
def run_module(module, callback \\ fn _result, _module, _koan -> nil end) do
|
|
Enum.reduce_while(module.all_koans, :passed, fn koan, _ ->
|
|
module
|
|
|> run_koan(koan)
|
|
|> hook(module, koan, callback)
|
|
|> continue?
|
|
end)
|
|
end
|
|
|
|
defp hook(result, module, koan, callback) do
|
|
callback.(result, module, koan)
|
|
result
|
|
end
|
|
|
|
defp continue?(:passed), do: {:cont, :passed}
|
|
defp continue?(result), do: {:halt, result}
|
|
|
|
def run_koan(module, name, args \\ []) do
|
|
parent = self()
|
|
spawn(fn -> exec(module, name, args, parent) end)
|
|
listen_for_result(module, name)
|
|
end
|
|
|
|
def listen_for_result(module, name) do
|
|
receive do
|
|
:ok -> :passed
|
|
%{error: _} = failure -> {:failed, failure, module, name}
|
|
_ -> listen_for_result(module, name)
|
|
end
|
|
end
|
|
|
|
defp exec(module, name, args, parent) do
|
|
result = apply(module, name, args)
|
|
send(parent, expand(result, module))
|
|
Process.exit(self(), :kill)
|
|
end
|
|
|
|
defp expand(:ok, _), do: :ok
|
|
|
|
defp expand({:error, stacktrace, exception}, module) do
|
|
{file, line} =
|
|
stacktrace
|
|
|> Enum.drop_while(&(!in_koan?(&1, module)))
|
|
|> List.first()
|
|
|> extract_file_and_line
|
|
|
|
%{error: exception, file: file, line: line}
|
|
end
|
|
|
|
defp in_koan?({module, _, _, _}, koan), do: module == koan
|
|
|
|
defp extract_file_and_line({_, _, _, [file: file, line: line]}) do
|
|
{file, line}
|
|
end
|
|
end
|