Class: RuboCop::Cop::Rails::HttpPositionalArguments
- 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, path without the usage of keyword arguments in your tests and change them to use keyword arguments.
Constant Summary collapse
- MSG =
'Use keyword arguments instead of ' \ 'positional arguments for http call: `%s`.'.freeze
- KEYWORD_ARGS =
[ :headers, :env, :params, :body, :flash, :as, :xhr, :session, :method, :format ].freeze
- HTTP_METHODS =
[:get, :post, :put, :patch, :delete, :head].freeze
Constants included from Util
Util::ASGN_NODES, Util::BYTE_ORDER_MARK, Util::EQUALS_ASGN_NODES, Util::LITERAL_REGEX, 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
-
#needs_conversion?(data) ⇒ Boolean
True if the line needs to be converted.
- #on_send(node) ⇒ Object
Methods inherited from Cop
#add_offense, all, #config_to_allow_offenses, #config_to_allow_offenses=, #cop_config, cop_name, #cop_name, cop_type, #correct, #debug?, #details, #display_cop_names?, #display_style_guide?, #duplicate_location?, #excluded_file?, #extra_details?, #find_location, #highlights, inherited, #initialize, #join_force?, lint?, match?, #message, #messages, non_rails, #parse, qualified_cop_name, #reference_url, #relevant_file?, #style_guide_url, #target_ruby_version
Methods included from 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_acceptable?, double_quotes_required?, effective_column, ends_its_line?, escape_string, first_part_of_call_chain, hard_to_type?, interpret_string_escapes, line_distance, line_range, move_pos, needs_escaping?, numeric_range_size, on_node, operator?, parentheses?, parenthesized_call?, preceed?, range_between, range_with_surrounding_comma, range_with_surrounding_space, same_line?, source_range, strip_quotes, stripped_source_upto, to_string_literal, to_symbol_literal, within_node?
Methods included from PathUtil
absolute?, match_path?, relative_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
77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/rubocop/cop/rails/http_positional_arguments.rb', line 77 def autocorrect(node) _receiver, http_method, http_path, *data = *node controller_action = http_path.source params = convert_hash_data(data.first, 'params') headers = convert_hash_data(data.last, 'headers') if data.count > 1 # the range of the text to replace, which is the whole line code_to_replace = node.loc.expression # what to replace with new_code = format('%s %s%s%s', http_method, controller_action, params, headers) ->(corrector) { corrector.replace(code_to_replace, new_code) } end |
#convert_hash_data(data, type) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/rubocop/cop/rails/http_positional_arguments.rb', line 54 def convert_hash_data(data, type) # empty hash or no hash return empty string return '' if data.nil? || data.children.count < 1 hash_data = if data.hash_type? format('{ %s }', data.children.map(&:source).join(', ')) else # user supplies an object, # no need to surround with braces data.source end format(', %s: %s', type, hash_data) end |
#needs_conversion?(data) ⇒ Boolean
Returns true if the line needs to be converted.
44 45 46 47 48 49 50 51 52 |
# File 'lib/rubocop/cop/rails/http_positional_arguments.rb', line 44 def needs_conversion?(data) # if the line has already been converted to use keyword args # then skip # ie. get :new, params: { user_id: 1 } (looking for keyword arg) value = data.descendants.find do |d| KEYWORD_ARGS.include?(d.children.first) if d.type == :sym end value.nil? end |
#on_send(node) ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/rubocop/cop/rails/http_positional_arguments.rb', line 25 def on_send(node) receiver, http_method, http_path, data = *node # if the first word on the line is not an http method, then skip return unless HTTP_METHODS.include?(http_method) # 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) # ensures this is the first method on the line # there is an edge case here where sometimes the http method is # wrapped into another method, but its just safer to skip those # cases and process manually return unless receiver.nil? # a http_method without a path?, must be something else return if http_path.nil? add_offense(node, node.loc.selector, format(MSG, node.method_name)) end |