Add argument to koan to allow it to be tested

This commit is contained in:
Felipe Sere
2016-03-09 23:31:27 +00:00
parent a212f674e0
commit fdb87b529f
5 changed files with 83 additions and 2 deletions

24
lib/ast_manger.ex Normal file
View File

@@ -0,0 +1,24 @@
defmodule ASTMangler do
def expand([do: thing], replacement) do
[do: expand(thing, replacement)]
end
def expand({fun, context, args}, replacement) do
new_args = replace(args, replacement)
{fun, context, new_args}
end
def replace(args, b) do
args
|> Enum.find_index(fn(x) -> x == :__ end)
|> replace(args, b)
end
def replace(nil, [], _b), do: []
def replace(nil, [ast], b) do
[expand(ast,b)]
end
def replace(index, list, b) do
List.update_at(list, index, fn(_)-> b end)
end
end

View File

@@ -1,11 +1,17 @@
defmodule Koans do
defmacro koan(name, body) do
compiled_name = String.to_atom(name)
x = quote do: answer
mangled_body = ASTMangler.expand(body, x)
quote do
@koans unquote(compiled_name)
def unquote(compiled_name)() do
def unquote(compiled_name)(answer \\ :nothing) do
try do
unquote(body)
if answer == :nothing do
unquote(body)
else
unquote(mangled_body)
end
:ok
rescue
e in _ -> e

View File

@@ -40,6 +40,13 @@ defmodule Runner do
end
end
def test_single_koan(module, name, answer) do
case apply(module, name, []) do
:ok -> :passed
error -> IO.inspect error
end
end
def run_koan(module, name) do
case apply(module, name, []) do
:ok -> :passed

35
test/ast_mangler_test.exs Normal file
View File

@@ -0,0 +1,35 @@
defmodule ASTManglerTest do
use ExUnit.Case, async: true
test "simple replacement" do
ast = quote do: 1 + :__
mangled = ASTMangler.expand(ast, 37)
assert {:+, [context: ASTManglerTest, import: Kernel], [1, 37]} == mangled
end
def complex_example do
[head | tail] = [1,2,3,4]
assert head == 1
assert tail == [2,3,4]
end
def foo(answer) do
if answer == :yes do
:bar
else
:batz
end
end
test "something" do
n = 1
end
test "complex example" do
ast = [do: {:assert, [line: 5], [{:==, [line: 5], [true, :__]}]}]
assert [do: {:assert, [line: 5], [{:==, [line: 5], [true, true]}]}] == ASTMangler.expand(ast, true)
end
end

9
test/power_test.exs Normal file
View File

@@ -0,0 +1,9 @@
defmodule PowerTest do
use ExUnit.Case
test "something" do
[first | _] = Equalities.all_koans
assert :passed == Runner.test_single_koan(Equalities, first, true)
end
end