Class: RuboCop::Cop::Rails::HttpPositionalArguments
- Extended by:
- TargetRailsVersion
- Defined in:
- lib/rubocop/cop/rails/http_positional_arguments.rb
Overview
This cop is used to identify usages of http methods like get, post, put, patch without the usage of keyword arguments in your tests and change them to use keyword args. This cop only applies to Rails >= 5 . If you are not running Rails < 5 you should disable # the Rails/HttpPositionalArguments cop or set your TargetRailsVersion in your .rubocop.yml file to 4.0, etc.
Constant Summary collapse
- MSG =
'Use keyword arguments instead of ' \ 'positional arguments for http call: `%s`.'.freeze
- KEYWORD_ARGS =
i[ headers env params body flash as xhr session method ].freeze
- HTTP_METHODS =
i[get post put patch delete head].freeze
Constants included from Util
Util::ASGN_NODES, Util::BYTE_ORDER_MARK, Util::CONDITIONAL_NODES, Util::EQUALS_ASGN_NODES, Util::LITERAL_REGEX, Util::LOGICAL_OPERATOR_NODES, Util::MODIFIER_NODES, Util::OPERATOR_METHODS, Util::SHORTHAND_ASGN_NODES
Instance Attribute Summary
Attributes inherited from Cop
#config, #corrections, #offenses, #processed_source
Instance Method Summary collapse
-
#autocorrect(node) ⇒ Object
given a pre Rails 5 method: get :new, user_id: @user.id, {}.
- #convert_hash_data(data, type) ⇒ Object
- #format_arg?(node) ⇒ Boolean
-
#needs_conversion?(data) ⇒ Boolean
True if the line needs to be converted.
- #on_send(node) ⇒ Object
- #special_keyword_arg?(node) ⇒ Boolean
Methods included from TargetRailsVersion
minimum_target_rails_version, support_target_rails_version?
Methods inherited from Cop
#add_offense, all, autocorrect_incompatible_with, badge, #config_to_allow_offenses, #config_to_allow_offenses=, #cop_config, cop_name, #cop_name, #correct, department, #duplicate_location?, #excluded_file?, #find_location, #highlights, inherited, #initialize, #join_force?, lint?, match?, #message, #messages, non_rails, #parse, qualified_cop_name, #relevant_file?, #target_rails_version, #target_ruby_version
Methods included from AST::Sexp
Methods included from NodePattern::Macros
#def_node_matcher, #def_node_search, #node_search, #node_search_all, #node_search_body, #node_search_first
Methods included from AutocorrectLogic
#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #support_autocorrect?
Methods included from IgnoredNode
#ignore_node, #ignored_node?, #part_of_ignored_node?
Methods included from Util
begins_its_line?, block_length, comment_line?, compatible_external_encoding_for?, directions, double_quotes_required?, effective_column, ends_its_line?, escape_string, first_part_of_call_chain, interpret_string_escapes, line_distance, line_range, move_pos, needs_escaping?, on_node, operator?, parentheses?, parenthesized_call?, preceed?, range_between, range_by_whole_lines, range_with_surrounding_comma, range_with_surrounding_space, same_line?, source_range, strip_quotes, stripped_source_upto, symbol_without_quote?, to_string_literal, to_supported_styles, to_symbol_literal, within_node?
Methods included from PathUtil
absolute?, match_path?, relative_path, smart_path
Constructor Details
This class inherits a constructor from RuboCop::Cop::Cop
Instance Method Details
#autocorrect(node) ⇒ Object
given a pre Rails 5 method: get :new, user_id: @user.id, {}
the result should look like:
get :new, params: { user_id: @user.id }, headers: {}
the http_method is the method use 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
89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/rubocop/cop/rails/http_positional_arguments.rb', line 89 def autocorrect(node) http_path, *data = *node.arguments controller_action = http_path.source params = convert_hash_data(data.first, 'params') headers = convert_hash_data(data.last, 'headers') if data.size > 1 # the range of the text to replace, which is the whole line code_to_replace = node.loc.expression # what to replace with format = parentheses?(node) ? '%s(%s%s%s)' : '%s %s%s%s' new_code = format(format, node.method_name, controller_action, params, headers) ->(corrector) { corrector.replace(code_to_replace, new_code) } end |
#convert_hash_data(data, type) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/rubocop/cop/rails/http_positional_arguments.rb', line 66 def convert_hash_data(data, type) # empty hash or no hash return empty string return '' if data.nil? || data.children.empty? hash_data = if data.hash_type? format('{ %s }', data.pairs.map(&:source).join(', ')) else # user supplies an object, # no need to surround with braces data.source end format(', %s: %s', type, hash_data) end |
#format_arg?(node) ⇒ Boolean
62 63 64 |
# File 'lib/rubocop/cop/rails/http_positional_arguments.rb', line 62 def format_arg?(node) node.children.first == :format if node.sym_type? end |
#needs_conversion?(data) ⇒ Boolean
Returns true if the line needs to be converted.
46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/rubocop/cop/rails/http_positional_arguments.rb', line 46 def needs_conversion?(data) return true unless data.hash_type? children = data.child_nodes value = children.find do |d| special_keyword_arg?(d.children.first) || (format_arg?(d.children.first) && children.size == 1) end value.nil? end |
#on_send(node) ⇒ Object
35 36 37 38 39 40 41 42 43 |
# File 'lib/rubocop/cop/rails/http_positional_arguments.rb', line 35 def on_send(node) data = http_request?(node) # if the data is nil then we don't need to add keyword arguments # because there is no data to put in params or headers, so skip return if data.nil? return unless needs_conversion?(data) add_offense(node, node.loc.selector, format(MSG, node.method_name)) end |
#special_keyword_arg?(node) ⇒ Boolean
58 59 60 |
# File 'lib/rubocop/cop/rails/http_positional_arguments.rb', line 58 def special_keyword_arg?(node) KEYWORD_ARGS.include?(node.children.first) if node.sym_type? end |