Last active
March 16, 2022 19:58
-
-
Save thebugcatcher/1329b1caf8d28a36b40e489b2d898367 to your computer and use it in GitHub Desktop.
Elixir helper module to test whether a function is delegated to another module.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule GenTestUtils.Module do | |
@moduledoc """ | |
Helper functions to test parts of an Elixir module | |
""" | |
require ExUnit.Assertions | |
@doc """ | |
Tests whether a module delegates a given MFA to another given MFA | |
# Usage | |
```elixir | |
defmodule GenTestUtils.ModuleA do | |
def hello(:world), do: "world" | |
end | |
``` | |
```elixir | |
defmodule GenTestUtils.ModuleB do | |
defdelegate hello(arg), to: GenTestUtils.ModuleA | |
end | |
``` | |
```elixir | |
# in test/**/*_test.exs | |
import GenTestUtils.Module | |
test "B delegates `hello/1` to A" do | |
assert_delegates_function( | |
{GenTestUtils.ModuleB, :hello, 1}, | |
to: {GenTestUtils.ModuleA, :hello, 1} | |
) | |
end | |
``` | |
# Examples | |
iex> GenTestUtils.Module.assert_delegates_function( | |
...> {GenTestUtils.ModuleB, :hello, 1}, | |
...> to: {GenTestUtils.ModuleA, :hello, 1} | |
...> ) | |
true | |
""" | |
def assert_delegates_function({module, function, arity}, to: {m, f, a}) do | |
ExUnit.Assertions.assert( | |
delegates_function?({module, function, arity}, to: {m, f, a}), | |
"Expected #{module}.#{function}/#{arity} to be delegated to " <> | |
"#{m}.#{f}/#{a}, but it wasn't the case" | |
) | |
end | |
@doc """ | |
Returns `true` or `false` whether a given MFA is delegated to another given | |
MFA. | |
# Usage | |
```elixir | |
defmodule GenTestUtils.ModuleA do | |
def hello(:world), do: "world" | |
end | |
``` | |
```elixir | |
defmodule GenTestUtils.ModuleB do | |
defdelegate hello(arg), to: GenTestUtils.ModuleA | |
end | |
``` | |
# Examples | |
iex> GenTestUtils.Module.delegates_function?( | |
...> {GenTestUtils.ModuleB, :hello, 1}, | |
...> to: {GenTestUtils.ModuleA, :hello, 1} | |
...> ) | |
true | |
iex> GenTestUtils.Module.delegates_function?( | |
...> {GenTestUtils.ModuleB, :hello2, 1}, | |
...> to: {GenTestUtils.ModuleA, :hello2, 1} | |
...> ) | |
false | |
""" | |
def delegates_function?({module, function, arity}, to: {m, f, a}) do | |
{_, _, _, _, _, _, docs} = Code.fetch_docs(module) | |
docs | |
|> Enum.find(fn | |
{{:function, ^function, ^arity}, _, _, _, %{delegate_to: {^m, ^f, ^a}}} -> | |
true | |
_ -> | |
false | |
end) | |
|> is_nil() | |
|> Kernel.not() | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment