pathway 0.9.1 → 0.11.3
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/.circleci/config.yml +38 -0
 - data/CHANGELOG.md +22 -0
 - data/Gemfile +0 -2
 - data/README.md +91 -50
 - data/Rakefile +2 -0
 - data/lib/pathway.rb +3 -1
 - data/lib/pathway/plugins/dry_validation.rb +17 -91
 - data/lib/pathway/plugins/dry_validation/v0_11.rb +86 -0
 - data/lib/pathway/plugins/dry_validation/v0_12.rb +86 -0
 - data/lib/pathway/plugins/dry_validation/v1_0.rb +78 -0
 - data/lib/pathway/plugins/responder.rb +2 -0
 - data/lib/pathway/plugins/sequel_models.rb +31 -16
 - data/lib/pathway/plugins/simple_auth.rb +2 -0
 - data/lib/pathway/result.rb +2 -0
 - data/lib/pathway/rspec.rb +2 -0
 - data/lib/pathway/rspec/matchers.rb +2 -0
 - data/lib/pathway/rspec/matchers/accept_optional_fields.rb +31 -6
 - data/lib/pathway/rspec/matchers/fail_on.rb +5 -3
 - data/lib/pathway/rspec/matchers/field_list_helpers.rb +4 -2
 - data/lib/pathway/rspec/matchers/form_schema_helpers.rb +47 -3
 - data/lib/pathway/rspec/matchers/list_helpers.rb +5 -3
 - data/lib/pathway/rspec/matchers/require_fields.rb +30 -5
 - data/lib/pathway/rspec/matchers/succeed_on.rb +3 -1
 - data/lib/pathway/version.rb +3 -1
 - data/pathway.gemspec +6 -5
 - metadata +13 -10
 
| 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Pathway
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Plugins
         
     | 
| 
      
 5 
     | 
    
         
            +
                module DryValidation
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module V0_11
         
     | 
| 
      
 7 
     | 
    
         
            +
                    module ClassMethods
         
     | 
| 
      
 8 
     | 
    
         
            +
                      attr_reader :form_class, :form_options
         
     | 
| 
      
 9 
     | 
    
         
            +
                      attr_accessor :auto_wire_options
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                      def form(base = nil, **opts, &block)
         
     | 
| 
      
 12 
     | 
    
         
            +
                        if block_given?
         
     | 
| 
      
 13 
     | 
    
         
            +
                          base ||= _base_form
         
     | 
| 
      
 14 
     | 
    
         
            +
                          self.form_class = _block_definition(base, opts, &block)
         
     | 
| 
      
 15 
     | 
    
         
            +
                        elsif base
         
     | 
| 
      
 16 
     | 
    
         
            +
                          self.form_class = _form_class(base)
         
     | 
| 
      
 17 
     | 
    
         
            +
                        else
         
     | 
| 
      
 18 
     | 
    
         
            +
                          raise ArgumentError, 'Either a form class or a block must be provided'
         
     | 
| 
      
 19 
     | 
    
         
            +
                        end
         
     | 
| 
      
 20 
     | 
    
         
            +
                      end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                      def form_class= klass
         
     | 
| 
      
 23 
     | 
    
         
            +
                        @builded_form = klass.options.empty? ? klass.new : nil
         
     | 
| 
      
 24 
     | 
    
         
            +
                        @form_class = klass
         
     | 
| 
      
 25 
     | 
    
         
            +
                        @form_options = klass.options.keys
         
     | 
| 
      
 26 
     | 
    
         
            +
                      end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                      def build_form(opts = {})
         
     | 
| 
      
 29 
     | 
    
         
            +
                        @builded_form || form_class.new(opts)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      def inherited(subclass)
         
     | 
| 
      
 33 
     | 
    
         
            +
                        super
         
     | 
| 
      
 34 
     | 
    
         
            +
                        subclass.form_class = form_class
         
     | 
| 
      
 35 
     | 
    
         
            +
                        subclass.auto_wire_options = auto_wire_options
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                      private
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                      def _base_form
         
     | 
| 
      
 41 
     | 
    
         
            +
                        superclass.respond_to?(:form_class) ? superclass.form_class : Dry::Validation::Schema::Form
         
     | 
