defmodule ElixirScript.Test.Callbacks do @moduledoc """ Defines ElixirScript.Test callbacks """ @doc """ Called before all tests are run in a test file """ defmacro setup_all(context \\ quote(do: _), contents) do do_setup(context, contents, :__elixirscript_test_setup_all) end @doc """ Called before each test is run in a test file """ defmacro setup(context \\ quote(do: _), contents) do do_setup(context, contents, :__elixirscript_test_setup) end defp do_setup(context, contents, name) do contents = case contents do [do: block] -> quote do unquote(block) end _ -> quote do try(unquote(contents)) end end context = Macro.escape(context) contents = Macro.escape(contents, unquote: true) quote bind_quoted: [context: context, contents: contents, name: name] do def unquote(name)(unquote(context)) do unquote(contents) end end end @doc """ Called after all tests are run in a test file """ defmacro teardown_all(context \\ quote(do: _), contents) do do_teardown(context, contents, :__elixirscript_test_teardown_all) end @doc """ Called after each test is run in a test file """ defmacro teardown(context \\ quote(do: _), contents) do do_teardown(context, contents, :__elixirscript_test_teardown) end defp do_teardown(context, contents, name) do contents = case contents do [do: block] -> quote do unquote(block) :ok end _ -> quote do try(unquote(contents)) :ok end end context = Macro.escape(context) contents = Macro.escape(contents, unquote: true) quote bind_quoted: [context: context, contents: contents, name: name] do def unquote(name)(unquote(context)) do unquote(contents) end end end @doc """ Defines a test """ defmacro test(message, context \\ quote(do: _), contents) do contents = case contents do [do: block] -> quote do unquote(block) :ok end _ -> quote do try(unquote(contents)) :ok end end context = Macro.escape(context) contents = Macro.escape(contents, unquote: true) name = message |> String.replace(" ", "_") |> String.replace(~r/[^A-Za-z0-9]/, "") name = String.to_atom("__elixirscript_test_case_#{name}") quote bind_quoted: [context: context, contents: contents, message: message, name: name] do def unquote(name)() do %{ message: unquote(message), test: fn(context) -> unquote(contents) end } end end end end