diff --git a/lib/mimic/module.ex b/lib/mimic/module.ex index 723d669..a46abef 100644 --- a/lib/mimic/module.ex +++ b/lib/mimic/module.ex @@ -119,7 +119,9 @@ defmodule Mimic.Module do mimic_functions = generate_mimic_functions(module) mimic_macros = generate_mimic_macros(module) mimic_struct = generate_mimic_struct(module) + quoted = [mimic_info, mimic_struct | mimic_behaviours ++ mimic_functions ++ mimic_macros] + Module.create(module, quoted, Macro.Env.location(__ENV__)) module end @@ -175,16 +177,11 @@ defmodule Mimic.Module do defp generate_mimic_functions(module) do internal_functions = [__info__: 1, module_info: 0, module_info: 1] - - functions = - if function_exported?(module, :__info__, 1) do - module.__info__(:functions) - else - module.module_info(:exports) - end + macro_functions = macro_functions(module) + functions = module.module_info(:exports) for {fn_name, arity} <- functions, - {fn_name, arity} not in internal_functions do + {fn_name, arity} not in (internal_functions ++ macro_functions) do args = Macro.generate_arguments(arity, module) quote do @@ -195,6 +192,16 @@ defmodule Mimic.Module do end end + defp macro_functions(module) do + if function_exported?(module, :__info__, 1) do + :macros + |> module.__info__() + |> Enum.map(fn {name, arity} -> {String.to_atom("MACRO-#{name}"), arity + 1} end) + else + [] + end + end + defp generate_mimic_macros(module) do macros = if function_exported?(module, :__info__, 1) do diff --git a/test/mimic_test.exs b/test/mimic_test.exs index 7fdc37d..82dc7be 100644 --- a/test/mimic_test.exs +++ b/test/mimic_test.exs @@ -1006,6 +1006,8 @@ defmodule Mimic.Test do end describe "behaviours" do + setup :set_mimic_private + test "copies behaviour attributes" do behaviours = Calculator.module_info(:attributes) @@ -1015,6 +1017,15 @@ defmodule Mimic.Test do assert AddAdapter in behaviours assert MultAdapter in behaviours end + + test "Regression test for PR #105: doesn't remove behaviour_info/1" do + Mimic.copy(MultAdapter) + + stub(MultAdapter) + expect(MultAdapter, :behaviour_info, fn :callbacks -> [mult: 2] end) + + assert MultAdapter.behaviour_info(:callbacks) == [mult: 2] + end end describe "copy/1 with duplicates" do