| 
      
 42 
     | 
    
         
            +
                      end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                      def _form_class(form)
         
     | 
| 
      
 45 
     | 
    
         
            +
                        form.is_a?(Class) ? form : form.class
         
     | 
| 
      
 46 
     | 
    
         
            +
                      end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                      def _form_opts(opts = {})
         
     | 
| 
      
 49 
     | 
    
         
            +
                        opts.merge(build: false)
         
     | 
| 
      
 50 
     | 
    
         
            +
                      end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                      def _block_definition(base, opts, &block)
         
     | 
| 
      
 53 
     | 
    
         
            +
                        Dry::Validation.Form(_form_class(base), _form_opts(opts), &block)
         
     | 
| 
      
 54 
     | 
    
         
            +
                      end
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                    module InstanceMethods
         
     | 
| 
      
 58 
     | 
    
         
            +
                      extend Forwardable
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                      delegate %i[build_form form_options auto_wire_options] => 'self.class'
         
     | 
| 
      
 61 
     | 
    
         
            +
                      alias :form :build_form
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                      def validate(state, with: nil)
         
     | 
| 
      
 64 
     | 
    
         
            +
                        if auto_wire_options && form_options.any?
         
     | 
| 
      
 65 
     | 
    
         
            +
                          with ||= form_options.zip(form_options).to_h
         
     | 
| 
      
 66 
     | 
    
         
            +
                        end
         
     | 
| 
      
 67 
     | 
    
         
            +
                        opts = Hash(with).map { |opt, key| [opt, state[key]] }.to_h
         
     | 
| 
      
 68 
     | 
    
         
            +
                        validate_with(state[:input], opts)
         
     | 
| 
      
 69 
     | 
    
         
            +
                          .then { |params| state.update(params: params) }
         
     | 
| 
      
 70 
     | 
    
         
            +
                      end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                      def validate_with(params, opts = {})
         
     | 
| 
      
 73 
     | 
    
         
            +
                        val = form(opts).call(params)
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                        val.success? ? wrap(val.output) : error(:validation, details: val.messages)
         
     | 
| 
      
 76 
     | 
    
         
            +
                      end
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                    def self.apply(operation, auto_wire_options: false)
         
     | 
| 
      
 80 
     | 
    
         
            +
                      operation.form_class = Dry::Validation::Schema::Form
         
     | 
| 
      
 81 
     | 
    
         
            +
                      operation.auto_wire_options = auto_wire_options
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,86 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Pathway
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Plugins
         
     | 
| 
      
 5 
     | 
    
         
            +
                module DryValidation
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module V0_12
         
     | 
| 
      
 7 
     | 
    
         
            +
                    module ClassMethods
         
     | 
| 
      
 8 
     | 
    
         
            +
                      attr_reader :form_class, :form_options
         
     | 
| 
      
 9 
     | 
    
         
            +
                      attr_accessor :auto_wire_options
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                      def form(base = nil, **opts, &block)
         
     | 
| 
      
 12 
     | 
    
         
            +
                        if block_given?
         
     | 
| 
      
 13 
     | 
    
         
            +
                          base ||= _base_form
         
     | 
| 
      
 14 
     | 
    
         
            +
                          self.form_class = _block_definition(base, opts, &block)
         
     | 
| 
      
 15 
     | 
    
         
            +
                        elsif base
         
     | 
| 
      
 16 
     | 
    
         
            +
                          self.form_class = _form_class(base)
         
     | 
| 
      
 17 
     | 
    
         
            +
                        else
         
     | 
| 
      
 18 
     | 
    
         
            +
                          raise ArgumentError, 'Either a form class or a block must be provided'
         
     | 
| 
      
 19 
     | 
    
         
            +
                        end
         
     | 
| 
      
 20 
     | 
    
         
            +
                      end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                      def form_class= klass
         
     | 
| 
      
 23 
     | 
    
         
            +
                        @builded_form = klass.options.empty? ? klass.new : nil
         
     | 
| 
      
 24 
     | 
    
         
            +
                        @form_class = klass
         
     | 
| 
      
 25 
     | 
    
         
            +
                        @form_options = klass.options.keys
         
     | 
