diff --git a/fixtures/macro.ex b/fixtures/macro.ex new file mode 100644 index 0000000..6d019a7 --- /dev/null +++ b/fixtures/macro.ex @@ -0,0 +1,21 @@ +defmodule Rewire.Macro do + defmacro __using__(opts) do + case opts do + [use_alias: true] -> + quote do + alias Rewire.Hello + alias Rewire.Macro + end + + _ -> + quote do + import Rewire.Hello + import Rewire.Macro + end + end + end + + def good_afternoon do + "good afternoon" + end +end diff --git a/fixtures/module_with_macro.ex b/fixtures/module_with_macro.ex new file mode 100644 index 0000000..b355a40 --- /dev/null +++ b/fixtures/module_with_macro.ex @@ -0,0 +1,11 @@ +defmodule Rewire.ModuleWithMacro do + use Rewire.Macro + + def hello_passthrough do + hello() + end + + def good_afternoon_passthrough do + good_afternoon() + end +end diff --git a/fixtures/module_with_macro_with_args.ex b/fixtures/module_with_macro_with_args.ex new file mode 100644 index 0000000..4d45d5b --- /dev/null +++ b/fixtures/module_with_macro_with_args.ex @@ -0,0 +1,11 @@ +defmodule Rewire.ModuleWithMacroWithArgs do + use Rewire.Macro, use_alias: true + + def hello_passthrough do + Hello.hello() + end + + def good_afternoon_passthrough do + Macro.good_afternoon() + end +end diff --git a/lib/rewire/module.ex b/lib/rewire/module.ex index d6ec3c8..76f5c19 100644 --- a/lib/rewire/module.ex +++ b/lib/rewire/module.ex @@ -143,6 +143,14 @@ defmodule Rewire.Module do ) end + defp rewrite(use_ast = {:use, _l1, [{:__aliases__, _l2, _macro_ast} | _args]}, acc) do + {:__block__, [], [{:__block__, [], [req, using]}]} = Macro.expand(use_ast, __ENV__) + {:require, _counter_ctx, [required_module]} = req + env = %{__ENV__ | requires: [required_module] ++ __ENV__.requires} + + {Macro.expand(using, env), acc} + end + # Removes a single alias (ie `alias A.A`) pointing to an overriden module dependency. Keeps the others. defp rewrite( expr = {:alias, _, [{:__aliases__, _, module_ast}]}, diff --git a/test/rewire_alias_test.exs b/test/rewire_alias_test.exs index 358b577..b32051c 100644 --- a/test/rewire_alias_test.exs +++ b/test/rewire_alias_test.exs @@ -34,5 +34,15 @@ defmodule RewireAliasTest do assert ModuleWithDependency.bye() == "au revoir" end end + + test "works for macro" do + rewire Rewire.ModuleWithMacro, Hello: Bonjour, Macro: BonApresMidi + assert ModuleWithMacro.hello_passthrough() == "bonjour" + assert ModuleWithMacro.good_afternoon_passthrough() == "bon apres-midi" + + rewire Rewire.ModuleWithMacroWithArgs, Hello: Bonjour, Macro: BonApresMidi + assert ModuleWithMacroWithArgs.hello_passthrough() == "bonjour" + assert ModuleWithMacroWithArgs.good_afternoon_passthrough() == "bon apres-midi" + end end end diff --git a/test/test_helper.exs b/test/test_helper.exs index c99779b..e377e7e 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -8,6 +8,10 @@ defmodule AuRevoir do def bye(), do: "au revoir" end +defmodule BonApresMidi do + def good_afternoon(), do: "bon apres-midi" +end + Mox.defmock(HelloMock, for: Rewire.Hello) defmodule TestHelpers do