Stop wrapping ExUnit
This commit is contained in:
3
config/config.exs
Normal file
3
config/config.exs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
use Mix.Config
|
||||||
|
|
||||||
|
config :ex_unit, assert_receive_timeout: 100
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
defmodule BlankAssertions do
|
|
||||||
defmacro assert(expr) do
|
|
||||||
if contains_blank?(expr) do
|
|
||||||
code = Macro.escape(expr)
|
|
||||||
quote do
|
|
||||||
raise ExUnit.AssertionError, expr: unquote(code)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
quote do
|
|
||||||
ExUnit.Assertions.assert(unquote(expr))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defmacro refute(expr) do
|
|
||||||
if contains_blank?(expr) do
|
|
||||||
code = Macro.escape(expr)
|
|
||||||
quote do
|
|
||||||
raise ExUnit.AssertionError, expr: unquote(code)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
quote do
|
|
||||||
ExUnit.Assertions.refute(unquote(expr))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defmacro assert_receive(expr) do
|
|
||||||
code = Macro.escape(expr)
|
|
||||||
if contains_blank?(expr) do
|
|
||||||
quote do
|
|
||||||
raise ExUnit.AssertionError, expr: {:assert_receive, [], [unquote(code)]}
|
|
||||||
end
|
|
||||||
else
|
|
||||||
quote do
|
|
||||||
receive do
|
|
||||||
unquote(expr) -> :ok
|
|
||||||
after
|
|
||||||
100 -> {:messages, messages} = Process.info(self(), :messages)
|
|
||||||
mailbox = Enum.map_join(messages, ", ", &inspect/1)
|
|
||||||
message = inspect(unquote(expr))
|
|
||||||
ExUnit.Assertions.flunk("Message #{message} not found in process mailbox. Mailbox contains: [#{mailbox}]")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def assert(value, opts) do
|
|
||||||
ExUnit.Assertions.assert(value, opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
def refute(value, opts) do
|
|
||||||
ExUnit.Assertions.refute(value, opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
def flunk(message \\ "Flunked!") do
|
|
||||||
ExUnit.Assertions.flunk(message)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp contains_blank?(expr) do
|
|
||||||
Blanks.count(expr) > 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -20,4 +20,20 @@ defmodule Blanks do
|
|||||||
defp count(:___, acc), do: {node, acc+1}
|
defp count(:___, acc), do: {node, acc+1}
|
||||||
defp count({:___, _, _}, acc), do: {node, acc+1}
|
defp count({:___, _, _}, acc), do: {node, acc+1}
|
||||||
defp count(node, acc), do: {node, acc}
|
defp count(node, acc), do: {node, acc}
|
||||||
|
|
||||||
|
def replace_line([do: ast], replacement_fn), do: [do: replace_line(ast, replacement_fn)]
|
||||||
|
def replace_line({:__block__, meta, lines}, replacement_fn) do
|
||||||
|
replaced_lines = Enum.map(lines, fn(line) ->
|
||||||
|
replace_line(line, replacement_fn)
|
||||||
|
end)
|
||||||
|
|
||||||
|
{:__block__, meta, replaced_lines}
|
||||||
|
end
|
||||||
|
def replace_line(line, replacement_fn) do
|
||||||
|
if Blanks.count(line) > 0 do
|
||||||
|
replacement_fn.(line)
|
||||||
|
else
|
||||||
|
line
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -52,13 +52,9 @@ defmodule Display do
|
|||||||
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)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp format_assertion_error(error, file, line) do
|
|
||||||
"""
|
"""
|
||||||
#{format_cyan("Assertion failed in #{file}:#{line}")}
|
#{format_cyan("Assertion failed in #{file}:#{line}")}
|
||||||
#{format_red(Macro.to_string(error))}
|
#{format_red(Macro.to_string(expr))}
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
17
lib/koans.ex
17
lib/koans.ex
@@ -7,8 +7,11 @@ defmodule Koans do
|
|||||||
if not valid_name(name) do
|
if not valid_name(name) do
|
||||||
raise "Name does not start with a capital ltter: #{name}"
|
raise "Name does not start with a capital ltter: #{name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
compiled_name = String.to_atom(name)
|
compiled_name = String.to_atom(name)
|
||||||
number_of_args = Blanks.count(body)
|
number_of_args = Blanks.count(body)
|
||||||
|
compiled_body = Blanks.replace_line(body, &blank_line_replacement/1)
|
||||||
|
|
||||||
quote do
|
quote do
|
||||||
@koans unquote(compiled_name)
|
@koans unquote(compiled_name)
|
||||||
|
|
||||||
@@ -16,7 +19,7 @@ defmodule Koans do
|
|||||||
|
|
||||||
def unquote(compiled_name)() do
|
def unquote(compiled_name)() do
|
||||||
try do
|
try do
|
||||||
unquote(body)
|
unquote(compiled_body)
|
||||||
:ok
|
:ok
|
||||||
rescue
|
rescue
|
||||||
e in _ -> e
|
e in _ -> e
|
||||||
@@ -47,6 +50,16 @@ defmodule Koans do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp blank_line_replacement({:assert, _meta, [expr]}) do
|
||||||
|
code = Macro.escape(expr)
|
||||||
|
quote do: raise ExUnit.AssertionError, expr: unquote(code)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp blank_line_replacement(line) do
|
||||||
|
code = Macro.escape(line)
|
||||||
|
quote do: raise ExUnit.AssertionError, expr: unquote(code)
|
||||||
|
end
|
||||||
|
|
||||||
defp create_vars(amount) do
|
defp create_vars(amount) do
|
||||||
for id <- 0..amount, do: quote do: elem(converted, unquote(id))
|
for id <- 0..amount, do: quote do: elem(converted, unquote(id))
|
||||||
end
|
end
|
||||||
@@ -57,8 +70,8 @@ defmodule Koans do
|
|||||||
Module.register_attribute(__MODULE__, :koans, accumulate: true)
|
Module.register_attribute(__MODULE__, :koans, accumulate: true)
|
||||||
|
|
||||||
require ExUnit.Assertions
|
require ExUnit.Assertions
|
||||||
|
import ExUnit.Assertions
|
||||||
import Koans
|
import Koans
|
||||||
import BlankAssertions
|
|
||||||
|
|
||||||
@before_compile Koans
|
@before_compile Koans
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -51,4 +51,38 @@ defmodule BlanksTest do
|
|||||||
|
|
||||||
assert Blanks.count(ast) == 2
|
assert Blanks.count(ast) == 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "replaces whole line containing blank" do
|
||||||
|
ast = quote do
|
||||||
|
1 + 2
|
||||||
|
2 + ___
|
||||||
|
end
|
||||||
|
|
||||||
|
expected_result = quote do
|
||||||
|
1 + 2
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
actual_result = Blanks.replace_line(ast, fn(_) -> true end)
|
||||||
|
|
||||||
|
assert actual_result == expected_result
|
||||||
|
end
|
||||||
|
|
||||||
|
test "replacement fn can access line" do
|
||||||
|
ast = quote do
|
||||||
|
1 + 2
|
||||||
|
2 + ___
|
||||||
|
end
|
||||||
|
|
||||||
|
expected_result = quote do
|
||||||
|
1 + 2
|
||||||
|
some_fun(2 + ___)
|
||||||
|
end
|
||||||
|
|
||||||
|
actual_result = Blanks.replace_line(ast, fn(line) ->
|
||||||
|
quote do: some_fun(unquote(line))
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert actual_result == expected_result
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ defmodule ExecuteTest do
|
|||||||
test "stops at the first failing koan" do
|
test "stops at the first failing koan" do
|
||||||
{:failed, %{error: _, file: file, line: line}, SampleKoan, _name} = Execute.run_module(SampleKoan)
|
{:failed, %{error: _, 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 == 5
|
assert line == 4
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user