2017-01-01 2 views

ответ

2

Вы можете в значительной степени следовать подходу от вопроса вы связаны:

defmodule Test do 
    use ExUnit.Case 

    # (other tests here) 

    ast = quote do 
    test "always pass", do: assert true 
    end 
    expanded = Macro.expand(ast, __ENV__) 

    IO.puts "Original:" 
    # IO.puts inspect(ast, pretty: true) 
    IO.puts ast |> Macro.to_string 
    IO.puts "" 
    IO.puts "Expanded:" 
    # IO.puts inspect(expanded, pretty: true) 
    IO.puts expanded |> Macro.to_string 
end 

Если запустить тесты теперь с mix test, вы будете видеть расширенную версию test макрос:

Original: 
test("always pass") do 
    assert(true) 
end 

Expanded: 
(
    var = {:_, [], ExUnit.Case} 
    contents = {:__block__, [], [{:assert, [context: CrawlieTest, import: ExUnit.Assertions], [true]}, :ok]} 
    message = "always pass" 
    (
    name = ExUnit.Case.register_test(__ENV__, :test, message, []) 
    def(unquote(name)(unquote(var))) do 
     unquote(contents) 
    end 
) 
) 

Вы можете расторгнуть строки IO.puts inspect(_, pretty: true), чтобы увидеть, как оригинал и расширенная версия выглядят в Abstract Syntax Tree представление.

+0

То, что я пропустил в подходе из связанного вопроса, состоит в том, что 'if/2' является макросом тоже :) – raacer

Смежные вопросы