class RuboCop::Cop::RSpec::SingleArgumentMessageChain

Checks that chains of messages contain more than one element.

@example

# bad
allow(foo).to receive_message_chain(:bar).and_return(42)

# good
allow(foo).to receive(:bar).and_return(42)

# also good
allow(foo).to receive(:bar, :baz)
allow(foo).to receive("bar.baz")

Constants

MSG

Public Instance Methods

autocorrect(node) click to toggle source
# File lib/rubocop/cop/rspec/single_argument_message_chain.rb, line 37
def autocorrect(node)
  lambda do |corrector|
    corrector.replace(node.loc.selector, replacement(node.method_name))
    message_chain(node) do |arg|
      autocorrect_hash_arg(corrector, arg) if single_key_hash?(arg)
      autocorrect_array_arg(corrector, arg) if arg.array_type?
    end
  end
end
on_send(node) click to toggle source
# File lib/rubocop/cop/rspec/single_argument_message_chain.rb, line 29
def on_send(node)
  message_chain(node) do |arg|
    return if valid_usage?(arg)

    add_offense(node, location: :selector)
  end
end

Private Instance Methods

autocorrect_array_arg(corrector, arg) click to toggle source
# File lib/rubocop/cop/rspec/single_argument_message_chain.rb, line 71
def autocorrect_array_arg(corrector, arg)
  value = arg.children.first

  corrector.replace(arg.loc.expression, value.source)
end
autocorrect_hash_arg(corrector, arg) click to toggle source
# File lib/rubocop/cop/rspec/single_argument_message_chain.rb, line 63
def autocorrect_hash_arg(corrector, arg)
  key, value = *arg.children.first

  corrector.replace(arg.loc.expression, key_to_arg(key))
  corrector.insert_after(arg.parent.loc.end,
                         ".and_return(#{value.source})")
end
key_to_arg(node) click to toggle source
# File lib/rubocop/cop/rspec/single_argument_message_chain.rb, line 77
def key_to_arg(node)
  key, = *node
  node.sym_type? ? ":#{key}" : node.source
end
message(node) click to toggle source
# File lib/rubocop/cop/rspec/single_argument_message_chain.rb, line 86
def message(node)
  method = node.method_name

  format(MSG, recommended: replacement(method), called: method)
end
replacement(method) click to toggle source
# File lib/rubocop/cop/rspec/single_argument_message_chain.rb, line 82
def replacement(method)
  method.equal?(:receive_message_chain) ? 'receive' : 'stub'
end
single_element_array?(node) click to toggle source
# File lib/rubocop/cop/rspec/single_argument_message_chain.rb, line 59
def single_element_array?(node)
  node.child_nodes.one?
end
valid_usage?(node) click to toggle source
# File lib/rubocop/cop/rspec/single_argument_message_chain.rb, line 49
def valid_usage?(node)
  return true unless node.literal? || node.array_type?

  case node.type
  when :hash then !single_key_hash?(node)
  when :array then !single_element_array?(node)
  else node.to_s.include?('.')
  end
end