Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing event kwargs to guards option #101

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/state_machines/branch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,10 @@ def matches?(object, query = {})
#
# branch.match(object, :on => :ignite) # => {:to => ..., :from => ..., :on => ...}
# branch.match(object, :on => :park) # => nil
def match(object, query = {})
def match(object, query = {}, **kwargs)
query.assert_valid_keys(:from, :to, :on, :guard)

if (match = match_query(query)) && matches_conditions?(object, query)
if (match = match_query(query)) && matches_conditions?(object, query, **kwargs)
match
end
end
Expand Down Expand Up @@ -176,9 +176,9 @@ def matches_requirement?(query, option, requirement)

# Verifies that the conditionals for this branch evaluate to true for the
# given object
def matches_conditions?(object, query)
def matches_conditions?(object, query, **kwargs)
query[:guard] == false ||
Array(if_condition).all? { |condition| evaluate_method(object, condition) } &&
Array(if_condition).all? { |condition| evaluate_method(object, condition, **kwargs) } &&
!Array(unless_condition).any? { |condition| evaluate_method(object, condition) }
end
end
Expand Down
9 changes: 7 additions & 2 deletions lib/state_machines/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class Event
# branches/transitions as the source
attr_reader :known_states

# Key-value args for event
attr_reader :kwargs

# Creates a new event within the context of the given machine
#
# Configuration options:
Expand All @@ -37,6 +40,7 @@ def initialize(machine, name, options = {}) #:nodoc:
@name = name
@qualified_name = machine.namespace ? :"#{name}_#{machine.namespace}" : name
@human_name = options[:human_name] || @name.to_s.tr('_', ' ')
@kwargs = {}
reset

# Output a warning if another event has a conflicting qualified name
Expand Down Expand Up @@ -123,7 +127,7 @@ def transition_for(object, requirements = {})
requirements[:from] = machine.states.match!(object).name unless (custom_from_state = requirements.include?(:from))

branches.each do |branch|
if (match = branch.match(object, requirements))
if (match = branch.match(object, requirements, **kwargs))
# Branch allows for the transition to occur
from = requirements[:from]
to = if match[:to].is_a?(LoopbackMatcher)
Expand All @@ -148,8 +152,9 @@ def transition_for(object, requirements = {})
#
# Any additional arguments are passed to the StateMachines::Transition#perform
# instance method.
def fire(object, *args)
def fire(object, *args, **kwargs)
machine.reset(object)
@kwargs = kwargs

if (transition = transition_for(object))
transition.perform(*args)
Expand Down
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
require 'minitest/reporters'
Minitest::Reporters.use! [Minitest::Reporters::ProgressReporter.new]

class StateMachinesTest < MiniTest::Test
class StateMachinesTest < Minitest::Test
def before_setup
super
StateMachines::Integrations.reset
Expand Down
2 changes: 1 addition & 1 deletion test/unit/branch/branch_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_should_have_a_state_requirement
end

def test_should_raise_an_exception_if_invalid_match_option_specified
exception = assert_raises(ArgumentError) { @branch.match(Object.new, invalid: true) }
exception = assert_raises(ArgumentError) { @branch.match(Object.new, {invalid: true}) }
assert_equal 'Unknown key: :invalid. Valid keys are: :from, :to, :on, :guard', exception.message
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def test_should_not_match_if_on_not_included
end

def test_should_be_nil_if_unmatched
assert_nil @branch.match(@object, from: :parked, to: :idling, on: :park)
assert_nil @branch.match(@object, {from: :parked, to: :idling, on: :park})
end

def test_should_include_all_known_states
Expand Down
4 changes: 2 additions & 2 deletions test/unit/event/event_on_failure_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ def test_should_pass_args_to_failure_callbacks
callback_args = nil
@machine.after_failure { |*args| callback_args = args }

@event.fire(@object, foo: 'bar')
@event.fire(@object, {foo: 'bar'})

object, transition = callback_args
assert_equal @object, object
refute_nil transition
assert_equal [{foo: 'bar'}], transition.args
assert_equal [{foo: 'bar'}], transition.args
end

def teardown
Expand Down