| 
      
 26 
     | 
    
         
            +
                      end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                      def build_form(opts = {})
         
     | 
| 
      
 29 
     | 
    
         
            +
                        @builded_form || form_class.new(opts)
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      def inherited(subclass)
         
     | 
| 
      
 33 
     | 
    
         
            +
                        super
         
     | 
| 
      
 34 
     | 
    
         
            +
                        subclass.form_class = form_class
         
     | 
| 
      
 35 
     | 
    
         
            +
                        subclass.auto_wire_options = auto_wire_options
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                      private
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                      def _base_form
         
     | 
| 
      
 41 
     | 
    
         
            +
                        superclass.respond_to?(:form_class) ? superclass.form_class : Dry::Validation::Schema::Params
         
     | 
| 
      
 42 
     | 
    
         
            +
                      end
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                      def _form_class(form)
         
     | 
| 
      
 45 
     | 
    
         
            +
                        form.is_a?(Class) ? form : form.class
         
     | 
| 
      
 46 
     | 
    
         
            +
                      end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                      def _form_opts(opts = {})
         
     | 
| 
      
 49 
     | 
    
         
            +
                        opts.merge(build: false)
         
     | 
| 
      
 50 
     | 
    
         
            +
                      end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                      def _block_definition(base, opts, &block)
         
     | 
| 
      
 53 
     | 
    
         
            +
                        Dry::Validation.Params(_form_class(base), _form_opts(opts), &block)
         
     | 
| 
      
 54 
     | 
    
         
            +
                      end
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                    module InstanceMethods
         
     | 
| 
      
 58 
     | 
    
         
            +
                      extend Forwardable
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                      delegate %i[build_form form_options auto_wire_options] => 'self.class'
         
     | 
| 
      
 61 
     | 
    
         
            +
                      alias :form :build_form
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                      def validate(state, with: nil)
         
     | 
| 
      
 64 
     | 
    
         
            +
                        if auto_wire_options && form_options.any?
         
     | 
| 
      
 65 
     | 
    
         
            +
                          with ||= form_options.zip(form_options).to_h
         
     | 
| 
      
 66 
     | 
    
         
            +
                        end
         
     | 
| 
      
 67 
     | 
    
         
            +
                        opts = Hash(with).map { |opt, key| [opt, state[key]] }.to_h
         
     | 
| 
      
 68 
     | 
    
         
            +
                        validate_with(state[:input], opts)
         
     | 
| 
      
 69 
     | 
    
         
            +
                          .then { |params| state.update(params: params) }
         
     | 
| 
      
 70 
     | 
    
         
            +
                      end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                      def validate_with(params, opts = {})
         
     | 
| 
      
 73 
     | 
    
         
            +
                        val = form(opts).call(params)
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                        val.success? ? wrap(val.output) : error(:validation, details: val.messages)
         
     | 
| 
      
 76 
     | 
    
         
            +
                      end
         
     | 
| 
      
 77 
     | 
    
         
            +
                    end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                    def self.apply(operation, auto_wire_options: false)
         
     | 
| 
      
 80 
     | 
    
         
            +
                      operation.form_class = Dry::Validation::Schema::Params
         
     | 
| 
      
 81 
     | 
    
         
            +
                      operation.auto_wire_options = auto_wire_options
         
     | 
| 
      
 82 
     | 
    
         
            +
                    end
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,78 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Pathway
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Plugins
         
     | 
| 
      
 5 
     | 
    
         
            +
                module DryValidation
         
     | 
| 
      
 6 
     | 
    
         
            +
                  module V1_0
         
     | 
| 
      
 7 
     | 
    
         
            +
                    module ClassMethods
         
     | 
| 
      
 8 
     | 
    
         
            +
                      attr_reader :contract_class, :contract_options
         
     | 
| 
      
 9 
     | 
    
         
            +
                      attr_accessor :auto_wire_options
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                      def contract(base = nil, &block)
         
     | 
| 
      
 12 
     | 
    
         
            +
                        if block_given?
         
     | 
| 
      
 13 
     | 
    
         
            +
                          base ||= _base_contract
         
     | 
| 
      
 14 
     | 
    
         
            +
                          self.contract_class = Class.new(base, &block)
         
     | 
