class RSpec::Support::MethodSignature

Extracts info about the number of arguments and allowed/required keyword args of a given method.

@private

Constants

INFINITY

Attributes

max_non_kw_args[R]
min_non_kw_args[R]
optional_kw_args[R]
required_kw_args[R]

Public Class Methods

new(method) click to toggle source
# File lib/rspec/support/method_signature_verifier.rb, line 14
def initialize(method)
  @method           = method
  @optional_kw_args = []
  @required_kw_args = []
  classify_parameters
end

Public Instance Methods

arbitrary_kw_args?() click to toggle source
# File lib/rspec/support/method_signature_verifier.rb, line 96
def arbitrary_kw_args?
  @allows_any_kw_args
end
classify_arity(arity=@method.arity) click to toggle source
# File lib/rspec/support/method_signature_verifier.rb, line 36
def classify_arity(arity=@method.arity)
  if arity < 0
    # `~` inverts the one's complement and gives us the
    # number of required args
    @min_non_kw_args = ~arity
    @max_non_kw_args = INFINITY
  else
    @min_non_kw_args = arity
    @max_non_kw_args = arity
  end
end
classify_parameters() click to toggle source
# File lib/rspec/support/method_signature_verifier.rb, line 104
def classify_parameters
  optional_non_kw_args = @min_non_kw_args = 0
  @allows_any_kw_args = false

  @method.parameters.each do |(type, name)|
    case type
    # def foo(a:)
    when :keyreq  then @required_kw_args << name
    # def foo(a: 1)
    when :key     then @optional_kw_args << name
    # def foo(**kw_args)
    when :keyrest then @allows_any_kw_args = true
    # def foo(a)
    when :req     then @min_non_kw_args += 1
    # def foo(a = 1)
    when :opt     then optional_non_kw_args += 1
    # def foo(*a)
    when :rest    then optional_non_kw_args = INFINITY
    end
  end

  @max_non_kw_args = @min_non_kw_args + optional_non_kw_args
  @allowed_kw_args = @required_kw_args + @optional_kw_args
end
could_contain_kw_args?(args) click to toggle source

Without considering what the last arg is, could it contain keyword arguments?

# File lib/rspec/support/method_signature_verifier.rb, line 90
def could_contain_kw_args?(args)
  return false if args.count <= min_non_kw_args

  @allows_any_kw_args || @allowed_kw_args.any?
end
description() click to toggle source
# File lib/rspec/support/method_signature_verifier.rb, line 49
def description
  @description ||= begin
    parts = []

    unless non_kw_args_arity_description == "0"
      parts << "arity of #{non_kw_args_arity_description}"
    end

    if @optional_kw_args.any?
      parts << "optional keyword args (#{@optional_kw_args.map(&:inspect).join(", ")})"
    end

    if @required_kw_args.any?
      parts << "required keyword args (#{@required_kw_args.map(&:inspect).join(", ")})"
    end

    parts << "any additional keyword args" if @allows_any_kw_args

    parts.join(" and ")
  end
end
has_kw_args_in?(args) click to toggle source

If the last argument is Hash, Ruby will treat only symbol keys as keyword arguments the rest will be grouped in another Hash and passed as positional argument.

# File lib/rspec/support/method_signature_verifier.rb, line 82
def has_kw_args_in?(args)
  Hash === args.last &&
    could_contain_kw_args?(args) &&
    (args.last.empty? || args.last.keys.any? { |x| x.is_a?(Symbol) })
end
invalid_kw_args_from(given_kw_args) click to toggle source
# File lib/rspec/support/method_signature_verifier.rb, line 75
def invalid_kw_args_from(given_kw_args)
  return [] if @allows_any_kw_args
  given_kw_args - @allowed_kw_args
end
missing_kw_args_from(given_kw_args) click to toggle source
# File lib/rspec/support/method_signature_verifier.rb, line 71
def missing_kw_args_from(given_kw_args)
  @required_kw_args - given_kw_args
end
non_kw_args_arity_description() click to toggle source
# File lib/rspec/support/method_signature_verifier.rb, line 21
def non_kw_args_arity_description
  case max_non_kw_args
  when min_non_kw_args then min_non_kw_args.to_s
  when INFINITY then "#{min_non_kw_args} or more"
  else "#{min_non_kw_args} to #{max_non_kw_args}"
  end
end
unlimited_args?() click to toggle source
# File lib/rspec/support/method_signature_verifier.rb, line 100
def unlimited_args?
  @max_non_kw_args == INFINITY
end
valid_non_kw_args?(positional_arg_count, optional_max_arg_count=positional_arg_count) click to toggle source
# File lib/rspec/support/method_signature_verifier.rb, line 29
def valid_non_kw_args?(positional_arg_count, optional_max_arg_count=positional_arg_count)
  return true if positional_arg_count.nil?

  min_non_kw_args <= positional_arg_count &&
    optional_max_arg_count <= max_non_kw_args
end