Skip to content

Commit

Permalink
Lists in sequences (#227)
Browse files Browse the repository at this point in the history
Can use lists in sequences. Fixes #223 

```
  def user_factory do
    %MyApp.User{
      name: "Jane Smith",
      email: sequence(:email, &"email-#{&1}@example.com"),
      role: sequence(:role, ["admin", "user", "other"]),
    }
  end
```
  • Loading branch information
suhrawardi authored and germsvel committed Oct 20, 2017
1 parent 3776a51 commit 779b4c8
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ defmodule MyApp.Factory do
%MyApp.User{
name: "Jane Smith",
email: sequence(:email, &"email-#{&1}@example.com"),
role: sequence(:role, ["admin", "user", "other"]),
}
end

Expand Down
4 changes: 3 additions & 1 deletion lib/ex_machina.ex
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,9 @@ defmodule ExMachina do
def user_factory do
%{
# Will generate "[email protected]" then "[email protected]", etc.
email: sequence(:email, &"me-\#{&1}@foo.com")
email: sequence(:email, &"me-\#{&1}@foo.com"),
# Will generate "admin" then "user", "other", "admin" etc.
role: sequence(:role, ["admin", "user", "other"])
}
end
"""
Expand Down
21 changes: 21 additions & 0 deletions lib/ex_machina/sequence.ex
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ defmodule ExMachina.Sequence do
ExMachina.Sequence.next("joe") # resets so the return value is "joe0"
You can use list as well
ExMachina.Sequence.next(["A", "B"]) # "A"
ExMachina.Sequence.next(["A", "B"]) # "B"
Sequence.reset
ExMachina.Sequence.next(["A", "B"]) # resets so the return value is "A"
If you want to reset sequences at the beginning of every test, put it in a
`setup` block in your test.
Expand All @@ -49,6 +58,18 @@ defmodule ExMachina.Sequence do
)
end

@doc false
def next(sequence_name, [_|_] = list) do
length = length(list)
Agent.get_and_update __MODULE__, fn(sequences) ->
current_value = Map.get(sequences, sequence_name, 0)
index = rem(current_value, length)
new_sequences = Map.put(sequences, sequence_name, index + 1)
{value, _} = List.pop_at(list, index)
{value, new_sequences}
end
end

@doc false
def next(sequence_name, formatter) do
Agent.get_and_update __MODULE__, fn(sequences) ->
Expand Down
7 changes: 7 additions & 0 deletions test/ex_machina/sequence_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ defmodule ExMachina.SequenceTest do
assert "joe1" == Sequence.next(:name, &"joe#{&1}")
end

test "traverses a list each time it is called" do
assert "A" == Sequence.next(:name, ["A", "B", "C"])
assert "B" == Sequence.next(:name, ["A", "B", "C"])
assert "C" == Sequence.next(:name, ["A", "B", "C"])
assert "A" == Sequence.next(:name, ["A", "B", "C"])
end

test "updates different sequences independently" do
assert "joe0" == Sequence.next(:name, &"joe#{&1}")
assert "joe1" == Sequence.next(:name, &"joe#{&1}")
Expand Down

0 comments on commit 779b4c8

Please sign in to comment.