Sha256: 593a8bfce93090a8c2ae606d7fa2c589ab751cf63797bad385a1aa42bc016649

Contents?: true

Size: 1.57 KB

Versions: 2

Compression:

Stored size: 1.57 KB

Contents

require_relative "../share/simulates_argument_error"

module Mocktail
  class ValidatesArguments
    def self.disable!
      Thread.current[:mocktail_arity_validation_disabled] = true
    end

    def self.enable!
      Thread.current[:mocktail_arity_validation_disabled] = false
    end

    def self.disabled?
      Thread.current[:mocktail_arity_validation_disabled]
    end

    def self.optional(disable, &blk)
      return blk.call unless disable

      disable!
      blk.call.tap do
        enable!
      end
    end

    def initialize
      @simulates_argument_error = SimulatesArgumentError.new
    end

    def validate(dry_call)
      return if self.class.disabled?

      arg_params, kwarg_params = dry_call.original_method.parameters.reject { |type, _|
        type == :block
      }.partition { |type, _|
        [:req, :opt, :rest].include?(type)
      }

      unless args_match?(arg_params, dry_call.args) &&
          kwargs_match?(kwarg_params, dry_call.kwargs)
        raise @simulates_argument_error.simulate(arg_params, dry_call.args, kwarg_params, dry_call.kwargs)
      end
    end

    private

    def args_match?(arg_params, args)
      args.size >= arg_params.count { |type, _| type == :req } &&
        (arg_params.any? { |type, _| type == :rest } || args.size <= arg_params.size)
    end

    def kwargs_match?(kwarg_params, kwargs)
      kwarg_params.select { |type, _| type == :keyreq }.all? { |_, name| kwargs.key?(name) } &&
        (kwarg_params.any? { |type, _| type == :keyrest } || kwargs.keys.all? { |name| kwarg_params.any? { |_, key| name == key } })
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
mocktail-0.0.2 lib/mocktail/handles_dry_call/validates_arguments.rb
mocktail-0.0.1 lib/mocktail/handles_dry_call/validates_arguments.rb