From 2d672020227fa99b0cdf232235597b6d191b91c5 Mon Sep 17 00:00:00 2001 From: Evgeniy Yagnenkov Date: Sun, 21 Apr 2024 11:19:20 +0000 Subject: [PATCH 1/2] Add passing args --- lib/state_machines/branch.rb | 8 ++++---- lib/state_machines/event.rb | 9 +++++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/state_machines/branch.rb b/lib/state_machines/branch.rb index cca552f..93a59e8 100644 --- a/lib/state_machines/branch.rb +++ b/lib/state_machines/branch.rb @@ -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 @@ -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 diff --git a/lib/state_machines/event.rb b/lib/state_machines/event.rb index 4d8f081..391fd23 100644 --- a/lib/state_machines/event.rb +++ b/lib/state_machines/event.rb @@ -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: @@ -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 @@ -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) @@ -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) From be6d0119f9feacfc0bc37b4fda036cafe4f08364 Mon Sep 17 00:00:00 2001 From: Evgeniy Yagnenkov Date: Sun, 21 Apr 2024 11:42:57 +0000 Subject: [PATCH 2/2] Fix tests --- test/test_helper.rb | 2 +- test/unit/branch/branch_test.rb | 2 +- test/unit/branch/branch_with_different_requirements_test.rb | 2 +- test/unit/event/event_on_failure_test.rb | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index 336a80b..775f6b5 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -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 diff --git a/test/unit/branch/branch_test.rb b/test/unit/branch/branch_test.rb index 70b4dd8..599fd48 100644 --- a/test/unit/branch/branch_test.rb +++ b/test/unit/branch/branch_test.rb @@ -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 diff --git a/test/unit/branch/branch_with_different_requirements_test.rb b/test/unit/branch/branch_with_different_requirements_test.rb index a497d3a..e3b1a7c 100644 --- a/test/unit/branch/branch_with_different_requirements_test.rb +++ b/test/unit/branch/branch_with_different_requirements_test.rb @@ -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 diff --git a/test/unit/event/event_on_failure_test.rb b/test/unit/event/event_on_failure_test.rb index 3236041..9bc26eb 100644 --- a/test/unit/event/event_on_failure_test.rb +++ b/test/unit/event/event_on_failure_test.rb @@ -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