From 575c5836cbe8ce5db1a9539faad13c8ec467a50d Mon Sep 17 00:00:00 2001 From: Maxim Krizhanovski Date: Mon, 11 Jan 2021 00:05:18 +0200 Subject: [PATCH] Imrpove performance by limitting on_send calls --- CHANGELOG.md | 1 + lib/rubocop/cop/rspec/any_instance.rb | 16 ++++++---------- lib/rubocop/cop/rspec/be_eql.rb | 1 + lib/rubocop/cop/rspec/before_after_all.rb | 2 ++ .../rspec/capybara/current_path_expectation.rb | 2 ++ .../cop/rspec/capybara/visibility_matcher.rb | 2 ++ lib/rubocop/cop/rspec/describe_symbol.rb | 1 + .../cop/rspec/factory_bot/factory_class_name.rb | 1 + .../cop/rspec/implicit_block_expectation.rb | 1 + lib/rubocop/cop/rspec/implicit_subject.rb | 1 + lib/rubocop/cop/rspec/it_behaves_like.rb | 1 + lib/rubocop/cop/rspec/message_chain.rb | 14 ++++---------- lib/rubocop/cop/rspec/not_to_not.rb | 1 + lib/rubocop/cop/rspec/rails/http_status.rb | 1 + lib/rubocop/cop/rspec/receive_never.rb | 1 + lib/rubocop/cop/rspec/return_from_stub.rb | 1 + .../cop/rspec/single_argument_message_chain.rb | 1 + lib/rubocop/cop/rspec/unspecified_exception.rb | 1 + lib/rubocop/cop/rspec/verified_doubles.rb | 1 + lib/rubocop/cop/rspec/void_expect.rb | 1 + 20 files changed, 31 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b80c8cbe..d61b76753 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Master (Unreleased) * Fix `HooksBeforeExamples`, `LeadingSubject`, `LetBeforeExamples` and `ScatteredLet` autocorrection to take into account inline comments and comments immediately before the moved node. ([@Darhazer][]) +* Improve rubocop-rspec performance. ([@Darhazer][]) ## 2.1.0 (2020-12-17) diff --git a/lib/rubocop/cop/rspec/any_instance.rb b/lib/rubocop/cop/rspec/any_instance.rb index b622224ce..282b0b711 100644 --- a/lib/rubocop/cop/rspec/any_instance.rb +++ b/lib/rubocop/cop/rspec/any_instance.rb @@ -24,18 +24,14 @@ module RSpec # end class AnyInstance < Base MSG = 'Avoid stubbing using `%s`.' - - def_node_matcher :disallowed_stub, <<-PATTERN - (send _ ${:any_instance :allow_any_instance_of :expect_any_instance_of} ...) - PATTERN + RESTRICT_ON_SEND = %i[ + any_instance + allow_any_instance_of + expect_any_instance_of + ].freeze def on_send(node) - disallowed_stub(node) do |method| - add_offense( - node, - message: format(MSG, method: method) - ) - end + add_offense(node, message: format(MSG, method: node.method_name)) end end end diff --git a/lib/rubocop/cop/rspec/be_eql.rb b/lib/rubocop/cop/rspec/be_eql.rb index fbecd4fbb..4f3eafb53 100644 --- a/lib/rubocop/cop/rspec/be_eql.rb +++ b/lib/rubocop/cop/rspec/be_eql.rb @@ -39,6 +39,7 @@ class BeEql < Base extend AutoCorrector MSG = 'Prefer `be` over `eql`.' + RESTRICT_ON_SEND = %i[to].freeze def_node_matcher :eql_type_with_identity, <<-PATTERN (send _ :to $(send nil? :eql {true false int float sym nil_type?})) diff --git a/lib/rubocop/cop/rspec/before_after_all.rb b/lib/rubocop/cop/rspec/before_after_all.rb index 7813b3d9d..8677a3b55 100644 --- a/lib/rubocop/cop/rspec/before_after_all.rb +++ b/lib/rubocop/cop/rspec/before_after_all.rb @@ -29,6 +29,8 @@ class BeforeAfterAll < Base '`use_transactional_fixtures` is enabled, then records created ' \ 'in `%s` are not automatically rolled back.' + RESTRICT_ON_SEND = %i[before after].freeze + def_node_matcher :before_or_after_all, <<-PATTERN $(send _ {:before :after} (sym {:all :context})) PATTERN diff --git a/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb b/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb index 5d692843b..6e9d32338 100644 --- a/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb +++ b/lib/rubocop/cop/rspec/capybara/current_path_expectation.rb @@ -30,6 +30,8 @@ class CurrentPathExpectation < Base 'Capybara feature specs - instead, use the ' \ '`have_current_path` matcher on `page`' + RESTRICT_ON_SEND = %i[expect].freeze + def_node_matcher :expectation_set_on_current_path, <<-PATTERN (send nil? :expect (send {(send nil? :page) nil?} :current_path)) PATTERN diff --git a/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb b/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb index 49d267c9a..4d2037398 100644 --- a/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb +++ b/lib/rubocop/cop/rspec/capybara/visibility_matcher.rb @@ -44,6 +44,8 @@ class VisibilityMatcher < Base have_content ].freeze + RESTRICT_ON_SEND = CAPYBARA_MATCHER_METHODS + def_node_matcher :visible_true?, <<~PATTERN (send nil? #capybara_matcher? ... (hash <$(pair (sym :visible) true) ...>)) PATTERN diff --git a/lib/rubocop/cop/rspec/describe_symbol.rb b/lib/rubocop/cop/rspec/describe_symbol.rb index bf8c9ac25..b60fb1a0c 100644 --- a/lib/rubocop/cop/rspec/describe_symbol.rb +++ b/lib/rubocop/cop/rspec/describe_symbol.rb @@ -19,6 +19,7 @@ module RSpec # @see https://github.com/rspec/rspec-core/issues/1610 class DescribeSymbol < Base MSG = 'Avoid describing symbols.' + RESTRICT_ON_SEND = %i[describe].freeze def_node_matcher :describe_symbol?, <<-PATTERN (send #rspec? :describe $sym ...) diff --git a/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb b/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb index fb4081218..23ae35e13 100644 --- a/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb +++ b/lib/rubocop/cop/rspec/factory_bot/factory_class_name.rb @@ -25,6 +25,7 @@ class FactoryClassName < Base MSG = "Pass '%s' string instead of `%s` " \ 'constant.' ALLOWED_CONSTANTS = %w[Hash OpenStruct].freeze + RESTRICT_ON_SEND = %i[factory].freeze def_node_matcher :class_name, <<~PATTERN (send _ :factory _ (hash <(pair (sym :class) $(const ...)) ...>)) diff --git a/lib/rubocop/cop/rspec/implicit_block_expectation.rb b/lib/rubocop/cop/rspec/implicit_block_expectation.rb index 16f2ea333..8bda1ed45 100644 --- a/lib/rubocop/cop/rspec/implicit_block_expectation.rb +++ b/lib/rubocop/cop/rspec/implicit_block_expectation.rb @@ -18,6 +18,7 @@ module RSpec # end class ImplicitBlockExpectation < Base MSG = 'Avoid implicit block expectations.' + RESTRICT_ON_SEND = %i[is_expected should should_not].freeze def_node_matcher :lambda?, <<-PATTERN { diff --git a/lib/rubocop/cop/rspec/implicit_subject.rb b/lib/rubocop/cop/rspec/implicit_subject.rb index ec5c184cc..7b5d79410 100644 --- a/lib/rubocop/cop/rspec/implicit_subject.rb +++ b/lib/rubocop/cop/rspec/implicit_subject.rb @@ -31,6 +31,7 @@ class ImplicitSubject < Base include ConfigurableEnforcedStyle MSG = "Don't use implicit subject." + RESTRICT_ON_SEND = %i[is_expected should should_not].freeze def_node_matcher :implicit_subject?, <<-PATTERN (send nil? {:should :should_not :is_expected} ...) diff --git a/lib/rubocop/cop/rspec/it_behaves_like.rb b/lib/rubocop/cop/rspec/it_behaves_like.rb index ceca22406..0fa15ec92 100644 --- a/lib/rubocop/cop/rspec/it_behaves_like.rb +++ b/lib/rubocop/cop/rspec/it_behaves_like.rb @@ -24,6 +24,7 @@ class ItBehavesLike < Base MSG = 'Prefer `%s` over `%s` when including ' \ 'examples in a nested context.' + RESTRICT_ON_SEND = %i[it_behaves_like it_should_behave_like].freeze def_node_matcher :example_inclusion_offense, '(send _ % ...)' diff --git a/lib/rubocop/cop/rspec/message_chain.rb b/lib/rubocop/cop/rspec/message_chain.rb index 561efc374..fc3593cad 100644 --- a/lib/rubocop/cop/rspec/message_chain.rb +++ b/lib/rubocop/cop/rspec/message_chain.rb @@ -15,18 +15,12 @@ module RSpec # class MessageChain < Base MSG = 'Avoid stubbing using `%s`.' - - def_node_matcher :message_chain, <<-PATTERN - (send _ {:receive_message_chain :stub_chain} ...) - PATTERN + RESTRICT_ON_SEND = %i[receive_message_chain stub_chain].freeze def on_send(node) - message_chain(node) do - add_offense( - node.loc.selector, - message: format(MSG, method: node.method_name) - ) - end + add_offense( + node.loc.selector, message: format(MSG, method: node.method_name) + ) end end end diff --git a/lib/rubocop/cop/rspec/not_to_not.rb b/lib/rubocop/cop/rspec/not_to_not.rb index f47e69fa8..2fb4fa515 100644 --- a/lib/rubocop/cop/rspec/not_to_not.rb +++ b/lib/rubocop/cop/rspec/not_to_not.rb @@ -20,6 +20,7 @@ class NotToNot < Base include ConfigurableEnforcedStyle MSG = 'Prefer `%s` over `%s`.' + RESTRICT_ON_SEND = %i[not_to to_not].freeze def_node_matcher :not_to_not_offense, '(send _ % ...)' diff --git a/lib/rubocop/cop/rspec/rails/http_status.rb b/lib/rubocop/cop/rspec/rails/http_status.rb index 8dc27c217..1ecbde0dd 100644 --- a/lib/rubocop/cop/rspec/rails/http_status.rb +++ b/lib/rubocop/cop/rspec/rails/http_status.rb @@ -33,6 +33,7 @@ module Rails class HttpStatus < Base extend AutoCorrector include ConfigurableEnforcedStyle + RESTRICT_ON_SEND = %i[have_http_status].freeze def_node_matcher :http_status, <<-PATTERN (send nil? :have_http_status ${int sym}) diff --git a/lib/rubocop/cop/rspec/receive_never.rb b/lib/rubocop/cop/rspec/receive_never.rb index 840360cff..93896cc68 100644 --- a/lib/rubocop/cop/rspec/receive_never.rb +++ b/lib/rubocop/cop/rspec/receive_never.rb @@ -16,6 +16,7 @@ module RSpec class ReceiveNever < Base extend AutoCorrector MSG = 'Use `not_to receive` instead of `never`.' + RESTRICT_ON_SEND = %i[never].freeze def_node_search :method_on_stub?, '(send nil? :receive ...)' diff --git a/lib/rubocop/cop/rspec/return_from_stub.rb b/lib/rubocop/cop/rspec/return_from_stub.rb index 0cce32ed9..a46273bbb 100644 --- a/lib/rubocop/cop/rspec/return_from_stub.rb +++ b/lib/rubocop/cop/rspec/return_from_stub.rb @@ -39,6 +39,7 @@ class ReturnFromStub < Base MSG_AND_RETURN = 'Use `and_return` for static values.' MSG_BLOCK = 'Use block for static values.' + RESTRICT_ON_SEND = %i[and_return].freeze def_node_search :contains_stub?, '(send nil? :receive (...))' def_node_matcher :stub_with_block?, '(block #contains_stub? ...)' diff --git a/lib/rubocop/cop/rspec/single_argument_message_chain.rb b/lib/rubocop/cop/rspec/single_argument_message_chain.rb index 7e1903b5d..1cc7e7876 100644 --- a/lib/rubocop/cop/rspec/single_argument_message_chain.rb +++ b/lib/rubocop/cop/rspec/single_argument_message_chain.rb @@ -21,6 +21,7 @@ class SingleArgumentMessageChain < Base MSG = 'Use `%s` instead of calling ' \ '`%s` with a single argument.' + RESTRICT_ON_SEND = %i[receive_message_chain stub_chain].freeze def_node_matcher :message_chain, <<-PATTERN (send _ {:receive_message_chain :stub_chain} $_) diff --git a/lib/rubocop/cop/rspec/unspecified_exception.rb b/lib/rubocop/cop/rspec/unspecified_exception.rb index 04092f20a..be0b472f1 100644 --- a/lib/rubocop/cop/rspec/unspecified_exception.rb +++ b/lib/rubocop/cop/rspec/unspecified_exception.rb @@ -32,6 +32,7 @@ module RSpec # expect { do_something }.not_to raise_error class UnspecifiedException < Base MSG = 'Specify the exception being captured' + RESTRICT_ON_SEND = %i[to].freeze def_node_matcher :empty_raise_error_or_exception, <<-PATTERN (send diff --git a/lib/rubocop/cop/rspec/verified_doubles.rb b/lib/rubocop/cop/rspec/verified_doubles.rb index 1dc1d0494..e70baf29b 100644 --- a/lib/rubocop/cop/rspec/verified_doubles.rb +++ b/lib/rubocop/cop/rspec/verified_doubles.rb @@ -24,6 +24,7 @@ module RSpec # end class VerifiedDoubles < Base MSG = 'Prefer using verifying doubles over normal doubles.' + RESTRICT_ON_SEND = %i[double spy].freeze def_node_matcher :unverified_double, <<-PATTERN {(send nil? {:double :spy} $...)} diff --git a/lib/rubocop/cop/rspec/void_expect.rb b/lib/rubocop/cop/rspec/void_expect.rb index 0f320e54c..ed0a835c6 100644 --- a/lib/rubocop/cop/rspec/void_expect.rb +++ b/lib/rubocop/cop/rspec/void_expect.rb @@ -14,6 +14,7 @@ module RSpec class VoidExpect < Base MSG = 'Do not use `expect()` without `.to` or `.not_to`. ' \ 'Chain the methods or remove it.' + RESTRICT_ON_SEND = %i[expect].freeze def_node_matcher :expect?, <<-PATTERN (send nil? :expect ...)