| 
      
 15 
     | 
    
         
            +
                        elsif base
         
     | 
| 
      
 16 
     | 
    
         
            +
                          self.contract_class = base
         
     | 
| 
      
 17 
     | 
    
         
            +
                        else
         
     | 
| 
      
 18 
     | 
    
         
            +
                          raise ArgumentError, 'Either a contract class or a block must be provided'
         
     | 
| 
      
 19 
     | 
    
         
            +
                        end
         
     | 
| 
      
 20 
     | 
    
         
            +
                      end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                      def params(*args, &block)
         
     | 
| 
      
 23 
     | 
    
         
            +
                        contract { params(*args, &block) }
         
     | 
| 
      
 24 
     | 
    
         
            +
                      end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                      def contract_class= klass
         
     | 
| 
      
 27 
     | 
    
         
            +
                        @contract_class = klass
         
     | 
| 
      
 28 
     | 
    
         
            +
                        @contract_options = (klass.dry_initializer.options - Dry::Validation::Contract.dry_initializer.options).map(&:target)
         
     | 
| 
      
 29 
     | 
    
         
            +
                        @builded_contract = @contract_options.empty? && klass.schema ? klass.new : nil
         
     | 
| 
      
 30 
     | 
    
         
            +
                      end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                      def build_contract(opts = {})
         
     | 
| 
      
 33 
     | 
    
         
            +
                        @builded_contract || contract_class.new(opts)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                      def inherited(subclass)
         
     | 
| 
      
 37 
     | 
    
         
            +
                        super
         
     | 
| 
      
 38 
     | 
    
         
            +
                        subclass.contract_class = contract_class
         
     | 
| 
      
 39 
     | 
    
         
            +
                        subclass.auto_wire_options = auto_wire_options
         
     | 
| 
      
 40 
     | 
    
         
            +
                      end
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                      private
         
     | 
| 
      
 43 
     | 
    
         
            +
             
     | 
| 
      
 44 
     | 
    
         
            +
                      def _base_contract
         
     | 
| 
      
 45 
     | 
    
         
            +
                        superclass.respond_to?(:contract_class) ? superclass.contract_class : Dry::Validation::Contract
         
     | 
| 
      
 46 
     | 
    
         
            +
                      end
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                    module InstanceMethods
         
     | 
| 
      
 50 
     | 
    
         
            +
                      extend Forwardable
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                      delegate %i[build_contract contract_options auto_wire_options] => 'self.class'
         
     | 
| 
      
 53 
     | 
    
         
            +
                      alias :contract :build_contract
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
                      def validate(state, with: nil)
         
     | 
| 
      
 56 
     | 
    
         
            +
                        if auto_wire_options && contract_options.any?
         
     | 
| 
      
 57 
     | 
    
         
            +
                          with ||= contract_options.zip(contract_options).to_h
         
     | 
| 
      
 58 
     | 
    
         
            +
                        end
         
     | 
| 
      
 59 
     | 
    
         
            +
                        opts = Hash(with).map { |to, from| [to, state[from]] }.to_h
         
     | 
| 
      
 60 
     | 
    
         
            +
                        validate_with(state[:input], opts)
         
     | 
| 
      
 61 
     | 
    
         
            +
                          .then { |params| state.update(params: params) }
         
     | 
| 
      
 62 
     | 
    
         
            +
                      end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                      def validate_with(input, opts = {})
         
     | 
| 
      
 65 
     | 
    
         
            +
                        result = contract(opts).call(input)
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                        result.success? ? wrap(result.values.to_h) : error(:validation, details: result.errors.to_h)
         
     | 
| 
      
 68 
     | 
    
         
            +
                      end
         
     | 
| 
      
 69 
     | 
    
         
            +
                    end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                    def self.apply(operation, auto_wire_options: false)
         
     | 
| 
      
 72 
     | 
    
         
            +
                      operation.contract_class = Dry::Validation::Contract
         
     | 
| 
      
 73 
     | 
    
         
            +
                      operation.auto_wire_options = auto_wire_options
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
                  end
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,25 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require 'sequel/model'
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
5 
     | 
    
         
             
            module Pathway
         
     | 
| 
       4 
