sequent 4.3.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/lib/sequent/core/command_record.rb +1 -1
 - data/lib/sequent/core/helpers/attr_matchers/argument_serializer.rb +35 -0
 - data/lib/sequent/core/helpers/attr_matchers/attr_matchers.rb +10 -0
 - data/lib/sequent/core/helpers/attr_matchers/dsl.rb +23 -0
 - data/lib/sequent/core/helpers/attr_matchers/equals.rb +24 -0
 - data/lib/sequent/core/helpers/attr_matchers/greater_than.rb +24 -0
 - data/lib/sequent/core/helpers/attr_matchers/greater_than_equals.rb +24 -0
 - data/lib/sequent/core/helpers/attr_matchers/less_than.rb +24 -0
 - data/lib/sequent/core/helpers/attr_matchers/less_than_equals.rb +24 -0
 - data/lib/sequent/core/helpers/attr_matchers/not_equals.rb +24 -0
 - data/lib/sequent/core/helpers/attribute_support.rb +34 -9
 - data/lib/sequent/core/helpers/autoset_attributes.rb +5 -5
 - data/lib/sequent/core/helpers/message_dispatcher.rb +20 -0
 - data/lib/sequent/core/helpers/message_handler.rb +62 -8
 - data/lib/sequent/core/helpers/message_handler_option_registry.rb +59 -0
 - data/lib/sequent/core/helpers/message_matchers/any.rb +34 -0
 - data/lib/sequent/core/helpers/message_matchers/argument_coercer.rb +24 -0
 - data/lib/sequent/core/helpers/message_matchers/argument_serializer.rb +20 -0
 - data/lib/sequent/core/helpers/message_matchers/dsl.rb +23 -0
 - data/lib/sequent/core/helpers/message_matchers/except_opt.rb +24 -0
 - data/lib/sequent/core/helpers/message_matchers/has_attrs.rb +54 -0
 - data/lib/sequent/core/helpers/message_matchers/instance_of.rb +24 -0
 - data/lib/sequent/core/helpers/message_matchers/is_a.rb +34 -0
 - data/lib/sequent/core/helpers/message_matchers/message_matchers.rb +10 -0
 - data/lib/sequent/core/helpers/message_router.rb +55 -0
 - data/lib/sequent/core/workflow.rb +2 -2
 - data/lib/sequent/test/command_handler_helpers.rb +2 -2
 - data/lib/version.rb +1 -1
 - metadata +31 -10
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 1dea4b53205452eaa68007ed47688b3fa074229677186e9342265cdd7a31d4db
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 2d342b9a013372ca99b441c4980432f642a56741746291d814c68ad60cf6c26e
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: cea76a7429f29dcff3e73789f608c968030ade74446493effcf6cf6b51f39c3815da7e5ccc040cf0392a797a6978fa773b5f8f2791f907ebbb31830ab7ae56bc
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: e03569382132ffefabd44ebc973d78a2c1745291cf64ef17c0dc744bd513d5fe72c816a0cfb69da7297ddd076df81139a53058816f02bc215f58ad48c0b7bc67
         
     | 
| 
         @@ -8,7 +8,7 @@ module Sequent 
     | 
|
| 
       8 
8 
     | 
    
         
             
                module SerializesCommand
         
     | 
| 
       9 
9 
     | 
    
         
             
                  def command
         
     | 
| 
       10 
10 
     | 
    
         
             
                    args = Sequent::Core::Oj.strict_load(command_json)
         
     | 
