Add argument to koan to allow it to be tested
This commit is contained in:
24
lib/ast_manger.ex
Normal file
24
lib/ast_manger.ex
Normal 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
|
||||||
10
lib/koans.ex
10
lib/koans.ex
@@ -1,11 +1,17 @@
|
|||||||
defmodule Koans do
|
defmodule Koans do
|
||||||
defmacro koan(name, body) do
|
defmacro koan(name, body) do
|
||||||
compiled_name = String.to_atom(name)
|
compiled_name = String.to_atom(name)
|
||||||
|
x = quote do: answer
|
||||||
|
mangled_body = ASTMangler.expand(body, x)
|
||||||
quote do
|
quote do
|
||||||
@koans unquote(compiled_name)
|
@koans unquote(compiled_name)
|
||||||
def unquote(compiled_name)() do
|
def unquote(compiled_name)(answer \\ :nothing) do
|
||||||
try do
|
try do
|
||||||
unquote(body)
|
if answer == :nothing do
|
||||||
|
unquote(body)
|
||||||
|
else
|
||||||
|
unquote(mangled_body)
|
||||||
|
end
|
||||||
:ok
|
:ok
|
||||||
rescue
|
rescue
|
||||||
e in _ -> e
|
e in _ -> e
|
||||||
|
|||||||
@@ -40,6 +40,13 @@ defmodule Runner do
|
|||||||
end
|
end
|
||||||
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
|
def run_koan(module, name) do
|
||||||
case apply(module, name, []) do
|
case apply(module, name, []) do
|
||||||
:ok -> :passed
|
:ok -> :passed
|
||||||
|
|||||||
35
test/ast_mangler_test.exs
Normal file
35
test/ast_mangler_test.exs
Normal 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
9
test/power_test.exs
Normal 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
|
||||||
Reference in New Issue
Block a user