6 
     | 
    
         
             
              module Plugins
         
     | 
| 
       5 
7 
     | 
    
         
             
                module SequelModels
         
     | 
| 
       6 
8 
     | 
    
         
             
                  module DSLMethods
         
     | 
| 
       7 
     | 
    
         
            -
                    def transaction(&bl)
         
     | 
| 
       8 
     | 
    
         
            -
                       
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                         
     | 
| 
       12 
     | 
    
         
            -
                       
     | 
| 
      
 9 
     | 
    
         
            +
                    def transaction(step_name = nil, &bl)
         
     | 
| 
      
 10 
     | 
    
         
            +
                      fail 'must provide a step or a block but not both' if !step_name.nil? == block_given?
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                      if step_name
         
     | 
| 
      
 13 
     | 
    
         
            +
                        transaction { step step_name }
         
     | 
| 
      
 14 
     | 
    
         
            +
                      else
         
     | 
| 
      
 15 
     | 
    
         
            +
                        around(-> steps, _ {
         
     | 
| 
      
 16 
     | 
    
         
            +
                          db.transaction(savepoint: true) do
         
     | 
| 
      
 17 
     | 
    
         
            +
                            raise Sequel::Rollback if steps.call.failure?
         
     | 
| 
      
 18 
     | 
    
         
            +
                          end
         
     | 
| 
      
 19 
     | 
    
         
            +
                        }, &bl)
         
     | 
| 
      
 20 
     | 
    
         
            +
                      end
         
     | 
| 
       13 
21 
     | 
    
         
             
                    end
         
     | 
| 
       14 
22 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
                    def after_commit(&bl)
         
     | 
| 
       16 
     | 
    
         
            -
                       
     | 
| 
       17 
     | 
    
         
            -
                        dsl = self.class::DSL.new(State.new(self, state.to_h.dup), self)
         
     | 
| 
      
 23 
     | 
    
         
            +
                    def after_commit(step_name = nil, &bl)
         
     | 
| 
      
 24 
     | 
    
         
            +
                      fail 'must provide a step or a block but not both' if !step_name.nil? == block_given?
         
     | 
| 
       18 
25 
     | 
    
         | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
      
 26 
     | 
    
         
            +
                      if step_name
         
     | 
| 
      
 27 
     | 
    
         
            +
                        after_commit { step step_name }
         
     | 
| 
      
 28 
     | 
    
         
            +
                      else
         
     | 
| 
      
 29 
     | 
    
         
            +
                        around(-> steps, state {
         
     | 
| 
      
 30 
     | 
    
         
            +
                          dsl = self.class::DSL.new(State.new(self, state.to_h.dup), self)
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                          db.after_commit do
         
     | 
| 
      
 33 
     | 
    
         
            +
                            steps.call(dsl)
         
     | 
| 
      
 34 
     | 
    
         
            +
                          end
         
     | 
| 
      
 35 
     | 
    
         
            +
                        }, &bl)
         
     | 
| 
      
 36 
     | 
    
         
            +
                      end
         
     | 
| 
       23 
37 
     | 
    
         
             
                    end
         
     | 
| 
       24 
38 
     | 
    
         
             
                  end
         
     | 
| 
       25 
39 
     | 
    
         | 
| 
         @@ -49,10 +63,11 @@ module Pathway 
     | 
|
| 
       49 
63 
     | 
    
         
             
                    delegate :db => :model_class
         
     | 
| 
       50 
64 
     | 
    
         | 
| 
       51 
65 
     | 
    
         
             
                    def fetch_model(state, from: model_class, search_by: search_field, using: search_by, to: result_key, overwrite: false, error_message: nil)
         
     | 
| 
       52 
     | 
    
         
            -
                      error_message ||= if from  
     | 
| 
       53 
     | 
    
         
            -
                                          Inflector.humanize(Inflector.underscore(Inflector.demodulize(from.name))) + ' not found'
         
     | 
| 
       54 
     | 
    
         
            -
                                        else
         
     | 
| 
      
 66 
     | 
    
         
            +
                      error_message ||= if (from == model_class)
         
     | 
| 
       55 
67 
     | 
    
         
             
                                          model_not_found
         
     | 
