Current section
Files
Jump to
Current section
Files
lib/ex_stub_generator.ex
defmodule ExStub.Generator do
@moduledoc """
Provide functions to generate a forwarding function, and the stub module.
This module is for internal use only.
"""
@doc """
Create a forwarding method
"""
def create_method({_, _, [{func_name, _, nil}| _]}, module),
do: create_method(func_name, 0, module)
def create_method({_, _, [{func_name, _, params}| _]}, module),
do: create_method(func_name, params |> Enum.count, module)
def create_method(func_name, params, module) do
func_params = create_params(params)
call = recording_call(func_name, params) |> Macro.to_string
"""
def #{func_name}(#{func_params}) do
#{call}
#{module}.#{func_name}(#{func_params})
end
"""
end
defp create_params(0), do: ""
defp create_params(num) do
params =
1..num
|> Enum.map(fn num ->
"p#{num}__"
end)
"#{Enum.join(params, ", ")}"
end
def recording_call(func, params) do
{:ok, param_string} = "[#{create_params(params)}]" |> Code.string_to_quoted
quote do
__MODULE__.__record_call__(unquote(func), unquote(param_string))
end
end
@doc """
Generate the stub module
"""
def generate_stub_module(stub_name, functions) do
"""
defmodule #{stub_name} do
#{gen_server_functions}
#{functions}
end
"""
end
defp gen_server_functions do
"""
def __record_call__(name, params) do
ExStub.Recorder.record_call(__MODULE__, name, params)
end
def __calls__ do
ExStub.Recorder.calls(__MODULE__)
end
"""
end
@doc """
Generate all the forwarding functions
"""
def generate_forwarding_functions(functions, module) do
functions
|> Enum.map(fn
{func_name, ar} ->
create_method(func_name, ar, module)
end)
end
@doc """
Convert module from string to AST
"""
def module_ast(module) do
{:ok, module_ast} = Code.string_to_quoted(module)
module_ast
end
end