defmodule Dummy do
@moduledoc """
Documentation for Dummy.
"""
alias Dummy.CallArgumentsError
alias Dummy.Method
def apply_options(module, options) do
if options[:passthrough] == false do
:meck.new(module)
else
:meck.new(module, [:passthrough])
end
end
def is_called_function?(call_tuple, module, function) do
if elem(call_tuple, 0) == module and elem(call_tuple, 1) == function do
true
else
false
end
end
def get_call_args(module, function) do
last_call =
module
|> :meck.history()
|> Enum.filter(fn item ->
Dummy.is_called_function?(elem(item, 1), module, function)
end)
|> List.last()
if last_call != nil do
elem(elem(last_call, 1), 2)
else
[]
end
end
def assert_called(module, f, expected_args) do
if :meck.called(module, f, expected_args) do
true
else
call_args = Dummy.get_call_args(module, f)
raise CallArgumentsError, [expected_args, call_args]
end
end
defmacro called({{:., _, [module, f]}, _, expected_args}) do
quote do
Dummy.assert_called(unquote(module), unquote(f), unquote(expected_args))
end
end
@doc """
Mocks methods of a single module. Mocked methods return their
first argument by default and non-mocked methods are passed through.
"""
defmacro dummy(module_name, methods_list, options \\ [], do: test) do
quote do
module = unquote(module_name)
methods = unquote(methods_list)
apply_options(module, unquote(options))
for method <- methods, do: Method.replace(module, method)
try do
unquote(test)
after
:meck.unload(module)
end
end
end
end