| 
      
 68 
     | 
    
         
            +
                                        elsif from.respond_to?(:name) || from.respond_to?(:model)
         
     | 
| 
      
 69 
     | 
    
         
            +
                                          from_name = (from.respond_to?(:name) ? from : from.model).name
         
     | 
| 
      
 70 
     | 
    
         
            +
                                          Inflector.humanize(Inflector.underscore(Inflector.demodulize(from_name))) + ' not found'
         
     | 
| 
       56 
71 
     | 
    
         
             
                                        end
         
     | 
| 
       57 
72 
     | 
    
         | 
| 
       58 
73 
     | 
    
         
             
                      if state[to].nil? || overwrite
         
     | 
    
        data/lib/pathway/result.rb
    CHANGED
    
    
    
        data/lib/pathway/rspec.rb
    CHANGED
    
    
| 
         @@ -1,30 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require 'pathway/rspec/matchers/form_schema_helpers'
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
5 
     | 
    
         
             
            RSpec::Matchers.define :accept_optional_fields do |*fields|
         
     | 
| 
       4 
6 
     | 
    
         
             
              match do |form|
         
     | 
| 
       5 
7 
     | 
    
         
             
                @form, @fields = form, fields
         
     | 
| 
       6 
8 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
                not_defined.empty? && 
     | 
| 
      
 9 
     | 
    
         
            +
                not_defined.empty? &&
         
     | 
| 
      
 10 
     | 
    
         
            +
                  not_optional.empty? &&
         
     | 
| 
      
 11 
     | 
    
         
            +
                  allowing_null_values_matches? &&
         
     | 
| 
      
 12 
     | 
    
         
            +
                  not_allowing_null_values_matches?
         
     | 
| 
       8 
13 
     | 
    
         
             
              end
         
     | 
| 
       9 
14 
     | 
    
         | 
| 
       10 
15 
     | 
    
         
             
              match_when_negated do |form|
         
     | 
| 
      
 16 
     | 
    
         
            +
                raise NotImplementedError, 'expect().not_to accept_optional_fields.not_allowing_null_values is not supported.' if @allowing_null_values || @not_allowing_null_values
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
       11 
18 
     | 
    
         
             
                @form, @fields = form, fields
         
     | 
| 
       12 
19 
     | 
    
         | 
| 
       13 
20 
     | 
    
         
             
                not_defined.empty? && optional.empty?
         
     | 
| 
       14 
21 
     | 
    
         
             
              end
         
     | 
| 
       15 
22 
     | 
    
         | 
| 
       16 
23 
     | 
    
         
             
              description do
         
     | 
| 
       17 
     | 
    
         
            -
                 
     | 
| 
      
 24 
     | 
    
         
            +
                null_value_allowed = @allowing_null_values ? ' allowing null values' : ''
         
     | 
| 
      
 25 
     | 
    
         
            +
                null_value_disallowed = @not_allowing_null_values ? ' not allowing null values' : ''
         
     | 
| 
      
 26 
     | 
    
         
            +
                "accept #{field_list} as optional #{pluralize_fields}#{null_value_allowed}#{null_value_disallowed}"
         
     | 
| 
       18 
27 
     | 
    
         
             
              end
         
     | 
| 
       19 
28 
     | 
    
         | 
| 
       20 
29 
     | 
    
         
             
              failure_message do
         
     | 
| 
       21 
     | 
    
         
            -
                 
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
      
 30 
     | 
    
         
            +
                null_value_allowed = @allowing_null_values ? ' allowing null values' : ''
         
     | 
| 
      
 31 
     | 
    
         
            +
                null_value_disallowed = @not_allowing_null_values ? ' not allowing null values' : ''
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                "Expected to accept #{field_list} as optional #{pluralize_fields}#{null_value_allowed}#{null_value_disallowed} but " +
         
     | 
| 
      
 34 
     | 
    
         
            +
                  as_sentence([not_optional_list, not_defined_list, accepting_null_list, not_accepting_null_list].compact,
         
     | 
| 
      
 35 
     | 
    
         
            +
                              connector: '; ', last_connector: '; and ')
         
     | 
| 
       23 
36 
     | 
    
         
             
              end
         
     | 
| 
       24 
