class RuboCop::Cop::Rails::HttpPositionalArguments

get :new, **options
get :new, params: { user_id: 1 }
# good
get :new, { user_id: 1}
# bad
@example
which makes the http methods incompatible behavior.
NOTE: It does not detect any cases where ‘include Rack::Test::Methods` is used
.rubocop.yml file to 4.2.
Rails/HttpPositionalArguments cop or set your TargetRailsVersion in your
If you are running Rails < 5 you should disable the
change them to use keyword args. This cop only applies to Rails >= 5.
`put`, `patch` without the usage of keyword arguments in your tests and
Identifies usages of http methods like `get`, `post`,

def convert_hash_data(data, type)

def convert_hash_data(data, type)
  return '' if data.hash_type? && data.empty?
  hash_data = if data.hash_type?
                format('{ %<data>s }', data: data.pairs.map(&:source).join(', '))
              else
                # user supplies an object,
                # no need to surround with braces
                data.source
              end
  format(', %<type>s: %<hash_data>s', type: type, hash_data: hash_data)
end

def correction(node)

def correction(node)
  http_path, *data = *node.arguments
  controller_action = http_path.source
  params = convert_hash_data(data.first, 'params')
  session = convert_hash_data(data.last, 'session') if data.size > 1
  format(correction_template(node), name: node.method_name,
                                    action: controller_action,
                                    params: params,
                                    session: session)
end

def correction_template(node)

def correction_template(node)
  if parentheses?(node)
    '%<name>s(%<action>s%<params>s%<session>s)'
  else
    '%<name>s %<action>s%<params>s%<session>s'
  end
end

def format_arg?(node)

def format_arg?(node)
  node.sym_type? && node.value == :format
end

def highlight_range(node)

def highlight_range(node)
  _http_path, *data = *node.arguments
  range_between(data.first.source_range.begin_pos, data.last.source_range.end_pos)
end

def in_routing_block?(node)

def in_routing_block?(node)
  !!node.each_ancestor(:block).detect { |block| ROUTING_METHODS.include?(block.method_name) }
end

def needs_conversion?(data)

rubocop:disable Metrics/CyclomaticComplexity
def needs_conversion?(data)
  return false if data.forwarded_args_type? || forwarded_kwrestarg?(data)
  return true unless data.hash_type?
  return false if kwsplat_hash?(data)
  data.each_pair.none? do |pair|
    special_keyword_arg?(pair.key) || (format_arg?(pair.key) && data.pairs.one?)
  end
end

def on_send(node)

def on_send(node)
  return if in_routing_block?(node) || use_rack_test_methods?
  http_request?(node) do |data|
    return unless needs_conversion?(data)
    message = format(MSG, verb: node.method_name)
    add_offense(highlight_range(node), message: message) do |corrector|
      # given a pre Rails 5 method: get :new, {user_id: @user.id}, {}
      #
      # @return lambda of auto correct procedure
      # the result should look like:
      #     get :new, params: { user_id: @user.id }, session: {}
      # the http_method is the method used to call the controller
      # the controller node can be a symbol, method, object or string
      # that represents the path/action on the Rails controller
      # the data is the http parameters and environment sent in
      # the Rails 5 http call
      corrector.replace(node, correction(node))
    end
  end
end

def special_keyword_arg?(node)

def special_keyword_arg?(node)
  node.sym_type? && KEYWORD_ARGS.include?(node.value)
end

def use_rack_test_methods?

def use_rack_test_methods?
  processed_source.ast.each_descendant(:send).any? do |node|
    include_rack_test_methods?(node)
  end
end