| 
       11 
     | 
    
         
            -
                    Class.const_get(command_type 
     | 
| 
      
 11 
     | 
    
         
            +
                    Class.const_get(command_type).deserialize_from_json(args)
         
     | 
| 
       12 
12 
     | 
    
         
             
                  end
         
     | 
| 
       13 
13 
     | 
    
         | 
| 
       14 
14 
     | 
    
         
             
                  def command=(command)
         
     | 
| 
         @@ -0,0 +1,35 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module AttrMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    class ArgumentSerializer
         
     | 
| 
      
 8 
     | 
    
         
            +
                      class << self
         
     | 
| 
      
 9 
     | 
    
         
            +
                        def serialize_value(value, enclose_hash: false)
         
     | 
| 
      
 10 
     | 
    
         
            +
                          return value.to_s if value.respond_to?(:matches_attr?)
         
     | 
| 
      
 11 
     | 
    
         
            +
                          return %("#{value}") if value.is_a?(String)
         
     | 
| 
      
 12 
     | 
    
         
            +
                          return serialize_hash(value, enclose_hash: enclose_hash) if value.is_a?(Hash)
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                          value
         
     | 
| 
      
 15 
     | 
    
         
            +
                        end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                        private
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                        def serialize_hash(hash, enclose_hash:)
         
     | 
| 
      
 20 
     | 
    
         
            +
                          serialized = hash
         
     | 
| 
      
 21 
     | 
    
         
            +
                            .map do |(name, value)|
         
     | 
| 
      
 22 
     | 
    
         
            +
                              "#{name}: #{serialize_value(value, enclose_hash: true)}"
         
     | 
| 
      
 23 
     | 
    
         
            +
                            end
         
     | 
| 
      
 24 
     | 
    
         
            +
                            .join(', ')
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                          return "{#{serialized}}" if enclose_hash
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                          serialized
         
     | 
| 
      
 29 
     | 
    
         
            +
                        end
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    end
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'dsl'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'argument_serializer'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'equals'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative 'not_equals'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require_relative 'greater_than_equals'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative 'greater_than'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require_relative 'less_than_equals'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require_relative 'less_than'
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module AttrMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    module DSL
         
     | 
| 
      
 8 
     | 
    
         
            +
                      def register_matcher(name, matcher_class)
         
     | 
| 
      
 9 
     | 
    
         
            +
                        if respond_to?(name)
         
     | 
| 
      
 10 
     | 
    
         
            +
                          fail ArgumentError, "Cannot register attr matcher because it would overwrite existing method '#{name}'"
         
     | 
| 
      
 11 
     | 
    
         
            +
                        end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                        define_method(name) do |*expected|
         
     | 
| 
      
 14 
     | 
    
         
            +
                          matcher_class.new(*expected)
         
     | 
| 
      
 15 
     | 
    
         
            +
                        end
         
     | 
| 
      
 16 
     | 
    
         
            +
                      end
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    extend DSL
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module AttrMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    Equals = Struct.new(:expected_value) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      def matches_attr?(actual_value)
         
     | 
| 
      
 9 
     | 
    
         
            +
                        actual_value == expected_value
         
     | 
| 
      
 10 
     | 
    
         
            +
                      end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      def to_s
         
     | 
| 
      
 13 
     | 
    
         
            +
                        "eq(#{ArgumentSerializer.serialize_value(expected_value)})"
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Sequent::Core::Helpers::AttrMatchers.register_matcher(
         
     | 
| 
      
 22 
     | 
    
         
            +
              :eq,
         
     | 
| 
      
 23 
     | 
    
         
            +
              Sequent::Core::Helpers::AttrMatchers::Equals,
         
     | 
| 
      
 24 
     | 
    
         
            +
            )
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module AttrMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    GreaterThan = Struct.new(:expected_value) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      def matches_attr?(actual_value)
         
     | 
| 
      
 9 
     | 
    
         
            +
                        actual_value > expected_value
         
     | 
| 
      
 10 
     | 
    
         
            +
                      end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      def to_s
         
     | 
| 
      
 13 
     | 
    
         
            +
                        "gt(#{ArgumentSerializer.serialize_value(expected_value)})"
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Sequent::Core::Helpers::AttrMatchers.register_matcher(
         
     | 
| 
      
 22 
     | 
    
         
            +
              :gt,
         
     | 
| 
      
 23 
     | 
    
         
            +
              Sequent::Core::Helpers::AttrMatchers::GreaterThan,
         
     | 
| 
      
 24 
     | 
    
         
            +
            )
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module AttrMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    GreaterThanEquals = Struct.new(:expected_value) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      def matches_attr?(actual_value)
         
     | 
| 
      
 9 
     | 
    
         
            +
                        actual_value >= expected_value
         
     | 
| 
      
 10 
     | 
    
         
            +
                      end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      def to_s
         
     | 
| 
      
 13 
     | 
    
         
            +
                        "gte(#{ArgumentSerializer.serialize_value(expected_value)})"
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Sequent::Core::Helpers::AttrMatchers.register_matcher(
         
     | 
| 
      
 22 
     | 
    
         
            +
              :gte,
         
     | 
| 
      
 23 
     | 
    
         
            +
              Sequent::Core::Helpers::AttrMatchers::GreaterThanEquals,
         
     | 
| 
      
 24 
     | 
    
         
            +
            )
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module AttrMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    LessThan = Struct.new(:expected_value) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      def matches_attr?(actual_value)
         
     | 
| 
      
 9 
     | 
    
         
            +
                        actual_value < expected_value
         
     | 
| 
      
 10 
     | 
    
         
            +
                      end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      def to_s
         
     | 
| 
      
 13 
     | 
    
         
            +
                        "lt(#{ArgumentSerializer.serialize_value(expected_value)})"
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Sequent::Core::Helpers::AttrMatchers.register_matcher(
         
     | 
| 
      
 22 
     | 
    
         
            +
              :lt,
         
     | 
| 
      
 23 
     | 
    
         
            +
              Sequent::Core::Helpers::AttrMatchers::LessThan,
         
     | 
| 
      
 24 
     | 
    
         
            +
            )
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module AttrMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    LessThanEquals = Struct.new(:expected_value) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      def matches_attr?(actual_value)
         
     | 
| 
      
 9 
     | 
    
         
            +
                        actual_value <= expected_value
         
     | 
| 
      
 10 
     | 
    
         
            +
                      end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      def to_s
         
     | 
| 
      
 13 
     | 
    
         
            +
                        "lte(#{ArgumentSerializer.serialize_value(expected_value)})"
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Sequent::Core::Helpers::AttrMatchers.register_matcher(
         
     | 
| 
      
 22 
     | 
    
         
            +
              :lte,
         
     | 
| 
      
 23 
     | 
    
         
            +
              Sequent::Core::Helpers::AttrMatchers::LessThanEquals,
         
     | 
| 
      
 24 
     | 
    
         
            +
            )
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module AttrMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    NotEquals = Struct.new(:expected_value) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      def matches_attr?(actual_value)
         
     | 
| 
      
 9 
     | 
    
         
            +
                        actual_value != expected_value
         
     | 
| 
      
 10 
     | 
    
         
            +
                      end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      def to_s
         
     | 
| 
      
 13 
     | 
    
         
            +
                        "neq(#{ArgumentSerializer.serialize_value(expected_value)})"
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Sequent::Core::Helpers::AttrMatchers.register_matcher(
         
     | 
| 
      
 22 
     | 
    
         
            +
              :neq,
         
     | 
| 
      
 23 
     | 
    
         
            +
              Sequent::Core::Helpers::AttrMatchers::NotEquals,
         
     | 
| 
      
 24 
     | 
    
         
            +
            )
         
     | 
| 
         @@ -40,19 +40,19 @@ module Sequent 
     | 
|
| 
       40 
40 
     | 
    
         | 
| 
       41 
41 
     | 
    
         
             
                    # module containing class methods to be added
         
     | 
| 
       42 
42 
     | 
    
         
             
                    module ClassMethods
         
     | 
| 
       43 
     | 
    
         
            -
                       
     | 
| 
       44 
     | 
    
         
            -
                        @types ||= {}
         
     | 
| 
       45 
     | 
    
         
            -
                        return @merged_types if @merged_types
         
     | 
| 
      
 43 
     | 
    
         
            +
                      attr_reader :types
         
     | 
| 
       46 
44 
     | 
    
         | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
      
 45 
     | 
    
         
            +
                      # Called when this module is included or when a class which includes this module is inherited from.
         
     | 
| 
      
 46 
     | 
    
         
            +
                      #
         
     | 
| 
      
 47 
     | 
    
         
            +
                      # All declared attrs are merged into @types in order to prevent superfluous calculation of types in a class
         
     | 
| 
      
 48 
     | 
    
         
            +
                      # hierarchy.
         
     | 
| 
      
 49 
     | 
    
         
            +
                      def initialize_types
         
     | 
| 
      
 50 
     | 
    
         
            +
                        @types = inherited_types
         
     | 
| 
       52 
51 
     | 
    
         
             
                      end
         
     | 
| 
       53 
52 
     | 
    
         | 
| 
       54 
53 
     | 
    
         
             
                      def attrs(args)
         
     | 
| 
       55 
     | 
    
         
            -
                         
     | 
| 
      
 54 
     | 
    
         
            +
                        validate_attrs!(args)
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
       56 
56 
     | 
    
         
             
                        @types.merge!(args)
         
     | 
| 
       57 
57 
     | 
    
         
             
                        associations = []
         
     | 
| 
       58 
58 
     | 
    
         
             
                        args.each do |attribute, type|
         
     | 
| 
         @@ -126,6 +126,18 @@ EOS 
     | 
|
| 
       126 
126 
     | 
    
         
             
                        @upcasters.push(block)
         
     | 
| 
       127 
127 
     | 
    
         
             
                      end
         
     | 
| 
       128 
128 
     | 
    
         | 
| 
      
 129 
     | 
    
         
            +
                      private
         
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                      def inherited_types
         
     | 
| 
      
 132 
     | 
    
         
            +
                        merged_types = is_a?(Class) && superclass.respond_to?(:types) ? superclass.types.dup : {}
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                        included_modules
         
     | 
| 
      
 135 
     | 
    
         
            +
                          .select { |m| m.include? Sequent::Core::Helpers::AttributeSupport }
         
     | 
| 
      
 136 
     | 
    
         
            +
                          .reduce(merged_types) do |memo, mod|
         
     | 
| 
      
 137 
     | 
    
         
            +
                            memo.merge(mod.types)
         
     | 
| 
      
 138 
     | 
    
         
            +
                          end
         
     | 
| 
      
 139 
     | 
    
         
            +
                      end
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
       129 
141 
     | 
    
         
             
                      def upcast!(hash)
         
     | 
| 
       130 
142 
     | 
    
         
             
                        return if @upcasters.nil?
         
     | 
| 
       131 
143 
     | 
    
         | 
| 
         @@ -133,11 +145,24 @@ EOS 
     | 
|
| 
       133 
145 
     | 
    
         
             
                          upcaster.call(hash)
         
     | 
| 
       134 
146 
     | 
    
         
             
                        end
         
     | 
| 
       135 
147 
     | 
    
         
             
                      end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                      def validate_attrs!(args)
         
     | 
| 
      
 150 
     | 
    
         
            +
                        duplicate_attrs = types.keys & args.keys
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                        fail ArgumentError, "Attributes already defined: #{duplicate_attrs.join(', ')}" if duplicate_attrs.any?
         
     | 
| 
      
 153 
     | 
    
         
            +
                      end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                      def inherited(subclass)
         
     | 
| 
      
 156 
     | 
    
         
            +
                        super
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
                        subclass.initialize_types
         
     | 
| 
      
 159 
     | 
    
         
            +
                      end
         
     | 
| 
       136 
160 
     | 
    
         
             
                    end
         
     | 
| 
       137 
161 
     | 
    
         | 
| 
       138 
162 
     | 
    
         
             
                    # extend host class with class methods when we're included
         
     | 
| 
       139 
163 
     | 
    
         
             
                    def self.included(host_class)
         
     | 
| 
       140 
164 
     | 
    
         
             
                      host_class.extend(ClassMethods)
         
     | 
| 
      
 165 
     | 
    
         
            +
                      host_class.initialize_types
         
     | 
| 
       141 
166 
     | 
    
         
             
                    end
         
     | 
| 
       142 
167 
     | 
    
         | 
| 
       143 
168 
     | 
    
         
             
                    def attributes
         
     | 
| 
         @@ -36,11 +36,11 @@ module Sequent 
     | 
|
| 
       36 
36 
     | 
    
         
             
                        event_class.types.keys.reject { |k| @@autoset_ignore_attributes.include?(k.to_s) }
         
     | 
| 
       37 
37 
     | 
    
         
             
                      end
         
     | 
| 
       38 
38 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                      def autoset_attributes_for_events(* 
     | 
| 
       40 
     | 
    
         
            -
                         
     | 
| 
       41 
     | 
    
         
            -
                          on  
     | 
| 
       42 
     | 
    
         
            -
                            self.class.event_attribute_keys( 
     | 
| 
       43 
     | 
    
         
            -
                              instance_variable_set(:"@#{attribute_name}", event. 
     | 
| 
      
 39 
     | 
    
         
            +
                      def autoset_attributes_for_events(*args)
         
     | 
| 
      
 40 
     | 
    
         
            +
                        args.each do |arg|
         
     | 
| 
      
 41 
     | 
    
         
            +
                          on arg do |event|
         
     | 
| 
      
 42 
     | 
    
         
            +
                            self.class.event_attribute_keys(event.class).each do |attribute_name|
         
     | 
| 
      
 43 
     | 
    
         
            +
                              instance_variable_set(:"@#{attribute_name}", event.public_send(attribute_name.to_sym))
         
     | 
| 
       44 
44 
     | 
    
         
             
                            end
         
     | 
| 
       45 
45 
     | 
    
         
             
                          end
         
     | 
| 
       46 
46 
     | 
    
         
             
                        end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class MessageDispatcher
         
     | 
| 
      
 7 
     | 
    
         
            +
                    def initialize(message_router, context)
         
     | 
| 
      
 8 
     | 
    
         
            +
                      @message_router = message_router
         
     | 
| 
      
 9 
     | 
    
         
            +
                      @context = context
         
     | 
| 
      
 10 
     | 
    
         
            +
                    end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    def dispatch_message(message)
         
     | 
| 
      
 13 
     | 
    
         
            +
                      @message_router
         
     | 
| 
      
 14 
     | 
    
         
            +
                        .match_message(message)
         
     | 
| 
      
 15 
     | 
    
         
            +
                        .each { |handler| @context.instance_exec(message, &handler) }
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,5 +1,9 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'message_handler_option_registry'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'message_router'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'message_dispatcher'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
       3 
7 
     | 
    
         
             
            module Sequent
         
     | 
| 
       4 
8 
     | 
    
         
             
              module Core
         
     | 
| 
       5 
9 
     | 
    
         
             
                module Helpers
         
     | 
| 
         @@ -36,29 +40,79 @@ module Sequent 
     | 
|
| 
       36 
40 
     | 
    
         
             
                  #
         
     | 
| 
       37 
41 
     | 
    
         
             
                  module MessageHandler
         
     | 
| 
       38 
42 
     | 
    
         
             
                    module ClassMethods
         
     | 
| 
       39 
     | 
    
         
            -
                      def on(* 
     | 
| 
       40 
     | 
    
         
            -
                         
     | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
      
 43 
     | 
    
         
            +
                      def on(*args, **opts, &block)
         
     | 
| 
      
 44 
     | 
    
         
            +
                        OnArgumentsValidator.validate_arguments!(*args)
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                        message_matchers = args.map { |arg| MessageMatchers::ArgumentCoercer.coerce_argument(arg) }
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                        message_router.register_matchers(
         
     | 
| 
      
 49 
     | 
    
         
            +
                          *message_matchers,
         
     | 
| 
      
 50 
     | 
    
         
            +
                          block,
         
     | 
| 
      
 51 
     | 
    
         
            +
                        )
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                        opts.each do |name, value|
         
     | 
| 
      
 54 
     | 
    
         
            +
                          option_registry.call_option(self, name, message_matchers, value)
         
     | 
| 
       43 
55 
     | 
    
         
             
                        end
         
     | 
| 
       44 
56 
     | 
    
         
             
                      end
         
     | 
| 
       45 
57 
     | 
    
         | 
| 
      
 58 
     | 
    
         
            +
                      def option(name, &block)
         
     | 
| 
      
 59 
     | 
    
         
            +
                        option_registry.register_option(name, block)
         
     | 
| 
      
 60 
     | 
    
         
            +
                      end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
       46 
62 
     | 
    
         
             
                      def message_mapping
         
     | 
| 
       47 
     | 
    
         
            -
                         
     | 
| 
      
 63 
     | 
    
         
            +
                        message_router
         
     | 
| 
      
 64 
     | 
    
         
            +
                          .routes
         
     | 
| 
      
 65 
     | 
    
         
            +
                          .select { |matcher, _handlers| matcher.is_a?(MessageMatchers::InstanceOf) }
         
     | 
| 
      
 66 
     | 
    
         
            +
                          .map { |k, v| [k.expected_class, v] }
         
     | 
| 
      
 67 
     | 
    
         
            +
                          .to_h
         
     | 
| 
       48 
68 
     | 
    
         
             
                      end
         
     | 
| 
       49 
69 
     | 
    
         | 
| 
       50 
70 
     | 
    
         
             
                      def handles_message?(message)
         
     | 
| 
       51 
     | 
    
         
            -
                         
     | 
| 
      
 71 
     | 
    
         
            +
                        message_router.matches_message?(message)
         
     | 
| 
      
 72 
     | 
    
         
            +
                      end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                      def message_router
         
     | 
| 
      
 75 
     | 
    
         
            +
                        @message_router ||= MessageRouter.new
         
     | 
| 
      
 76 
     | 
    
         
            +
                      end
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                    class OnArgumentsValidator
         
     | 
| 
      
 80 
     | 
    
         
            +
                      class << self
         
     | 
| 
      
 81 
     | 
    
         
            +
                        def validate_arguments!(*args)
         
     | 
| 
      
 82 
     | 
    
         
            +
                          fail ArgumentError, "Must provide at least one argument to 'on'" if args.empty?
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                          duplicates = args
         
     | 
| 
      
 85 
     | 
    
         
            +
                            .select { |arg| args.count(arg) > 1 }
         
     | 
| 
      
 86 
     | 
    
         
            +
                            .uniq
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                          if duplicates.any?
         
     | 
| 
      
 89 
     | 
    
         
            +
                            humanized_duplicates = duplicates
         
     | 
| 
      
 90 
     | 
    
         
            +
                              .map { |x| MessageMatchers::ArgumentSerializer.serialize_value(x) }
         
     | 
| 
      
 91 
     | 
    
         
            +
                              .join(', ')
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                            fail ArgumentError,
         
     | 
| 
      
 94 
     | 
    
         
            +
                                 "Arguments to 'on' must be unique, duplicates: #{humanized_duplicates}"
         
     | 
| 
      
 95 
     | 
    
         
            +
                          end
         
     | 
| 
      
 96 
     | 
    
         
            +
                        end
         
     | 
| 
       52 
97 
     | 
    
         
             
                      end
         
     | 
| 
       53 
98 
     | 
    
         
             
                    end
         
     | 
| 
       54 
99 
     | 
    
         | 
| 
       55 
100 
     | 
    
         
             
                    def self.included(host_class)
         
     | 
| 
       56 
101 
     | 
    
         
             
                      host_class.extend(ClassMethods)
         
     | 
| 
      
 102 
     | 
    
         
            +
                      host_class.extend(MessageMatchers)
         
     | 
| 
      
 103 
     | 
    
         
            +
                      host_class.extend(AttrMatchers)
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                      host_class.class_attribute :option_registry, default: MessageHandlerOptionRegistry.new
         
     | 
| 
       57 
106 
     | 
    
         
             
                    end
         
     | 
| 
       58 
107 
     | 
    
         | 
| 
       59 
108 
     | 
    
         
             
                    def handle_message(message)
         
     | 
| 
       60 
     | 
    
         
            -
                       
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
      
 109 
     | 
    
         
            +
                      message_dispatcher.dispatch_message(message)
         
     | 
| 
      
 110 
     | 
    
         
            +
                    end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                    private
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                    def message_dispatcher
         
     | 
| 
      
 115 
     | 
    
         
            +
                      MessageDispatcher.new(self.class.message_router, self)
         
     | 
| 
       62 
116 
     | 
    
         
             
                    end
         
     | 
| 
       63 
117 
     | 
    
         
             
                  end
         
     | 
| 
       64 
118 
     | 
    
         
             
                end
         
     | 
| 
         @@ -0,0 +1,59 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class MessageHandlerOptionRegistry
         
     | 
| 
      
 7 
     | 
    
         
            +
                    attr_reader :entries
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                    def initialize
         
     | 
| 
      
 10 
     | 
    
         
            +
                      clear_options
         
     | 
| 
      
 11 
     | 
    
         
            +
                    end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                    ##
         
     | 
| 
      
 14 
     | 
    
         
            +
                    # Registers a handler for the given option.
         
     | 
| 
      
 15 
     | 
    
         
            +
                    #
         
     | 
| 
      
 16 
     | 
    
         
            +
                    def register_option(name, handler)
         
     | 
| 
      
 17 
     | 
    
         
            +
                      fail ArgumentError, "Option with name '#{name}' already registered" if option_registered?(name)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                      @entries[name] = handler
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                    ##
         
     | 
| 
      
 23 
     | 
    
         
            +
                    # Calls the options with the given arguments with `self` bound to the given context.
         
     | 
| 
      
 24 
     | 
    
         
            +
                    #
         
     | 
| 
      
 25 
     | 
    
         
            +
                    def call_option(context, name, *args)
         
     | 
| 
      
 26 
     | 
    
         
            +
                      handler = find_option(name)
         
     | 
| 
      
 27 
     | 
    
         
            +
                      context.instance_exec(*args, &handler)
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                    ##
         
     | 
| 
      
 31 
     | 
    
         
            +
                    # Removes all options from the registry.
         
     | 
| 
      
 32 
     | 
    
         
            +
                    #
         
     | 
| 
      
 33 
     | 
    
         
            +
                    def clear_options
         
     | 
| 
      
 34 
     | 
    
         
            +
                      @entries = {}
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    private
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    ##
         
     | 
| 
      
 40 
     | 
    
         
            +
                    # Returns the handler for given option.
         
     | 
| 
      
 41 
     | 
    
         
            +
                    #
         
     | 
| 
      
 42 
     | 
    
         
            +
                    def find_option(name)
         
     | 
| 
      
 43 
     | 
    
         
            +
                      @entries[name] || fail(
         
     | 
| 
      
 44 
     | 
    
         
            +
                        ArgumentError,
         
     | 
| 
      
 45 
     | 
    
         
            +
                        "Unsupported option: '#{name}'; " \
         
     | 
| 
      
 46 
     | 
    
         
            +
                        "#{@entries.keys.any? ? "registered options: #{@entries.keys.join(', ')}" : 'no registered options'}",
         
     | 
| 
      
 47 
     | 
    
         
            +
                      )
         
     | 
| 
      
 48 
     | 
    
         
            +
                    end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                    ##
         
     | 
| 
      
 51 
     | 
    
         
            +
                    # Returns true when an option for the given name is registered, or false otherwise.
         
     | 
| 
      
 52 
     | 
    
         
            +
                    #
         
     | 
| 
      
 53 
     | 
    
         
            +
                    def option_registered?(name)
         
     | 
| 
      
 54 
     | 
    
         
            +
                      @entries.key?(name)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
                  end
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
              end
         
     | 
| 
      
 59 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module MessageMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    Any = Struct.new(:opts) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      include ExceptOpt
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                      def matches_message?(message)
         
     | 
| 
      
 11 
     | 
    
         
            +
                        return false if excluded?(message)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                        true
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                      def to_s
         
     | 
| 
      
 17 
     | 
    
         
            +
                        "any#{matcher_arguments}"
         
     | 
| 
      
 18 
     | 
    
         
            +
                      end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                      private
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                      def matcher_arguments
         
     | 
| 
      
 23 
     | 
    
         
            +
                        "(except: #{except})" if except
         
     | 
| 
      
 24 
     | 
    
         
            +
                      end
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            Sequent::Core::Helpers::MessageMatchers.register_matcher(
         
     | 
| 
      
 32 
     | 
    
         
            +
              :any,
         
     | 
| 
      
 33 
     | 
    
         
            +
              Sequent::Core::Helpers::MessageMatchers::Any,
         
     | 
| 
      
 34 
     | 
    
         
            +
            )
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module MessageMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    class ArgumentCoercer
         
     | 
| 
      
 8 
     | 
    
         
            +
                      class << self
         
     | 
| 
      
 9 
     | 
    
         
            +
                        def coerce_argument(arg)
         
     | 
| 
      
 10 
     | 
    
         
            +
                          fail ArgumentError, 'Cannot coerce nil argument' if arg.nil?
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                          return MessageMatchers::InstanceOf.new(arg) if [Class, Module].include?(arg.class)
         
     | 
| 
      
 13 
     | 
    
         
            +
                          return arg if arg.respond_to?(:matches_message?)
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                          fail ArgumentError,
         
     | 
| 
      
 16 
     | 
    
         
            +
                               "Can't coerce argument '#{arg}'; " \
         
     | 
| 
      
 17 
     | 
    
         
            +
                               'must be either a Class, Module or message matcher (respond to :matches_message?)'
         
     | 
| 
      
 18 
     | 
    
         
            +
                        end
         
     | 
| 
      
 19 
     | 
    
         
            +
                      end
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module MessageMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    class ArgumentSerializer
         
     | 
| 
      
 8 
     | 
    
         
            +
                      class << self
         
     | 
| 
      
 9 
     | 
    
         
            +
                        def serialize_value(value)
         
     | 
| 
      
 10 
     | 
    
         
            +
                          return value.to_s if value.respond_to?(:matches_message?)
         
     | 
| 
      
 11 
     | 
    
         
            +
                          return %("#{value}") if value.is_a?(String)
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                          value
         
     | 
| 
      
 14 
     | 
    
         
            +
                        end
         
     | 
| 
      
 15 
     | 
    
         
            +
                      end
         
     | 
| 
      
 16 
     | 
    
         
            +
                    end
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module MessageMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    module DSL
         
     | 
| 
      
 8 
     | 
    
         
            +
                      def register_matcher(name, matcher_class)
         
     | 
| 
      
 9 
     | 
    
         
            +
                        if respond_to?(name)
         
     | 
| 
      
 10 
     | 
    
         
            +
                          fail ArgumentError, "Cannot register message matcher because it would overwrite existing method '#{name}'"
         
     | 
| 
      
 11 
     | 
    
         
            +
                        end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                        define_method(name) do |*expected|
         
     | 
| 
      
 14 
     | 
    
         
            +
                          matcher_class.new(*expected)
         
     | 
| 
      
 15 
     | 
    
         
            +
                        end
         
     | 
| 
      
 16 
     | 
    
         
            +
                      end
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    extend DSL
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module MessageMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    module ExceptOpt
         
     | 
| 
      
 8 
     | 
    
         
            +
                      private
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                      def excluded?(message)
         
     | 
| 
      
 11 
     | 
    
         
            +
                        [except]
         
     | 
| 
      
 12 
     | 
    
         
            +
                          .flatten
         
     | 
| 
      
 13 
     | 
    
         
            +
                          .compact
         
     | 
| 
      
 14 
     | 
    
         
            +
                          .any? { |x| message.is_a?(x) }
         
     | 
| 
      
 15 
     | 
    
         
            +
                      end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                      def except
         
     | 
| 
      
 18 
     | 
    
         
            +
                        opts.try(:[], :except)
         
     | 
| 
      
 19 
     | 
    
         
            +
                      end
         
     | 
| 
      
 20 
     | 
    
         
            +
                    end
         
     | 
| 
      
 21 
     | 
    
         
            +
                  end
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,54 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module MessageMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    HasAttrs = Struct.new(:message_matcher, :expected_attrs) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      def initialize(message_matcher, expected_attrs)
         
     | 
| 
      
 9 
     | 
    
         
            +
                        super
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                        fail ArgumentError, 'Missing required message matcher' if message_matcher.nil?
         
     | 
| 
      
 12 
     | 
    
         
            +
                        fail ArgumentError, 'Missing required expected attrs' if expected_attrs.blank?
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                        self.message_matcher = ArgumentCoercer.coerce_argument(message_matcher)
         
     | 
| 
      
 15 
     | 
    
         
            +
                      end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                      def matches_message?(message)
         
     | 
| 
      
 18 
     | 
    
         
            +
                        message_matcher.matches_message?(message) &&
         
     | 
| 
      
 19 
     | 
    
         
            +
                          matches_attrs?(message, expected_attrs)
         
     | 
| 
      
 20 
     | 
    
         
            +
                      end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                      def to_s
         
     | 
| 
      
 23 
     | 
    
         
            +
                        'has_attrs(' \
         
     | 
| 
      
 24 
     | 
    
         
            +
                          "#{MessageMatchers::ArgumentSerializer.serialize_value(message_matcher)}, " \
         
     | 
| 
      
 25 
     | 
    
         
            +
                          "#{AttrMatchers::ArgumentSerializer.serialize_value(expected_attrs)}" \
         
     | 
| 
      
 26 
     | 
    
         
            +
                        ')'
         
     | 
| 
      
 27 
     | 
    
         
            +
                      end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                      private
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                      def matches_attrs?(message, expected_attrs, path = [])
         
     | 
| 
      
 32 
     | 
    
         
            +
                        expected_attrs.all? do |(name, expected_value)|
         
     | 
| 
      
 33 
     | 
    
         
            +
                          matches_attr?(message, expected_value, path.dup.push(name))
         
     | 
| 
      
 34 
     | 
    
         
            +
                        end
         
     | 
| 
      
 35 
     | 
    
         
            +
                      end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                      def matches_attr?(message, expected_value, path)
         
     | 
| 
      
 38 
     | 
    
         
            +
                        return matches_attrs?(message, expected_value, path) if expected_value.is_a?(Hash)
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                        expected_value = AttrMatchers::Equals.new(expected_value) unless expected_value.respond_to?(:matches_attr?)
         
     | 
| 
      
 41 
     | 
    
         
            +
                        value = path.reduce(message) { |memo, p| memo.public_send(p) }
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                        expected_value.matches_attr?(value)
         
     | 
| 
      
 44 
     | 
    
         
            +
                      end
         
     | 
| 
      
 45 
     | 
    
         
            +
                    end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  end
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
              end
         
     | 
| 
      
 49 
     | 
    
         
            +
            end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            Sequent::Core::Helpers::MessageMatchers.register_matcher(
         
     | 
| 
      
 52 
     | 
    
         
            +
              :has_attrs,
         
     | 
| 
      
 53 
     | 
    
         
            +
              Sequent::Core::Helpers::MessageMatchers::HasAttrs,
         
     | 
| 
      
 54 
     | 
    
         
            +
            )
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module MessageMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    InstanceOf = Struct.new(:expected_class) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      def matches_message?(message)
         
     | 
| 
      
 9 
     | 
    
         
            +
                        message.instance_of?(expected_class)
         
     | 
| 
      
 10 
     | 
    
         
            +
                      end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      def to_s
         
     | 
| 
      
 13 
     | 
    
         
            +
                        expected_class
         
     | 
| 
      
 14 
     | 
    
         
            +
                      end
         
     | 
| 
      
 15 
     | 
    
         
            +
                    end
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
              end
         
     | 
| 
      
 19 
     | 
    
         
            +
            end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            Sequent::Core::Helpers::MessageMatchers.register_matcher(
         
     | 
| 
      
 22 
     | 
    
         
            +
              :instance_of,
         
     | 
| 
      
 23 
     | 
    
         
            +
              Sequent::Core::Helpers::MessageMatchers::InstanceOf,
         
     | 
| 
      
 24 
     | 
    
         
            +
            )
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module MessageMatchers
         
     | 
| 
      
 7 
     | 
    
         
            +
                    IsA = Struct.new(:expected_class, :opts) do
         
     | 
| 
      
 8 
     | 
    
         
            +
                      include ExceptOpt
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                      def matches_message?(message)
         
     | 
| 
      
 11 
     | 
    
         
            +
                        message.is_a?(expected_class) unless excluded?(message)
         
     | 
| 
      
 12 
     | 
    
         
            +
                      end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                      def to_s
         
     | 
| 
      
 15 
     | 
    
         
            +
                        "is_a(#{matcher_arguments})"
         
     | 
| 
      
 16 
     | 
    
         
            +
                      end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                      private
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                      def matcher_arguments
         
     | 
| 
      
 21 
     | 
    
         
            +
                        arguments = expected_class.to_s
         
     | 
| 
      
 22 
     | 
    
         
            +
                        arguments += ", except: #{except}" if except
         
     | 
| 
      
 23 
     | 
    
         
            +
                        arguments
         
     | 
| 
      
 24 
     | 
    
         
            +
                      end
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  end
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            Sequent::Core::Helpers::MessageMatchers.register_matcher(
         
     | 
| 
      
 32 
     | 
    
         
            +
              :is_a,
         
     | 
| 
      
 33 
     | 
    
         
            +
              Sequent::Core::Helpers::MessageMatchers::IsA,
         
     | 
| 
      
 34 
     | 
    
         
            +
            )
         
     | 
| 
         @@ -0,0 +1,10 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'dsl'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative 'argument_coercer'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'argument_serializer'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative 'except_opt'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require_relative 'instance_of'
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative 'is_a'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require_relative 'has_attrs'
         
     | 
| 
      
 10 
     | 
    
         
            +
            require_relative 'any'
         
     | 
| 
         @@ -0,0 +1,55 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative './attr_matchers/attr_matchers'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require_relative './message_matchers/message_matchers'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Sequent
         
     | 
| 
      
 7 
     | 
    
         
            +
              module Core
         
     | 
| 
      
 8 
     | 
    
         
            +
                module Helpers
         
     | 
| 
      
 9 
     | 
    
         
            +
                  class MessageRouter
         
     | 
| 
      
 10 
     | 
    
         
            +
                    attr_reader :routes
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                    def initialize
         
     | 
| 
      
 13 
     | 
    
         
            +
                      clear_routes
         
     | 
| 
      
 14 
     | 
    
         
            +
                    end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                    ##
         
     | 
| 
      
 17 
     | 
    
         
            +
                    # Registers a handler for the given matchers.
         
     | 
| 
      
 18 
     | 
    
         
            +
                    #
         
     | 
| 
      
 19 
     | 
    
         
            +
                    # A matcher must implement #matches_message?(message) and return a truthy value when it matches,
         
     | 
| 
      
 20 
     | 
    
         
            +
                    # or a falsey value otherwise.
         
     | 
| 
      
 21 
     | 
    
         
            +
                    #
         
     | 
| 
      
 22 
     | 
    
         
            +
                    def register_matchers(*matchers, handler)
         
     | 
| 
      
 23 
     | 
    
         
            +
                      matchers.each do |matcher|
         
     | 
| 
      
 24 
     | 
    
         
            +
                        @routes[matcher] << handler
         
     | 
| 
      
 25 
     | 
    
         
            +
                      end
         
     | 
| 
      
 26 
     | 
    
         
            +
                    end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                    ##
         
     | 
| 
      
 29 
     | 
    
         
            +
                    # Returns a set of handlers that match the given message, or an empty set when none match.
         
     | 
| 
      
 30 
     | 
    
         
            +
                    #
         
     | 
| 
      
 31 
     | 
    
         
            +
                    def match_message(message)
         
     | 
| 
      
 32 
     | 
    
         
            +
                      @routes
         
     | 
| 
      
 33 
     | 
    
         
            +
                        .reduce(Set.new) do |memo, (matcher, handlers)|
         
     | 
| 
      
 34 
     | 
    
         
            +
                          memo = memo.merge(handlers) if matcher.matches_message?(message)
         
     | 
| 
      
 35 
     | 
    
         
            +
                          memo
         
     | 
| 
      
 36 
     | 
    
         
            +
                        end
         
     | 
| 
      
 37 
     | 
    
         
            +
                    end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    ##
         
     | 
| 
      
 40 
     | 
    
         
            +
                    # Returns true when there is at least one handler for the given message, or false otherwise.
         
     | 
| 
      
 41 
     | 
    
         
            +
                    #
         
     | 
| 
      
 42 
     | 
    
         
            +
                    def matches_message?(message)
         
     | 
| 
      
 43 
     | 
    
         
            +
                      match_message(message).any?
         
     | 
| 
      
 44 
     | 
    
         
            +
                    end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                    ##
         
     | 
| 
      
 47 
     | 
    
         
            +
                    # Removes all routes from the router.
         
     | 
| 
      
 48 
     | 
    
         
            +
                    #
         
     | 
| 
      
 49 
     | 
    
         
            +
                    def clear_routes
         
     | 
| 
      
 50 
     | 
    
         
            +
                      @routes = Hash.new { |h, k| h[k] = Set.new }
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
      
 52 
     | 
    
         
            +
                  end
         
     | 
| 
      
 53 
     | 
    
         
            +
                end
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -13,7 +13,7 @@ module Sequent 
     | 
|
| 
       13 
13 
     | 
    
         
             
                    Workflows << subclass
         
     | 
| 
       14 
14 
     | 
    
         
             
                  end
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
                  def self.on(* 
     | 
| 
      
 16 
     | 
    
         
            +
                  def self.on(*args, **opts, &block)
         
     | 
| 
       17 
17 
     | 
    
         
             
                    decorated_block = ->(event) do
         
     | 
| 
       18 
18 
     | 
    
         
             
                      begin
         
     | 
| 
       19 
19 
     | 
    
         
             
                        old_event = CurrentEvent.current
         
     | 
| 
         @@ -23,7 +23,7 @@ module Sequent 
     | 
|
| 
       23 
23 
     | 
    
         
             
                        CurrentEvent.current = old_event
         
     | 
| 
       24 
24 
     | 
    
         
             
                      end
         
     | 
| 
       25 
25 
     | 
    
         
             
                    end
         
     | 
| 
       26 
     | 
    
         
            -
                    super(* 
     | 
| 
      
 26 
     | 
    
         
            +
                    super(*args, **opts, &decorated_block)
         
     | 
| 
       27 
27 
     | 
    
         
             
                  end
         
     | 
| 
       28 
28 
     | 
    
         | 
| 
       29 
29 
     | 
    
         
             
                  def execute_commands(*commands)
         
     | 
| 
         @@ -11,8 +11,8 @@ module Sequent 
     | 
|
| 
       11 
11 
     | 
    
         
             
                # This provides a nice DSL for event based testing of your CommandHandler like
         
     | 
| 
       12 
12 
     | 
    
         
             
                #
         
     | 
| 
       13 
13 
     | 
    
         
             
                # given_events InvoiceCreatedEvent.new(args)
         
     | 
| 
       14 
     | 
    
         
            -
                # when_command PayInvoiceCommand(args)
         
     | 
| 
       15 
     | 
    
         
            -
                # then_events InvoicePaidEvent(args)
         
     | 
| 
      
 14 
     | 
    
         
            +
                # when_command PayInvoiceCommand.new(args)
         
     | 
| 
      
 15 
     | 
    
         
            +
                # then_events InvoicePaidEvent.new(args)
         
     | 
| 
       16 
16 
     | 
    
         
             
                #
         
     | 
| 
       17 
17 
     | 
    
         
             
                # Example for Rspec config
         
     | 
| 
       18 
18 
     | 
    
         
             
                #
         
     | 
    
        data/lib/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: sequent
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version:  
     | 
| 
      
 4 
     | 
    
         
            +
              version: 5.0.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Lars Vonk
         
     | 
| 
         @@ -12,7 +12,7 @@ authors: 
     | 
|
| 
       12 
12 
     | 
    
         
             
            autorequire:
         
     | 
| 
       13 
13 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       14 
14 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       15 
     | 
    
         
            -
            date: 2022- 
     | 
| 
      
 15 
     | 
    
         
            +
            date: 2022-06-16 00:00:00.000000000 Z
         
     | 
| 
       16 
16 
     | 
    
         
             
            dependencies:
         
     | 
| 
       17 
17 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       18 
18 
     | 
    
         
             
              name: activemodel
         
     | 
| 
         @@ -21,9 +21,9 @@ dependencies: 
     | 
|
| 
       21 
21 
     | 
    
         
             
                - - ">="
         
     | 
| 
       22 
22 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       23 
23 
     | 
    
         
             
                    version: '5.0'
         
     | 
| 
       24 
     | 
    
         
            -
                - - " 
     | 
| 
      
 24 
     | 
    
         
            +
                - - "<"
         
     | 
| 
       25 
25 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       26 
     | 
    
         
            -
                    version: 7. 
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '7.1'
         
     | 
| 
       27 
27 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       28 
28 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       29 
29 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -31,9 +31,9 @@ dependencies: 
     | 
|
| 
       31 
31 
     | 
    
         
             
                - - ">="
         
     | 
| 
       32 
32 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       33 
33 
     | 
    
         
             
                    version: '5.0'
         
     | 
| 
       34 
     | 
    
         
            -
                - - " 
     | 
| 
      
 34 
     | 
    
         
            +
                - - "<"
         
     | 
| 
       35 
35 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       36 
     | 
    
         
            -
                    version: 7. 
     | 
| 
      
 36 
     | 
    
         
            +
                    version: '7.1'
         
     | 
| 
       37 
37 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       38 
38 
     | 
    
         
             
              name: activerecord
         
     | 
| 
       39 
39 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -41,9 +41,9 @@ dependencies: 
     | 
|
| 
       41 
41 
     | 
    
         
             
                - - ">="
         
     | 
| 
       42 
42 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       43 
43 
     | 
    
         
             
                    version: '5.0'
         
     | 
| 
       44 
     | 
    
         
            -
                - - " 
     | 
| 
      
 44 
     | 
    
         
            +
                - - "<"
         
     | 
| 
       45 
45 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       46 
     | 
    
         
            -
                    version: 7. 
     | 
| 
      
 46 
     | 
    
         
            +
                    version: '7.1'
         
     | 
| 
       47 
47 
     | 
    
         
             
              type: :runtime
         
     | 
| 
       48 
48 
     | 
    
         
             
              prerelease: false
         
     | 
| 
       49 
49 
     | 
    
         
             
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -51,9 +51,9 @@ dependencies: 
     | 
|
| 
       51 
51 
     | 
    
         
             
                - - ">="
         
     | 
| 
       52 
52 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       53 
53 
     | 
    
         
             
                    version: '5.0'
         
     | 
| 
       54 
     | 
    
         
            -
                - - " 
     | 
| 
      
 54 
     | 
    
         
            +
                - - "<"
         
     | 
| 
       55 
55 
     | 
    
         
             
                  - !ruby/object:Gem::Version
         
     | 
| 
       56 
     | 
    
         
            -
                    version: 7. 
     | 
| 
      
 56 
     | 
    
         
            +
                    version: '7.1'
         
     | 
| 
       57 
57 
     | 
    
         
             
            - !ruby/object:Gem::Dependency
         
     | 
| 
       58 
58 
     | 
    
         
             
              name: bcrypt
         
     | 
| 
       59 
59 
     | 
    
         
             
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
         @@ -333,6 +333,15 @@ files: 
     | 
|
| 
       333 
333 
     | 
    
         
             
            - lib/sequent/core/ext/ext.rb
         
     | 
| 
       334 
334 
     | 
    
         
             
            - lib/sequent/core/helpers/array_with_type.rb
         
     | 
| 
       335 
335 
     | 
    
         
             
            - lib/sequent/core/helpers/association_validator.rb
         
     | 
| 
      
 336 
     | 
    
         
            +
            - lib/sequent/core/helpers/attr_matchers/argument_serializer.rb
         
     | 
| 
      
 337 
     | 
    
         
            +
            - lib/sequent/core/helpers/attr_matchers/attr_matchers.rb
         
     | 
| 
      
 338 
     | 
    
         
            +
            - lib/sequent/core/helpers/attr_matchers/dsl.rb
         
     | 
| 
      
 339 
     | 
    
         
            +
            - lib/sequent/core/helpers/attr_matchers/equals.rb
         
     | 
| 
      
 340 
     | 
    
         
            +
            - lib/sequent/core/helpers/attr_matchers/greater_than.rb
         
     | 
| 
      
 341 
     | 
    
         
            +
            - lib/sequent/core/helpers/attr_matchers/greater_than_equals.rb
         
     | 
| 
      
 342 
     | 
    
         
            +
            - lib/sequent/core/helpers/attr_matchers/less_than.rb
         
     | 
| 
      
 343 
     | 
    
         
            +
            - lib/sequent/core/helpers/attr_matchers/less_than_equals.rb
         
     | 
| 
      
 344 
     | 
    
         
            +
            - lib/sequent/core/helpers/attr_matchers/not_equals.rb
         
     | 
| 
       336 
345 
     | 
    
         
             
            - lib/sequent/core/helpers/attribute_support.rb
         
     | 
| 
       337 
346 
     | 
    
         
             
            - lib/sequent/core/helpers/autoset_attributes.rb
         
     | 
| 
       338 
347 
     | 
    
         
             
            - lib/sequent/core/helpers/boolean_validator.rb
         
     | 
| 
         @@ -343,7 +352,19 @@ files: 
     | 
|
| 
       343 
352 
     | 
    
         
             
            - lib/sequent/core/helpers/equal_support.rb
         
     | 
| 
       344 
353 
     | 
    
         
             
            - lib/sequent/core/helpers/helpers.rb
         
     | 
| 
       345 
354 
     | 
    
         
             
            - lib/sequent/core/helpers/mergable.rb
         
     | 
| 
      
 355 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_dispatcher.rb
         
     | 
| 
       346 
356 
     | 
    
         
             
            - lib/sequent/core/helpers/message_handler.rb
         
     | 
| 
      
 357 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_handler_option_registry.rb
         
     | 
| 
      
 358 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_matchers/any.rb
         
     | 
| 
      
 359 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_matchers/argument_coercer.rb
         
     | 
| 
      
 360 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_matchers/argument_serializer.rb
         
     | 
| 
      
 361 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_matchers/dsl.rb
         
     | 
| 
      
 362 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_matchers/except_opt.rb
         
     | 
| 
      
 363 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_matchers/has_attrs.rb
         
     | 
| 
      
 364 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_matchers/instance_of.rb
         
     | 
| 
      
 365 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_matchers/is_a.rb
         
     | 
| 
      
 366 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_matchers/message_matchers.rb
         
     | 
| 
      
 367 
     | 
    
         
            +
            - lib/sequent/core/helpers/message_router.rb
         
     | 
| 
       347 
368 
     | 
    
         
             
            - lib/sequent/core/helpers/param_support.rb
         
     | 
| 
       348 
369 
     | 
    
         
             
            - lib/sequent/core/helpers/secret.rb
         
     | 
| 
       349 
370 
     | 
    
         
             
            - lib/sequent/core/helpers/string_support.rb
         
     |