Hello,
I have here (a rather silly) example of defining and using a macro within the same module.
defmodule FooTest do
use ExUnit.Case
defmacro p(x) do
quote do
IO.puts(unquote(x))
end
end
test "foo" do
p(123)
end
end
It works
18:53 $ mix test
123
.
Finished in 0.01 seconds
1 test, 0 failures
Randomized with seed 450622
I do not really care if the macro is public or private.
Now, what Iād really like to do is to use a āwithin the sameā module macro to define tests.
This works if I create a separate Helper module.
defmodule Helper do
defmacro testp(name, do: body) do
quote do
test(unquote(name)) do
IO.puts "Running test #{unquote(name)}"
unquote(body)
end
end
end
end
defmodule FooTest do
use ExUnit.Case
import Helper
testp "foo" do
assert 1 == 1
end
end
19:03 $ mix test
Running test foo
.
Finished in 0.02 seconds
1 test, 0 failures
Randomized with seed 678670
But I do not get it to work within the same module.
defmodule FooTest do
use ExUnit.Case
defmacro testp(name, do: body) do
quote do
test(unquote(name)) do
IO.puts "Running test #{unquote(name)}"
unquote(body)
end
end
end
testp "foo" do
assert 1 == 1
end
end
This gives
19:03 $ mix test
** (CompileError) test/foo_test.exs:13: undefined function testp/2
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
(elixir) lib/code.ex:370: Code.require_file/2
(elixir) lib/kernel/parallel_require.ex:57: anonymous fn/2 in Kernel.ParallelRequire.spawn_requires/5
Am I missing something? Or is this technically not possible?
I am using
19:04 $ elixir -v
Erlang/OTP 19 [erts-8.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Elixir 1.4.2
Cheers
Kilian