Packages

`MapBot` builds Elixir Maps/Structs based on factory definitions and attributes.

Current section

Files

Jump to
map_bot lib map_bot.ex
Raw

lib/map_bot.ex

defmodule MapBot do
@moduledoc """
`MapBot` builds Elixir Maps/Structs based on factory definitions and attributes.
If you want to check how `MapBot` should be installed, configured and used please [check this out](https://hexdocs.pm/map_bot/).
In summary you should create your own Factory module such as this:
```elixir
defmodule YourApp.Factory do
use MapBot
@impl MapBot
def new(YouyApp.Car), do: %YouyApp.Car{model: "SUV", color: :black}
def new(:tomato), do: %{name: "Tomato", color: :red}
def new(:with_code_and_ref), do: %{code: &"CODE-\#{&1}", reference: &"REF-\#{&1}"}
end
defmodule YourApp.Car do
defstruct id: nil, model: nil, color: nil
end
```
For building your own maps and structs take a look on the function `MapBot.build/3`.
"""
@type factory :: module()
@type name :: module() | atom()
@type attributes :: map() | keyword()
@type result :: struct() | map()
@callback new(name) :: result
@doc """
Builds an Elixir Map or Struct.
## Examples
iex> YourApp.Factory.build(YourApp.Car)
%YourApp.Car{model: "SUV", color: :black}
iex> YourApp.Factory.build(YourApp.Car, color: :yellow)
%YourApp.Car{model: "SUV", color: :yellow}
iex> YourApp.Factory.build(YourApp.Car, %{color: :yellow})
%YourApp.Car{model: "SUV", color: :yellow}
iex> YourApp.Factory.build(:tomato)
%{name: "Tomato", color: :red}
iex> YourApp.Factory.build(:tomato, color: :green)
%{name: "Tomato", color: :green}
iex> YourApp.Factory.build(:tomato, %{color: :green})
%{name: "Tomato", color: :green}
iex> MapBot.Sequence.reset(123)
iex> YourApp.Factory.build(:with_code_and_ref)
%{code: "CODE-123", reference: "REF-123"}
"""
@spec build(factory, name, attributes) :: result
def build(factory, name, attrs) do
attrs = Map.new(attrs)
name
|> factory.new()
|> Map.merge(attrs)
|> MapBot.Sequence.apply()
end
defmacro __using__(_opts) do
quote do
@behaviour MapBot
@spec build(MapBot.name(), MapBot.attributes()) :: MapBot.result()
def build(name, attrs \\ []) do
MapBot.build(__MODULE__, name, attrs)
end
end
end
end