1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Checks that message expectations are set using spies.
#
# This cop can be configured in your configuration using the
# `EnforcedStyle` option and supports `--auto-gen-config`.
#
# @example `EnforcedStyle: have_received` (default)
#
# # bad
# expect(foo).to receive(:bar)
# do_something
#
# # good
# allow(foo).to receive(:bar) # or use instance_spy
# do_something
# expect(foo).to have_received(:bar)
#
# @example `EnforcedStyle: receive`
#
# # bad
# allow(foo).to receive(:bar)
# do_something
# expect(foo).to have_received(:bar)
#
# # good
# expect(foo).to receive(:bar)
# do_something
#
class MessageSpies < Base
include ConfigurableEnforcedStyle
MSG_RECEIVE = 'Prefer `receive` for setting message expectations.'
MSG_HAVE_RECEIVED = 'Prefer `have_received` for setting message ' \
'expectations. Setup `%<source>s` as a spy using ' \
'`allow` or `instance_spy`.'
SUPPORTED_STYLES = %w[have_received receive].freeze
RESTRICT_ON_SEND = Runners.all
# @!method message_expectation(node)
def_node_matcher :message_expectation, %(
(send (send nil? :expect $_) #Runners.all ...)
)
# @!method receive_message(node)
def_node_search :receive_message, %(
$(send nil? {:receive :have_received} ...)
)
def on_send(node)
receive_message_matcher(node) do |receiver, message_matcher|
return correct_style_detected if preferred_style?(message_matcher)
add_offense(
message_matcher.loc.selector,
message: error_message(receiver)
) { opposite_style_detected }
end
end
private
def receive_message_matcher(node)
return unless (receiver = message_expectation(node))
receive_message(node) { |match| yield(receiver, match) }
end
def preferred_style?(expectation)
expectation.method_name.equal?(style)
end
def error_message(receiver)
case style
when :receive
MSG_RECEIVE
when :have_received
format(MSG_HAVE_RECEIVED, source: receiver.source)
end
end
end
end
end
end
|