ExZample v0.10.1 ExZample behaviour View Source
ExZample is a factory library based on Elixir behaviours.
Link to this section Summary
Functions
Builds a struct with given factory_or_alias
module.
Same as build/2
, but returns a list with where the size is the given
count
.
Same as build/2
, but returns a tuple with a pair of structs.
Creates aliases for your factories to simplify the build calls.
Same as config_aliases/1
, but you can define a different scope.
Creates a sequence with the given name
.
Same as create_sequence/1
, but you can define a different scope or a
sequence function.
Same as create_sequence/1
, but you can define a different scope and a
sequence function.
Utiliy function that you can define severial settings that ExZample
will look
for before executing their functions.
Inserts in the repository the example built by the factory_or_alias
module.
Same as insert/2
, but the attributes
and opts
are explicit
separated.
Same as insert/2
, but returns a list with where the size is the given
count
.
Same as insert/3
, but returns a list with where the size is the given
count
.
Same as insert/2
, but returns a tuple with a pair of structs.
Same as insert/3
, but returns a tuple with a pair of structs.
Builds a map with given factory_or_alias
module. Has the same mechanism of
build/2
.
Same as map_for/2
, but returns a list with where the size is the given
count
.
Same as map_for/2
, but returns a tuple with a pair of maps.
Builds a map with string keys given factory_or_alias
module. Has the same mechanism of
build/2
. Useful to simulate request parameters in a plug or phoenix
controller.
Same as params_for/2
, but returns a list with where the size is the given
count
.
Same as params_for/2
, but returns a tuple with a pair of maps.
Returns the current counter registered in the given sequence name
.
Same as sequence/1
, but returns a list of where the number is determined by
the given count
.
Same as sequence/1
, but returns a pair of sequence items.
Link to this section Types
Link to this section Functions
Builds a struct with given factory_or_alias
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.
If will override the generated data with the given attrs
.
Examples
iex> ExZample.build(User)
%ExZample.User{}
iex> ExZample.build(UserFactory)
%ExZample.User{age: 21, email: "test@test.test", first_name: "First Name", id: 1, last_name: "Last Name"}
iex> ExZample.build(:book)
%ExZample.Book{code: "1321", title: "The Book's Title"}
iex> ExZample.build(User, age: 45)
%ExZample.User{age: 45}
iex> ExZample.build(UserFactory, age: 45)
%ExZample.User{age: 45, email: "test@test.test", first_name: "First Name", id: 1, last_name: "Last Name"}
iex> ExZample.build(:book, code: "007")
%ExZample.Book{code: "007", title: "The Book's Title"}
build_list(count, factory, attrs \\ nil)
View Source (since 0.2.0)build_list(count :: pos_integer(), factory(), attrs :: Enum.t() | nil) :: [ struct() ]
Same as build/2
, but returns a list with where the size is the given
count
.
Examples
iex> ExZample.build_list(3, User)
[%ExZample.User{}, %ExZample.User{}, %ExZample.User{}]
iex> ExZample.build_list(3, :book)
[%ExZample.Book{},%ExZample.Book{}, %ExZample.Book{}]
iex> ExZample.build_list(3, User, age: 45)
[%ExZample.User{age: 45}, %ExZample.User{age: 45}, %ExZample.User{age: 45}]
iex> ExZample.build_list(3, :book, code: "007")
[%ExZample.Book{code: "007"},%ExZample.Book{code: "007"}, %ExZample.Book{code: "007"}]
Same as build/2
, but returns a tuple with a pair of structs.
Examples
iex> ExZample.build_pair(User)
{%ExZample.User{}, %ExZample.User{}}
iex> ExZample.build_pair(:book)
{%ExZample.Book{},%ExZample.Book{}}
iex> ExZample.build_pair(User, age: 45)
{%ExZample.User{age: 45}, %ExZample.User{age: 45}}
iex> ExZample.build_pair(:book, code: "007")
{%ExZample.Book{code: "007"},%ExZample.Book{code: "007"}}
Creates aliases for your factories to simplify the build calls.
A aliases
should be a map with atom keys and values as factory
compatible
modules. If you call with repeated keys this function will fail. This function
is ideal to be called once, for example in your test_helper.ex
file.
Examples
iex> ExZample.config_aliases(%{user: UserFactory})
...> ExZample.build(:user)
%User{age: 21, email: "test@test.test", first_name: "First Name", id: 1, last_name: "Last Name"}
Same as config_aliases/1
, but you can define a different scope.
This function is specially useful for umbrella apps where each app can define
their factories without leaking any aliases to other apps. You can enforce the
current scope with ex_zample/1
.
Examples
iex> ExZample.config_aliases(:my_app, %{user: UserFactory})
...> ExZample.ex_zample(%{ex_zample_scope: :my_app})
...> ExZample.build(:user)
%User{age: 21, email: "test@test.test", first_name: "First Name", id: 1, last_name: "Last Name"}
create_sequence(name)
View Source (since 0.4.0)create_sequence(atom()) :: :ok
Creates a sequence with the given name
.
A sequence is global runtime counter that can be invoked with sequence/1
. The
default counter starts from 1
and increments 1
by 1
.
Examples
iex> ExZample.create_sequence(:customer_id)
...> Enum.map(1..10, fn _ -> ExZample.sequence(:customer_id) end)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
create_sequence(scope_or_name, sequence_fun_or_name)
View Source (since 0.4.0)create_sequence( scope_or_name :: atom(), sequence_fun_or_name :: sequence_fun() | atom() ) :: :ok
Same as create_sequence/1
, but you can define a different scope or a
sequence function.
When use with scope
and name
you define scoped global counter, it's
useful for umbrella apps for example.
When you use name
and sequence_fun
, the given function will receive the
counter and then you can transform in anything you want.
Examples
iex> ExZample.create_sequence(:my_app, :customer_id)
...> ExZample.ex_zample(%{ex_zample_scope: :my_app})
...> ExZample.sequence(:customer_id)
1
iex> ExZample.create_sequence(:customer_id, &("customer_" <> to_string(&1)))
...> Enum.map(1..3, fn _ -> ExZample.sequence(:customer_id) end)
["customer_1", "customer_2", "customer_3"]
create_sequence(scope, name, sequence_fun)
View Source (since 0.4.0)create_sequence(atom(), atom(), sequence_fun()) :: :ok
Same as create_sequence/1
, but you can define a different scope and a
sequence function.
The scope
is where where your global counter will lives, useful for umbrella
apps for example. The given sequence_fun
will receive the counter and then
you can transform in anything you want.
Examples
iex> ExZample.create_sequence(:my_app, :customer_id, &("customer_" <> to_string(&1)))
...> ExZample.ex_zample(%{ex_zample_scope: :my_app})
...> Enum.map(1..3, fn _ -> ExZample.sequence(:customer_id) end)
["customer_1", "customer_2", "customer_3"]
Utiliy function that you can define severial settings that ExZample
will look
for before executing their functions.
Options
:ex_zample_scope
, the scope that ExZample should look up for aliases. If no scope is defined,:global
is the default scope.:ex_zample_ecto_repo
, the Ecto repo that ExZample should use to run their insert functions.
This function works well with setup/1
callback of ExUnit
and @tags
.
For example:
defmodule MyTest do
use ExUnit.Case
import ExZample
@moduletag ex_zample_scope: :my_app
setup :ex_zample
test "returns a user" do
assert %User{} == build(:user)
end
end
In the example above, ExZample
will look for a factory registered in alias
:user
in the :my_app
scope.
Inserts in the repository the example built by the factory_or_alias
module.
If the given factory exports the c:repo/0
function it will use it call the
insert!
function. Beyond that, it works similar as build/2
.
If will override the generated data with the given attributes
.
Options
ecto_opts
, when given, it will be forwarded to the second argument ofEcto.Repo.insert/2
Examples
iex> ExZample.insert(:player)
%ExZample.RPG.Player{}
iex> ExZample.insert(:player, email: "testmail")
%ExZample.RPG.Player{email: "testmail"}
Same as insert/2
, but the attributes
and opts
are explicit
separated.
Options
ecto_opts
, when given, it will be forwarded to the second argument ofEcto.Repo.insert/2
Examples
iex> ExZample.insert(:player, %{email: "testmail"}, ecto_opts: [prefix: "private"])
%ExZample.RPG.Player{email: "testmail"}
insert_list(count, factory, attributes \\ nil)
View Source (since 0.10.0)insert_list(pos_integer(), factory(), Enum.t() | nil) :: [struct()]
Same as insert/2
, but returns a list with where the size is the given
count
.
Examples
iex> ExZample.insert_list(3, :character)
[%ExZample.RPG.Character{}, %ExZample.RPG.Character{}, %ExZample.RPG.Character{}]
iex> ExZample.insert_list(3, :character, name: "Todd")
[%ExZample.RPG.Character{name: "Todd"}, %ExZample.RPG.Character{name: "Todd"}, %ExZample.RPG.Character{name: "Todd"}]
insert_list(count, factory, attributes, opts)
View Source (since 0.10.0)insert_list(pos_integer(), factory(), Enum.t() | nil, Keyword.t()) :: [struct()]
Same as insert/3
, but returns a list with where the size is the given
count
.
Examples
iex> ExZample.insert_list(3, :character, %{name: "Todd"}, ecto_opts: [prefix: "private"])
[%ExZample.RPG.Character{name: "Todd"}, %ExZample.RPG.Character{name: "Todd"}, %ExZample.RPG.Character{name: "Todd"}]
Same as insert/2
, but returns a tuple with a pair of structs.
Examples
iex> ExZample.insert_pair(:character)
{%ExZample.RPG.Character{}, %ExZample.RPG.Character{}}
iex> ExZample.insert_pair(:character, name: "Todd")
{%ExZample.RPG.Character{name: "Todd"}, %ExZample.RPG.Character{name: "Todd"}}
Same as insert/3
, but returns a tuple with a pair of structs.
Examples
iex> ExZample.insert_pair(:character, %{name: "Todd"}, ecto_opts: [prefix: "private"])
{%ExZample.RPG.Character{name: "Todd"}, %ExZample.RPG.Character{name: "Todd"}}
Builds a map with given factory_or_alias
module. Has the same mechanism of
build/2
.
Examples
iex> ExZample.map_for(User)
%{age: nil, email: nil, first_name: nil, id: nil, last_name: nil}
iex> ExZample.map_for(UserFactory)
%{age: 21, email: "test@test.test", first_name: "First Name", id: 1, last_name: "Last Name"}
iex> ExZample.map_for(:book)
%{code: "1321", title: "The Book's Title"}
iex> ExZample.map_for(User, age: 45)
%{age: 45, email: nil, first_name: nil, id: nil, last_name: nil}
iex> ExZample.map_for(UserFactory, age: 45)
%{age: 45, email: "test@test.test", first_name: "First Name", id: 1, last_name: "Last Name"}
iex> ExZample.map_for(:book, code: "007")
%{code: "007", title: "The Book's Title"}
map_list_for(count, factory, attrs \\ nil)
View Source (since 0.8.0)map_list_for(count :: pos_integer(), factory(), attrs :: Enum.t() | nil) :: [ struct() ]
Same as map_for/2
, but returns a list with where the size is the given
count
.
Examples
iex> ExZample.map_list_for(3, User)
[%{age: nil, email: nil, first_name: nil, id: nil, last_name: nil},
%{age: nil, email: nil, first_name: nil, id: nil, last_name: nil},
%{age: nil, email: nil, first_name: nil, id: nil, last_name: nil}]
iex> ExZample.map_list_for(3, :book)
[%{code: "1321", title: "The Book's Title"},
%{code: "1321", title: "The Book's Title"},
%{code: "1321", title: "The Book's Title"}]
iex> ExZample.map_list_for(3, User, age: 45)
[%{age: 45, email: nil, first_name: nil, id: nil, last_name: nil},
%{age: 45, email: nil, first_name: nil, id: nil, last_name: nil},
%{age: 45, email: nil, first_name: nil, id: nil, last_name: nil}]
iex> ExZample.map_list_for(3, :book, code: "007")
[%{code: "007", title: "The Book's Title"},
%{code: "007", title: "The Book's Title"},
%{code: "007", title: "The Book's Title"}]
Same as map_for/2
, but returns a tuple with a pair of maps.
Examples
iex> ExZample.map_pair_for(User)
{%{age: nil, email: nil, first_name: nil, id: nil, last_name: nil},
%{age: nil, email: nil, first_name: nil, id: nil, last_name: nil}}
iex> ExZample.map_pair_for(:book)
{%{code: "1321", title: "The Book's Title"},
%{code: "1321", title: "The Book's Title"}}
iex> ExZample.map_pair_for(User, age: 45)
{%{age: 45, email: nil, first_name: nil, id: nil, last_name: nil},
%{age: 45, email: nil, first_name: nil, id: nil, last_name: nil}}
iex> ExZample.map_pair_for(:book, code: "007")
{%{code: "007", title: "The Book's Title"},
%{code: "007", title: "The Book's Title"}}
Builds a map with string keys given factory_or_alias
module. Has the same mechanism of
build/2
. Useful to simulate request parameters in a plug or phoenix
controller.
Examples
iex> ExZample.params_for(User)
%{"age" => nil, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil}
iex> ExZample.params_for(UserFactory)
%{"age" => 21, "email" => "test@test.test", "first_name" => "First Name", "id" => 1, "last_name" => "Last Name"}
iex> ExZample.params_for(:book)
%{"code" => "1321", "title" => "The Book's Title"}
iex> ExZample.params_for(User, age: 45)
%{"age" => 45, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil}
iex> ExZample.params_for(UserFactory, age: 45)
%{"age" => 45, "email" => "test@test.test", "first_name" => "First Name", "id" => 1, "last_name" => "Last Name"}
iex> ExZample.params_for(:book, code: "007")
%{"code" => "007", "title" => "The Book's Title"}
params_list_for(count, factory, attrs \\ nil)
View Source (since 0.9.0)params_list_for(count :: pos_integer(), factory(), attrs :: Enum.t() | nil) :: [ struct() ]
Same as params_for/2
, but returns a list with where the size is the given
count
.
Examples
iex> ExZample.params_list_for(3, User)
[%{"age" => nil, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil},
%{"age" => nil, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil},
%{"age" => nil, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil}]
iex> ExZample.params_list_for(3, :book)
[%{"code" => "1321", "title" => "The Book's Title"},
%{"code" => "1321", "title" => "The Book's Title"},
%{"code" => "1321", "title" => "The Book's Title"}]
iex> ExZample.params_list_for(3, User, age: 45)
[%{"age" => 45, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil},
%{"age" => 45, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil},
%{"age" => 45, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil}]
iex> ExZample.params_list_for(3, :book, code: "007")
[%{"code" => "007", "title" => "The Book's Title"},
%{"code" => "007", "title" => "The Book's Title"},
%{"code" => "007", "title" => "The Book's Title"}]
Same as params_for/2
, but returns a tuple with a pair of maps.
Examples
iex> ExZample.params_pair_for(User)
{%{"age" => nil, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil},
%{"age" => nil, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil}}
iex> ExZample.params_pair_for(:book)
{%{"code" => "1321", "title" => "The Book's Title"},
%{"code" => "1321", "title" => "The Book's Title"}}
iex> ExZample.params_pair_for(User, age: 45)
{%{"age" => 45, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil},
%{"age" => 45, "email" => nil, "first_name" => nil, "id" => nil, "last_name" => nil}}
iex> ExZample.params_pair_for(:book, code: "007")
{%{"code" => "007", "title" => "The Book's Title"},
%{"code" => "007", "title" => "The Book's Title"}}
Returns the current counter registered in the given sequence name
.
Examples
iex> ExZample.create_sequence(:customer_id, &("customer_" <> to_string(&1)))
...> ExZample.sequence(:customer_id)
"customer_1"
sequence_list(count, name)
View Source (since 0.4.0)sequence_list(pos_integer(), atom()) :: [term()]
Same as sequence/1
, but returns a list of where the number is determined by
the given count
.
Examples
iex> ExZample.create_sequence(:customer_id, &("customer_" <> to_string(&1)))
...> ExZample.sequence_list(3, :customer_id)
["customer_1", "customer_2", "customer_3"]
Same as sequence/1
, but returns a pair of sequence items.
Examples
iex> ExZample.create_sequence(:customer_id, &("customer_" <> to_string(&1)))
...> ExZample.sequence_pair(:customer_id)
{"customer_1", "customer_2"}
Link to this section Callbacks
Invoked every time you insert your data using ExZample
module.
You need to return the Ecto Repo
module that ExZample should use
to insert records in database
This callback is optional if the goal is to use only in memory.
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.
Same as example/0
, but here you have the full control in how will build
your struct given the attributes.
The keyword list given in functions like build/2
are transformed in map
for your convenience and you need to return a struct.
You can have two scenarios when using this callback:
If you define
example/0
andexample/1
in same factory,example/0
will be prefered when you usebuild/1
. Theexample/1
will preferend if you use withbuild/2
.If you only implement
example/1
and usebuild/1
, your callback will invoked with an empty map.
This callback is optional.