class RuboCop::Cop::RSpec::ReceiveCounts

Check for `once` and `twice` receive counts matchers usage.

@example

# bad
expect(foo).to receive(:bar).exactly(1).times
expect(foo).to receive(:bar).exactly(2).times
expect(foo).to receive(:bar).at_least(1).times
expect(foo).to receive(:bar).at_least(2).times
expect(foo).to receive(:bar).at_most(1).times
expect(foo).to receive(:bar).at_most(2).times

# good
expect(foo).to receive(:bar).once
expect(foo).to receive(:bar).twice
expect(foo).to receive(:bar).at_least(:once)
expect(foo).to receive(:bar).at_least(:twice)
expect(foo).to receive(:bar).at_most(:once)
expect(foo).to receive(:bar).at_most(:twice).times

Constants

MSG

Public Instance Methods

autocorrect(node) click to toggle source
# File lib/rubocop/cop/rspec/receive_counts.rb, line 49
def autocorrect(node)
  lambda do |corrector|
    replacement = matcher_for(
      node.method_name,
      node.first_argument.source.to_i
    )

    original = range(node.parent, node)
    corrector.replace(original, replacement)
  end
end
on_send(node) click to toggle source
# File lib/rubocop/cop/rspec/receive_counts.rb, line 35
def on_send(node)
  receive_counts(node) do |offending_node|
    return unless stub?(offending_node.receiver)

    offending_range = range(node, offending_node)

    add_offense(
      offending_node,
      message: message_for(offending_node, offending_range.source),
      location: offending_range
    )
  end
end

Private Instance Methods

matcher_for(method, count) click to toggle source
# File lib/rubocop/cop/rspec/receive_counts.rb, line 71
def matcher_for(method, count)
  matcher = count == 1 ? 'once' : 'twice'
  if method == :exactly
    ".#{matcher}"
  else
    ".#{method}(:#{matcher})"
  end
end
message_for(node, source) click to toggle source
# File lib/rubocop/cop/rspec/receive_counts.rb, line 63
def message_for(node, source)
  alternative = matcher_for(
    node.method_name,
    node.first_argument.source.to_i
  )
  format(MSG, alternative: alternative, original: source)
end
range(node, offending_node) click to toggle source
# File lib/rubocop/cop/rspec/receive_counts.rb, line 80
def range(node, offending_node)
  offending_node.loc.dot.with(
    end_pos: node.loc.expression.end_pos
  )
end