Skip to content

Commit db76909

Browse files
fix: define replaced Elixir module macros using defmacro (#104)
1 parent ac567d7 commit db76909

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

lib/mimic/module.ex

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,9 @@ defmodule Mimic.Module do
117117
mimic_info = module_mimic_info(opts)
118118
mimic_behaviours = generate_mimic_behaviours(module)
119119
mimic_functions = generate_mimic_functions(module)
120+
mimic_macros = generate_mimic_macros(module)
120121
mimic_struct = generate_mimic_struct(module)
121-
quoted = [mimic_info, mimic_struct | mimic_behaviours ++ mimic_functions]
122+
quoted = [mimic_info, mimic_struct | mimic_behaviours ++ mimic_functions ++ mimic_macros]
122123
Module.create(module, quoted, Macro.Env.location(__ENV__))
123124
module
124125
end
@@ -175,7 +176,14 @@ defmodule Mimic.Module do
175176
defp generate_mimic_functions(module) do
176177
internal_functions = [__info__: 1, module_info: 0, module_info: 1]
177178

178-
for {fn_name, arity} <- module.module_info(:exports),
179+
functions =
180+
if function_exported?(module, :__info__, 1) do
181+
module.__info__(:functions)
182+
else
183+
module.module_info(:exports)
184+
end
185+
186+
for {fn_name, arity} <- functions,
179187
{fn_name, arity} not in internal_functions do
180188
args = Macro.generate_arguments(arity, module)
181189

@@ -187,6 +195,26 @@ defmodule Mimic.Module do
187195
end
188196
end
189197

198+
defp generate_mimic_macros(module) do
199+
macros =
200+
if function_exported?(module, :__info__, 1) do
201+
module.__info__(:macros)
202+
else
203+
[]
204+
end
205+
206+
for {macro_name, arity} <- macros do
207+
args = Macro.generate_arguments(arity, module)
208+
macro_fun = String.to_existing_atom("MACRO-#{macro_name}")
209+
210+
quote do
211+
defmacro unquote(macro_name)(unquote_splicing(args)) do
212+
Server.apply(__MODULE__, unquote(macro_fun), [__CALLER__ | unquote(args)])
213+
end
214+
end
215+
end
216+
end
217+
190218
defp generate_mimic_behaviours(module) do
191219
module.module_info(:attributes)
192220
|> Keyword.get_values(:behaviour)

test/mimic_test.exs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,17 @@ defmodule Mimic.Test do
489489
expect(Calculator, :add, 0, fn x, y -> x + y end)
490490
end
491491
end
492+
493+
test "macros" do
494+
expect(Calculator, :add, fn x, _y -> x + 2 end)
495+
496+
quote do
497+
require Calculator
498+
499+
assert Calculator.add(4, 2) == Calculator.add_macro(4, 2)
500+
end
501+
|> Code.eval_quoted()
502+
end
492503
end
493504

494505
describe "expect/4 global mode" do

test/support/test_modules.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
defmodule AddAdapter do
22
@moduledoc false
33
@callback add(number(), number()) :: number()
4+
@macrocallback add_macro(Macro.t(), Macro.t()) :: Macro.t()
5+
@optional_callbacks add_macro: 2
46
end
57

68
defmodule MultAdapter do
@@ -13,6 +15,7 @@ defmodule Calculator do
1315
@behaviour AddAdapter
1416
@behaviour MultAdapter
1517
def add(x, y), do: x + y
18+
defmacro add_macro(x, y), do: {:+, [], [x, y]}
1619
def mult(x, y), do: x * y
1720
end
1821

0 commit comments

Comments
 (0)