Simpler progressbar and handle --koan=<KOAN> better

This commit is contained in:
Felipe Sere
2016-04-25 09:32:34 +01:00
parent 2b2240340e
commit ab72b0e908
5 changed files with 48 additions and 57 deletions

View File

@@ -2,8 +2,7 @@ defmodule Display do
alias IO.ANSI alias IO.ANSI
@current_dir File.cwd! @current_dir File.cwd!
@no_value :ex_unit_no_meaningful_value @no_value :ex_unit_no_meaningful_value
@window_width 40 @progress_bar_length 30
@half_window 20
def invalid_koan(koan, modules) do def invalid_koan(koan, modules) do
koans_names = module_names(modules) koans_names = module_names(modules)
@@ -31,45 +30,22 @@ defmodule Display do
end end
defp bar() do defp bar() do
String.duplicate("-", @window_width + 1) "----------------------------------------"
end end
def progress_bar(%{current: current, total: total}) do def progress_bar(%{current: current, total: total}) do
progress = caluculate_progress(current, total) arrow = caluculate_progress(current, total) |> build_arrow
progress_notification = "(#{current}/#{total})"
if current/total < 0.5 do "|" <> String.ljust(arrow, @progress_bar_length) <> "| #{current} of #{total}"
left_progress(progress_notification, progress)
else
right_progress(progress_notification, progress)
end
end end
defp caluculate_progress(current, total) do defp caluculate_progress(current, total) do
round( Float.floor((current/total) * @window_width)) round( (current/total) * @progress_bar_length)
end end
def left_progress(progress_notification, progress) do defp build_arrow(0), do: ""
left = String.ljust("#{arrow(progress)}", @half_window - 1) defp build_arrow(length) do
right = String.ljust(progress_notification, @half_window) String.duplicate("=", length-1) <> ">"
in_bars(left<>right)
end
def right_progress(progress_notification, progress) do
arrow_length = progress - @half_window - 1
left = String.ljust(progress_notification, @half_window - 1, ?=)
right = String.ljust(arrow(arrow_length), @half_window)
in_bars(left<>right)
end
defp in_bars(thing) do
"|" <> thing <> "|"
end
defp arrow(length) do
String.duplicate("=", length) <> ">"
end end
def show_compile_error(error) do def show_compile_error(error) do
@@ -95,14 +71,9 @@ defmodule Display do
#{format_red(message)} #{format_red(message)}
""" """
end end
defp format_failure(%{error: %ExUnit.AssertionError{expr: expr}, file: file, line: line}) do defp format_failure(%{error: %ExUnit.AssertionError{expr: expr}, file: file, line: line}) do
""" format_assertion_error(expr, file, line)
#{format_cyan("Assertion failed in #{file}:#{line}")}
#{format_red(Macro.to_string(expr))}
"""
end end
defp format_failure(%{error: error, file: file, line: line}) do defp format_failure(%{error: error, file: file, line: line}) do
""" """
#{format_cyan("Error in #{file}:#{line}")} #{format_cyan("Error in #{file}:#{line}")}
@@ -110,6 +81,14 @@ defmodule Display do
""" """
end end
defp format_assertion_error(error, file, line) do
"""
#{format_cyan("Assertion failed in #{file}:#{line}")}
#{format_red(Macro.to_string(error))}
"""
end
defp format_error(error) do defp format_error(error) do
trace = System.stacktrace |> Enum.take(2) trace = System.stacktrace |> Enum.take(2)
format_red(Exception.format(:error, error, trace)) format_red(Exception.format(:error, error, trace))

View File

@@ -2,14 +2,31 @@ defmodule Mix.Tasks.Meditate do
use Mix.Task use Mix.Task
alias Options alias Options
@modules [
Equalities,
Strings,
Tuples,
Lists,
Maps,
Structs,
PatternMatching,
Functions,
Enums,
Processes,
Tasks,
Agents,
]
def run(args) do def run(args) do
Application.ensure_all_started(:elixir_koans) Application.ensure_all_started(:elixir_koans)
Code.compiler_options(ignore_module_conflict: true) Code.compiler_options(ignore_module_conflict: true)
Watcher.start Watcher.start
Tracker.start(Runner.modules)
Options.start(args) Options.start(args)
Runner.run
modules = Runner.modules_to_run
Tracker.start(modules)
Runner.run(modules)
:timer.sleep(:infinity) :timer.sleep(:infinity)
end end

View File

@@ -17,19 +17,13 @@ defmodule Runner do
def koan?(koan), do: Enum.member?(@modules, koan) def koan?(koan), do: Enum.member?(@modules, koan)
def modules, do: @modules def modules, do: @modules
def run do def modules_to_run, do: Options.initial_koan |> modules_to_run
Options.initial_koan def modules_to_run(start_module), do: Enum.drop_while(@modules, &(&1 != start_module))
|>run
end
def run(start_module) when start_module in @modules, do: run(start_module, @modules) def run(modules) do
def run(start_module), do: Display.invalid_koan(start_module, @modules)
def run(start_module, modules) do
Display.clear_screen() Display.clear_screen()
modules modules
|> Enum.drop_while( &(&1 != start_module))
|> Enum.take_while( &(run_module(&1) == :passed)) |> Enum.take_while( &(run_module(&1) == :passed))
end end
@@ -38,7 +32,6 @@ defmodule Runner do
|> Display.considering |> Display.considering
|> Execute.run_module(&track/2) |> Execute.run_module(&track/2)
|> display |> display
end end
defp track(:passed, koan), do: Tracker.completed(koan) defp track(:passed, koan), do: Tracker.completed(koan)

View File

@@ -7,6 +7,7 @@ defmodule Watcher do
Code.load_file(file) Code.load_file(file)
|> Enum.map(&(elem(&1, 0))) |> Enum.map(&(elem(&1, 0)))
|> Enum.find(&Runner.koan?/1) |> Enum.find(&Runner.koan?/1)
|> Runner.modules_to_run
|> Runner.run |> Runner.run
rescue rescue
e -> Display.show_compile_error(e) e -> Display.show_compile_error(e)

View File

@@ -1,18 +1,19 @@
defmodule DisplayTest do defmodule DisplayTest do
use ExUnit.Case use ExUnit.Case
test "puts counter on the right until half the koans are complete" do test "empty bar" do
bar = Display.progress_bar(%{total: 12, current: 3}) bar = Display.progress_bar(%{total: 12, current: 0})
assert bar == "|==========> (3/12) |" assert bar == "| | 0 of 12"
end end
test "puts the counter on the left after half the koans are complete" do test "puts counter on the right until half the koans are complete" do
bar = Display.progress_bar(%{total: 12, current: 10}) bar = Display.progress_bar(%{total: 12, current: 3})
assert bar == "|(10/12)========================> |" assert bar == "|=======> | 3 of 12"
end end
test "full bar" do test "full bar" do
bar = Display.progress_bar(%{total: 12, current: 12}) bar = Display.progress_bar(%{total: 12, current: 12})
assert bar == "|(12/12)===============================>|" assert bar == "|=============================>| 12 of 12"
end end
end end