Skip to content

Commit

Permalink
Use simple lookup table for replacements in StubbedMock
Browse files Browse the repository at this point in the history
  • Loading branch information
corsonknowles committed Nov 2, 2024
1 parent e80d28c commit e6bbc1d
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 16 deletions.
24 changes: 9 additions & 15 deletions lib/rubocop/cop/rspec/stubbed_mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@ module RSpec
class StubbedMock < Base
MSG = 'Prefer `%<replacement>s` over `%<method_name>s` when ' \
'configuring a response.'
REPLACEMENTS = {
expect: :allow,
is_expected: 'allow(subject)',
expect_any_instance_of: :allow_any_instance_of
}.freeze
REPLACABLE_METHODS = Set.new(REPLACEMENTS.keys).freeze
RESTRICT_ON_SEND = %i[to].freeze

# @!method message_expectation?(node)
# Match message expectation matcher
Expand Down Expand Up @@ -60,7 +67,7 @@ class StubbedMock < Base
# @yield [RuboCop::AST::Node] expectation, method name, matcher
def_node_matcher :expectation, <<~PATTERN
(send
$(send nil? $#Expectations.all ...)
$(send nil? $REPLACABLE_METHODS ...)
:to $_)
PATTERN

Expand Down Expand Up @@ -133,8 +140,6 @@ class StubbedMock < Base
}
PATTERN

RESTRICT_ON_SEND = %i[to].freeze

def on_send(node)
expectation(node) do |expectation, method_name, matcher|
on_expectation(expectation, method_name, matcher)
Expand All @@ -157,18 +162,7 @@ def on_expectation(expectation, method_name, matcher)
def msg(method_name)
format(MSG,
method_name: method_name,
replacement: replacement(method_name))
end

def replacement(method_name)
case method_name
when :expect
:allow
when :is_expected
'allow(subject)'
when :expect_any_instance_of
:allow_any_instance_of
end
replacement: REPLACEMENTS.fetch(method_name))
end
end
end
Expand Down
37 changes: 36 additions & 1 deletion spec/rubocop/cop/rspec/stubbed_mock_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,47 @@
RUBY
end

it 'tolerates passed arguments without parentheses' do
it 'flags even when passed arguments without parentheses' do
expect_offense(<<~RUBY)
expect(Foo)
^^^^^^^^^^^ Prefer `allow` over `expect` when configuring a response.
.to receive(:new)
.with(bar).and_return baz
RUBY
end

it 'flags `should_receive`', skip: 'Not implemented yet' do
expect_offense(<<~RUBY)
foo.should_receive(:bar).and_return(:baz)
^^^^^^^^^^^^^^^^^^^ Prefer `allow` over `should_receive` when configuring a response.
RUBY
end

it 'flags `should_not_receive`', skip: 'Not implemented yet' do
expect_offense(<<~RUBY)
foo.should_not_receive(:bar)
^^^^^^^^^^^^^^^^^^^^^^ Prefer `allow(...).not_to receive` over `should_not_receive` when configuring a response.
RUBY
end

it 'flags `are_expected`', skip: 'Not implemented yet' do
expect_offense(<<~RUBY)
are_expected.to receive(:bar).and_return(:baz)
^^^^^^^^^^^^ Prefer `` over `are_expected` when configuring a response.
RUBY
end

it 'flags `should`', skip: 'Not implemented yet' do
expect_offense(<<~RUBY)
foo.should receive(:bar).and_return(:baz)
^^^ Prefer `allow` over `should` when configuring a response.
RUBY
end

it 'flags `should_not`', skip: 'Not implemented yet' do
expect_offense(<<~RUBY)
foo.should_not receive(:bar)
^^^^^^^^^^ Prefer `allow(...).not_to receive` over `should_not` when configuring a response.
RUBY
end
end

0 comments on commit e6bbc1d

Please sign in to comment.