Current section

Files

Jump to
ex_zample lib ex_zample.ex
Raw

lib/ex_zample.ex

defmodule ExZample do
@moduledoc """
ExZample is a factory library based on Elixir behaviours.
"""
@doc """
Invoked every time you build your data using `ExZample` module.
You need to return a struct with example values.
This callback is optional when the module given is a struct. It will use
the struct default values if no callback is given.
"""
@callback example() :: struct
@type factory :: module
@optional_callbacks example: 0
@doc """
Builds a struct with given `factory` module.
If the given factory exports the `example/0` function it will use to return
the struct and its values. Otherwise, if the module is a struct it will use
its default values.
## Examples
iex> ExZample.build(User)
%ExZample.User{}
iex> ExZample.build(Factories.User)
%ExZample.User{age: 21, email: "test@test.test", first_name: "First Name", id: 1, last_name: "Last Name"}
"""
@spec build(factory) :: struct
def build(factory) when is_atom(factory) do
cond do
function_exported?(factory, :example, 0) -> factory.example()
function_exported?(factory, :__struct__, 1) -> struct!(factory)
true -> raise ArgumentError, message: "#{inspect(factory)} is not a factory"
end
end
@doc """
Same as `build/1`, but overrides the struct values with the given `attrs`.
## Examples
iex> ExZample.build(User, age: 45)
%ExZample.User{age: 45}
iex> ExZample.build(Factories.User, age: 45)
%ExZample.User{age: 45, email: "test@test.test", first_name: "First Name", id: 1, last_name: "Last Name"}
"""
@spec build(factory, Enum.t()) :: struct
def build(factory, attrs) do
factory
|> build()
|> struct!(attrs)
end
end