37 
     | 
    
         | 
| 
       25 
38 
     | 
    
         
             
              failure_message_when_negated do
         
     | 
| 
       26 
39 
     | 
    
         
             
                "Did not expect to accept #{field_list} as optional #{pluralize_fields} but " +
         
     | 
| 
       27 
     | 
    
         
            -
                  [optional_list, not_defined_list].compact.join( 
     | 
| 
      
 40 
     | 
    
         
            +
                  [optional_list, not_defined_list].compact.join('; and ')
         
     | 
| 
       28 
41 
     | 
    
         
             
              end
         
     | 
| 
       29 
42 
     | 
    
         | 
| 
       30 
43 
     | 
    
         
             
              include Pathway::Rspec::FormSchemaHelpers
         
     | 
| 
         @@ -34,7 +47,19 @@ RSpec::Matchers.define :accept_optional_fields do |*fields| 
     | 
|
| 
       34 
47 
     | 
    
         
             
              end
         
     | 
| 
       35 
48 
     | 
    
         | 
| 
       36 
49 
     | 
    
         
             
              def not_optional_list
         
     | 
| 
       37 
     | 
    
         
            -
                "#{as_list( 
     | 
| 
      
 50 
     | 
    
         
            +
                "#{as_list(not_optional)} #{were_was(not_optional)} not optional" if not_optional.any?
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              chain :allowing_null_values do
         
     | 
| 
      
 54 
     | 
    
         
            +
                fail 'cannot use allowing_null_values and not_allowing_null_values at the same time' if @not_allowing_null_values
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                @allowing_null_values = true
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              chain :not_allowing_null_values do
         
     | 
| 
      
 60 
     | 
    
         
            +
                fail 'cannot use allowing_null_values and not_allowing_null_values at the same time' if @allowing_null_values
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                @not_allowing_null_values = true
         
     | 
| 
       38 
63 
     | 
    
         
             
              end
         
     | 
| 
       39 
64 
     | 
    
         
             
            end
         
     | 
| 
       40 
65 
     | 
    
         | 
| 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require 'pathway/rspec/matchers/list_helpers'
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
5 
     | 
    
         
             
            RSpec::Matchers.define :fail_on do |input|
         
     | 
| 
         @@ -38,20 +40,20 @@ RSpec::Matchers.define :fail_on do |input| 
     | 
|
| 
       38 
40 
     | 
    
         
             
              alias :and_details :details
         
     | 
| 
       39 
41 
     | 
    
         | 
| 
       40 
42 
     | 
    
         
             
              description do
         
     | 
| 
       41 
     | 
    
         
            -
                 
     | 
| 
      
 43 
     | 
    
         
            +
                'fail' + (@type ? " with :#@type error" : '')
         
     | 
| 
       42 
44 
     | 
    
         
             
              end
         
     | 
| 
       43 
45 
     | 
    
         | 
| 
       44 
46 
     | 
    
         
             
              failure_message do
         
     | 
| 
       45 
47 
     | 
    
         
             
                if !failure?
         
     | 
| 
       46 
48 
     | 
    
         
             
                  "Expected operation to fail but it didn't"
         
     | 
| 
       47 
49 
     | 
    
         
             
                else
         
     | 
| 
       48 
     | 
    
         
            -
                   
     | 
| 
      
 50 
     | 
    
         
            +
                  'Expected failed operation to ' +
         
     | 
| 
       49 
51 
     | 
    
         
             
                    as_sentence(failure_descriptions, connector: '; ', last_connector: '; and ')
         
     | 
| 
       50 
52 
     | 
    
         
             
                end
         
     | 
| 
       51 
53 
     | 
    
         
             
              end
         
     | 
| 
       52 
54 
     | 
    
         | 
| 
       53 
55 
     | 
    
         
             
              failure_message_when_negated do
         
     | 
| 
       54 
     | 
    
         
            -
                 
     | 
| 
      
 56 
     | 
    
         
            +
                'Did not expected operation to fail but it did'
         
     | 
| 
       55 
57 
     | 
    
         
             
              end
         
     | 
| 
       56 
58 
     | 
    
         | 
| 
       57 
59 
     | 
    
         
             
              def failure?
         
     |