Skip to content

Commit

Permalink
Merge ad68d08 into e1d263a
Browse files Browse the repository at this point in the history
  • Loading branch information
joaomdmoura committed Mar 30, 2018
2 parents e1d263a + ad68d08 commit 9943729
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# ChangeLog

## WIP Version
- Adding support for wildcard transitions - [Pull Request](https://github.com/joaomdmoura/machinery/pull/32)

## 0.13.0
- Adding basic auth to Machinery Dashboard - [Pull Request](https://github.com/joaomdmoura/machinery/pull/30)
Expand Down
20 changes: 16 additions & 4 deletions lib/machinery/transition.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ defmodule Machinery.Transition do
"""
@spec declared_transition?(list, atom, atom) :: boolean
def declared_transition?(transitions, current_state, next_state) do
case Map.fetch(transitions, current_state) do
{:ok, [_|_] = declared_states} -> Enum.member?(declared_states, next_state)
{:ok, declared_state} -> declared_state == next_state
:error -> false
if matches_wildcard?(transitions, next_state) do
true
else
matches_transition?(transitions, current_state, next_state)
end
end

Expand Down Expand Up @@ -59,6 +59,18 @@ defmodule Machinery.Transition do
run_or_fallback(&module.persist/2, &persist_fallback/3, struct, state)
end

defp matches_wildcard?(transitions, next_state) do
matches_transition?(transitions, "*", next_state)
end

defp matches_transition?(transitions, current_state, next_state) do
case Map.fetch(transitions, current_state) do
{:ok, [_|_] = declared_states} -> Enum.member?(declared_states, next_state)
{:ok, declared_state} -> declared_state == next_state
:error -> false
end
end

# Private function that receives a function, a callback,
# a struct and the related state. It tries to execute the function,
# rescue for a couple of specific Exceptions and passes it forward
Expand Down
22 changes: 16 additions & 6 deletions test/machinery/transition_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,22 @@ defmodule MachineryTest.TransitionTest do

test "declared_transition?/3 based on a map of transitions, current and next state" do
transitions = %{
created: [:partial, :completed],
partial: :completed
"created" => ["partial", "completed"],
"partial" => "completed"
}
assert Transition.declared_transition?(transitions, :created, :partial)
assert Transition.declared_transition?(transitions, :created, :completed)
assert Transition.declared_transition?(transitions, :partial, :completed)
refute Transition.declared_transition?(transitions, :partial, :created)
assert Transition.declared_transition?(transitions, "created", "partial")
assert Transition.declared_transition?(transitions, "created", "completed")
assert Transition.declared_transition?(transitions, "partial", "completed")
refute Transition.declared_transition?(transitions, "partial", "created")
end

test "declared_transition?/3 for a declared transition that allows transition for any state" do
transitions = %{
"created" => "completed",
"*" =>"canceled"
}
assert Transition.declared_transition?(transitions, "created", "completed")
assert Transition.declared_transition?(transitions, "created", "canceled")
assert Transition.declared_transition?(transitions, "completed", "canceled")
end
end
10 changes: 10 additions & 0 deletions test/machinery_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ defmodule MachineryTest do
assert {:error, "Transition to this state isn't declared."} = Machinery.transition_to(completed_struct, TestStateMachine, "created")
end

test "Wildcard transitions should be valid" do
created_struct = %TestStruct{state: "created", missing_fields: false}
partial_struct = %TestStruct{state: "partial", missing_fields: false}
completed_struct = %TestStruct{state: "completed"}

assert {:ok, %TestStruct{state: "canceled", missing_fields: false}} = Machinery.transition_to(created_struct, TestStateMachine, "canceled")
assert {:ok, %TestStruct{state: "canceled", missing_fields: false}} = Machinery.transition_to(partial_struct, TestStateMachine, "canceled")
assert {:ok, %TestStruct{state: "canceled"}} = Machinery.transition_to(completed_struct, TestStateMachine, "canceled")
end

test "Guard functions should be executed before moving the resource to the next state" do
struct = %TestStruct{state: "created", missing_fields: true}
assert {:error, "Transition not completed, blocked by guard function."} = Machinery.transition_to(struct, TestStateMachineWithGuard, "completed")
Expand Down
5 changes: 3 additions & 2 deletions test/support/test_state_machine.exs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
defmodule MachineryTest.TestStateMachine do
use Machinery,
states: ["created", "partial", "completed"],
states: ["created", "partial", "completed", "canceled"],
transitions: %{
"created" => ["partial", "completed"],
"partial" => "completed"
"partial" => "completed",
"*" => "canceled"
}

def before_transition(struct, "partial") do
Expand Down

0 comments on commit 9943729

Please sign in to comment.