Merge pull request #14908 from Homebrew/dependabot/bundler/Library/Homebrew/rubocop-rspec-2.19.0

build(deps): bump rubocop-rspec from 2.18.1 to 2.19.0 in /Library/Homebrew
This commit is contained in:
Mike McQuaid 2023-03-07 10:43:26 +00:00 committed by GitHub
commit ad0d1a719f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
156 changed files with 917 additions and 381 deletions

View File

@ -151,7 +151,7 @@ GEM
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
rubocop-rspec (2.18.1)
rubocop-rspec (2.19.0)
rubocop (~> 1.33)
rubocop-capybara (~> 2.17)
rubocop-sorbet (0.7.0)

View File

@ -212,6 +212,19 @@ module RuboCop::Cop::RSpec::CommentsHelp
def start_line_position(node); end
end
class RuboCop::Cop::RSpec::ContainExactly < ::RuboCop::Cop::RSpec::Base
extend ::RuboCop::Cop::AutoCorrector
def on_send(node); end
private
def autocorrect(node, corrector); end
end
RuboCop::Cop::RSpec::ContainExactly::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::RSpec::ContainExactly::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::RSpec::ContextMethod < ::RuboCop::Cop::RSpec::Base
extend ::RuboCop::Cop::AutoCorrector
@ -234,7 +247,8 @@ class RuboCop::Cop::RSpec::ContextWording < ::RuboCop::Cop::RSpec::Base
private
def allowed_patterns; end
def bad_pattern?(description); end
def bad_pattern?(node); end
def description(context); end
def expect_patterns; end
def prefix_regexes; end
def prefixes; end
@ -262,8 +276,13 @@ RuboCop::Cop::RSpec::DescribeClass::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::RSpec::DescribeMethod < ::RuboCop::Cop::RSpec::Base
include ::RuboCop::Cop::RSpec::TopLevelGroup
def method_name?(param0 = T.unsafe(nil)); end
def on_top_level_group(node); end
def second_argument(param0 = T.unsafe(nil)); end
def second_string_literal_argument(param0 = T.unsafe(nil)); end
private
def method_name_prefix?(description); end
end
RuboCop::Cop::RSpec::DescribeMethod::MSG = T.let(T.unsafe(nil), String)
@ -823,7 +842,7 @@ class RuboCop::Cop::RSpec::HookArgument < ::RuboCop::Cop::RSpec::Base
private
def argument_range(send_node); end
def autocorrect(corrector, _node, method_send); end
def check_implicit(method_send); end
def explicit_message(scope); end
def hook(node, &block); end
@ -1073,6 +1092,27 @@ end
RuboCop::Cop::RSpec::LetSetup::MSG = T.let(T.unsafe(nil), String)
module RuboCop::Cop::RSpec::LocationHelp
private
def arguments_with_whitespace(node); end
def block_with_whitespace(node); end
class << self
def arguments_with_whitespace(node); end
def block_with_whitespace(node); end
end
end
class RuboCop::Cop::RSpec::MatchArray < ::RuboCop::Cop::RSpec::Base
extend ::RuboCop::Cop::AutoCorrector
def on_send(node); end
end
RuboCop::Cop::RSpec::MatchArray::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::RSpec::MatchArray::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::RSpec::MessageChain < ::RuboCop::Cop::RSpec::Base
def on_send(node); end
end
@ -1301,18 +1341,21 @@ end
RuboCop::Cop::RSpec::Pending::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::RSpec::PendingWithoutReason < ::RuboCop::Cop::RSpec::Base
def metadata_without_reason?(param0 = T.unsafe(nil)); end
def on_send(node); end
def pending_by_example_method?(param0 = T.unsafe(nil)); end
def pending_by_metadata_without_reason?(param0 = T.unsafe(nil)); end
def pending_step_without_reason?(param0 = T.unsafe(nil)); end
def skipped_by_example_group_method?(param0 = T.unsafe(nil)); end
def skipped_by_example_method?(param0 = T.unsafe(nil)); end
def skipped_by_metadata_without_reason?(param0 = T.unsafe(nil)); end
def without_reason?(param0 = T.unsafe(nil)); end
def skipped_in_example?(param0 = T.unsafe(nil)); end
private
def pending_without_reason?(node); end
def skipped_without_reason?(node); end
def block_node_example_group?(node); end
def on_pending_by_metadata(node); end
def on_skipped_by_example_group_method(node); end
def on_skipped_by_example_method(node); end
def on_skipped_by_in_example_method(node, _direct_parent); end
def parent_node(node); end
end
RuboCop::Cop::RSpec::PendingWithoutReason::MSG = T.let(T.unsafe(nil), String)
@ -1325,11 +1368,6 @@ class RuboCop::Cop::RSpec::PredicateMatcher < ::RuboCop::Cop::RSpec::Base
def on_block(node); end
def on_send(node); end
private
def args_loc(send_node); end
def block_loc(send_node); end
end
RuboCop::Cop::RSpec::PredicateMatcher::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
@ -1438,6 +1476,23 @@ end
RuboCop::Cop::RSpec::Rails::MinitestAssertions::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::RSpec::Rails::MinitestAssertions::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::RSpec::Rails::TravelAround < ::RuboCop::Cop::RSpec::Base
extend ::RuboCop::Cop::AutoCorrector
def extract_run_in_travel(param0 = T.unsafe(nil)); end
def match_around_each?(param0 = T.unsafe(nil)); end
def on_block(node); end
def on_numblock(node); end
private
def autocorrect(corrector, node, run_node, around_node); end
def extract_surrounding_around_block(node); end
end
RuboCop::Cop::RSpec::Rails::TravelAround::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::RSpec::Rails::TravelAround::TRAVEL_METHOD_NAMES = T.let(T.unsafe(nil), Set)
class RuboCop::Cop::RSpec::ReceiveCounts < ::RuboCop::Cop::RSpec::Base
extend ::RuboCop::Cop::AutoCorrector
@ -1470,6 +1525,23 @@ end
RuboCop::Cop::RSpec::ReceiveNever::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::RSpec::ReceiveNever::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::RSpec::RedundantAround < ::RuboCop::Cop::RSpec::Base
extend ::RuboCop::Cop::AutoCorrector
def match_redundant_around_hook_block?(param0 = T.unsafe(nil)); end
def match_redundant_around_hook_send?(param0 = T.unsafe(nil)); end
def on_block(node); end
def on_numblock(node); end
def on_send(node); end
private
def autocorrect(corrector, node); end
end
RuboCop::Cop::RSpec::RedundantAround::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::RSpec::RedundantAround::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::RSpec::RepeatedDescription < ::RuboCop::Cop::RSpec::Base
def on_block(node); end
@ -1495,12 +1567,13 @@ end
RuboCop::Cop::RSpec::RepeatedExample::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::RSpec::RepeatedExampleGroupBody < ::RuboCop::Cop::RSpec::Base
include ::RuboCop::Cop::RSpec::SkipOrPending
def body(param0 = T.unsafe(nil)); end
def const_arg(param0 = T.unsafe(nil)); end
def metadata(param0 = T.unsafe(nil)); end
def on_begin(node); end
def several_example_groups?(param0 = T.unsafe(nil)); end
def skip_or_pending?(param0 = T.unsafe(nil)); end
private
@ -1513,11 +1586,12 @@ end
RuboCop::Cop::RSpec::RepeatedExampleGroupBody::MSG = T.let(T.unsafe(nil), String)
class RuboCop::Cop::RSpec::RepeatedExampleGroupDescription < ::RuboCop::Cop::RSpec::Base
include ::RuboCop::Cop::RSpec::SkipOrPending
def doc_string_and_metadata(param0 = T.unsafe(nil)); end
def empty_description?(param0 = T.unsafe(nil)); end
def on_begin(node); end
def several_example_groups?(param0 = T.unsafe(nil)); end
def skip_or_pending?(param0 = T.unsafe(nil)); end
private
@ -1680,10 +1754,21 @@ end
RuboCop::Cop::RSpec::SingleArgumentMessageChain::MSG = T.let(T.unsafe(nil), String)
RuboCop::Cop::RSpec::SingleArgumentMessageChain::RESTRICT_ON_SEND = T.let(T.unsafe(nil), Array)
class RuboCop::Cop::RSpec::SkipBlockInsideExample < ::RuboCop::Cop::RSpec::Base
def on_block(node); end
def on_numblock(node); end
private
def inside_example?(node); end
end
RuboCop::Cop::RSpec::SkipBlockInsideExample::MSG = T.let(T.unsafe(nil), String)
module RuboCop::Cop::RSpec::SkipOrPending
extend ::RuboCop::AST::NodePattern::Macros
def skip_or_pending?(param0 = T.unsafe(nil)); end
def skip_or_pending_inside_block?(param0 = T.unsafe(nil)); end
def skipped_in_metadata?(param0 = T.unsafe(nil)); end
end
@ -1794,6 +1879,7 @@ RuboCop::Cop::RSpec::Variable::Subjects = RuboCop::RSpec::Language::Subjects
class RuboCop::Cop::RSpec::VariableDefinition < ::RuboCop::Cop::RSpec::Base
include ::RuboCop::Cop::ConfigurableEnforcedStyle
include ::RuboCop::Cop::RSpec::Variable
include ::RuboCop::Cop::RSpec::InsideExampleGroup
extend ::RuboCop::Cop::AutoCorrector
def on_send(node); end
@ -1814,6 +1900,7 @@ class RuboCop::Cop::RSpec::VariableName < ::RuboCop::Cop::RSpec::Base
include ::RuboCop::Cop::ConfigurableNaming
include ::RuboCop::Cop::AllowedPattern
include ::RuboCop::Cop::RSpec::Variable
include ::RuboCop::Cop::RSpec::InsideExampleGroup
def on_send(node); end
@ -2026,6 +2113,7 @@ module RuboCop::RSpec::Language
def example?(param0 = T.unsafe(nil)); end
def example_group?(param0 = T.unsafe(nil)); end
def example_group_with_body?(param0 = T.unsafe(nil)); end
def explicit_rspec?(param0 = T.unsafe(nil)); end
def hook?(param0 = T.unsafe(nil)); end
def include?(param0 = T.unsafe(nil)); end
def let?(param0 = T.unsafe(nil)); end
@ -2100,9 +2188,14 @@ module RuboCop::RSpec::Language::Includes
end
module RuboCop::RSpec::Language::NodePattern
def block_or_numblock_pattern(string); end
def block_pattern(string); end
def numblock_pattern(string); end
def send_pattern(string); end
private
def deprecation_warning(method); end
end
module RuboCop::RSpec::Language::Runners

View File

@ -6652,6 +6652,7 @@ module RuboCop::AST::NodePattern::Sets
SET_MAC_LINUX = ::T.let(nil, ::T.untyped)
SET_ON_INTEL_ON_ARM = ::T.let(nil, ::T.untyped)
SET_OR_NEWER_OR_OLDER = ::T.let(nil, ::T.untyped)
SET_SKIP_PENDING = ::T.let(nil, ::T.untyped)
SET_SYSTEM_SHELL_OUTPUT_PIPE_OUTPUT = ::T.let(nil, ::T.untyped)
SET_WITH_WITHOUT = ::T.let(nil, ::T.untyped)
SET____ETC_4 = ::T.let(nil, ::T.untyped)

View File

@ -156,7 +156,7 @@ describe Utils::Autoremove do
specify "multiple dependents" do
expect(described_class.send(:formulae_with_cask_dependents, casks_multiple_deps))
.to match_array([formula_with_deps, formula_is_dep1, formula_is_dep2])
.to contain_exactly(formula_with_deps, formula_is_dep1, formula_is_dep2)
end
end
end

View File

@ -107,7 +107,7 @@ $:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-capybara-2.17.1/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-performance-1.16.0/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-rails-2.18.0/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-rspec-2.18.1/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-rspec-2.19.0/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/rubocop-sorbet-0.7.0/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/ruby-macho-3.0.0/lib")
$:.unshift File.expand_path("#{__dir__}/../#{RUBY_ENGINE}/#{Gem.ruby_api_version}/gems/simplecov-html-0.12.3/lib")

View File

@ -1,23 +0,0 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Helps check offenses with variable definitions
module SkipOrPending
extend RuboCop::NodePattern::Macros
# @!method skipped_in_metadata?(node)
def_node_matcher :skipped_in_metadata?, <<-PATTERN
{
(send _ _ <#skip_or_pending? ...>)
(send _ _ ... (hash <(pair #skip_or_pending? { true str dstr }) ...>))
}
PATTERN
# @!method skip_or_pending?(node)
def_node_matcher :skip_or_pending?, '{(sym :skip) (sym :pending)}'
end
end
end
end

View File

@ -1,121 +0,0 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Checks for pending or skipped examples without reason.
#
# @example
# # bad
# pending 'does something' do
# end
#
# # bad
# it 'does something', :pending do
# end
#
# # bad
# it 'does something' do
# pending
# end
#
# # bad
# xdescribe 'something' do
# end
#
# # bad
# skip 'does something' do
# end
#
# # bad
# it 'does something', :skip do
# end
#
# # bad
# it 'does something' do
# skip
# end
#
# # bad
# it 'does something'
#
# # good
# it 'does something' do
# pending 'reason'
# end
#
# # good
# it 'does something' do
# skip 'reason'
# end
#
# # good
# it 'does something', pending: 'reason' do
# end
#
# # good
# it 'does something', skip: 'reason' do
# end
class PendingWithoutReason < Base
MSG = 'Give the reason for pending or skip.'
# @!method pending_by_example_method?(node)
def_node_matcher :pending_by_example_method?, block_pattern(<<~PATTERN)
#Examples.pending
PATTERN
# @!method pending_by_metadata_without_reason?(node)
def_node_matcher :pending_by_metadata_without_reason?, <<~PATTERN
(send #rspec? {#ExampleGroups.all #Examples.all} ... {<(sym :pending) ...> (hash <(pair (sym :pending) true) ...>)})
PATTERN
# @!method skipped_by_example_method?(node)
def_node_matcher :skipped_by_example_method?, block_pattern(<<~PATTERN)
#Examples.skipped
PATTERN
# @!method skipped_by_example_group_method?(node)
def_node_matcher(
:skipped_by_example_group_method?,
block_pattern(<<~PATTERN)
#ExampleGroups.skipped
PATTERN
)
# @!method skipped_by_metadata_without_reason?(node)
def_node_matcher :skipped_by_metadata_without_reason?, <<~PATTERN
(send #rspec? {#ExampleGroups.all #Examples.all} ... {<(sym :skip) ...> (hash <(pair (sym :skip) true) ...>)})
PATTERN
# @!method without_reason?(node)
def_node_matcher :without_reason?, <<~PATTERN
(send nil? ${:pending :skip})
PATTERN
def on_send(node)
if pending_without_reason?(node)
add_offense(node, message: 'Give the reason for pending.')
elsif skipped_without_reason?(node)
add_offense(node, message: 'Give the reason for skip.')
elsif without_reason?(node) && example?(node.parent)
add_offense(node,
message: "Give the reason for #{node.method_name}.")
end
end
private
def pending_without_reason?(node)
pending_by_example_method?(node.block_node) ||
pending_by_metadata_without_reason?(node)
end
def skipped_without_reason?(node)
skipped_by_example_group_method?(node.block_node) ||
skipped_by_example_method?(node.block_node) ||
skipped_by_metadata_without_reason?(node)
end
end
end
end
end

View File

@ -1,22 +0,0 @@
# frozen_string_literal: true
module RuboCop
module RSpec
module Language
# Helper methods to detect RSpec DSL used with send and block
module NodePattern
def send_pattern(string)
"(send #rspec? #{string} ...)"
end
def block_pattern(string)
"(block #{send_pattern(string)} ...)"
end
def numblock_pattern(string)
"(numblock #{send_pattern(string)} ...)"
end
end
end
end
end

View File

@ -201,6 +201,12 @@ RSpec/ClassCheck:
- be_kind_of
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ClassCheck
RSpec/ContainExactly:
Description: Prefer `match_array` when matching array values.
Enabled: true
VersionAdded: '2.19'
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ContainExactly
RSpec/ContextMethod:
Description: "`context` should not be used for specifying methods."
Enabled: true
@ -556,6 +562,12 @@ RSpec/LetSetup:
VersionAdded: '1.7'
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/LetSetup
RSpec/MatchArray:
Description: Prefer `contain_exactly` when matching an array literal.
Enabled: true
VersionAdded: '2.19'
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MatchArray
RSpec/MessageChain:
Description: Check that chains of messages are not being stubbed.
Enabled: true
@ -706,6 +718,12 @@ RSpec/ReceiveNever:
VersionAdded: '1.28'
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/ReceiveNever
RSpec/RedundantAround:
Description: Remove redundant `around` hook.
Enabled: pending
VersionAdded: '2.19'
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RedundantAround
RSpec/RepeatedDescription:
Description: Check for repeated description strings in example groups.
Enabled: true
@ -779,6 +797,12 @@ RSpec/SingleArgumentMessageChain:
VersionChanged: '1.10'
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SingleArgumentMessageChain
RSpec/SkipBlockInsideExample:
Description: Checks for passing a block to `skip` within examples.
Enabled: pending
VersionAdded: '2.19'
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SkipBlockInsideExample
RSpec/SortMetadata:
Description: Sort RSpec metadata alphabetically.
Enabled: pending
@ -1056,3 +1080,10 @@ RSpec/Rails/MinitestAssertions:
Enabled: pending
VersionAdded: '2.17'
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/MinitestAssertions
RSpec/Rails/TravelAround:
Description: Prefer to travel in `before` rather than `around`.
Enabled: pending
Safe: false
VersionAdded: '2.19'
Reference: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Rails/TravelAround

View File

@ -20,6 +20,7 @@ require_relative 'rubocop/rspec/factory_bot/language'
require_relative 'rubocop/cop/rspec/mixin/final_end_location'
require_relative 'rubocop/cop/rspec/mixin/inside_example_group'
require_relative 'rubocop/cop/rspec/mixin/location_help'
require_relative 'rubocop/cop/rspec/mixin/metadata'
require_relative 'rubocop/cop/rspec/mixin/namespace'
require_relative 'rubocop/cop/rspec/mixin/skip_or_pending'

View File

@ -57,7 +57,7 @@ module RuboCop
return unless be_nil_matcher?(node)
add_offense(node, message: BE_MSG) do |corrector|
corrector.replace(node.loc.expression, 'be(nil)')
corrector.replace(node.source_range, 'be(nil)')
end
end
@ -65,7 +65,7 @@ module RuboCop
return unless nil_value_expectation?(node)
add_offense(node, message: BE_NIL_MSG) do |corrector|
corrector.replace(node.loc.expression, 'be_nil')
corrector.replace(node.source_range, 'be_nil')
end
end
end

View File

@ -99,7 +99,7 @@ module RuboCop
private
def check_offense(node)
expression = node.loc.expression
expression = node.source_range
if compound_expectations?(node)
add_offense(expression, message: message_compound) do |corrector|
autocorrect_compound(corrector, node)
@ -117,7 +117,7 @@ module RuboCop
def autocorrect(corrector, node)
corrector.replace(node.parent.loc.selector, 'not_to')
range = node.loc.dot.with(end_pos: node.loc.expression.end_pos)
range = node.loc.dot.with(end_pos: node.source_range.end_pos)
corrector.remove(range)
end
@ -126,7 +126,7 @@ module RuboCop
change_nodes(node) do |change_node|
corrector.replace(change_node.loc.selector, negated_matcher)
range = node.loc.dot.with(end_pos: node.loc.expression.end_pos)
range = node.loc.dot.with(end_pos: node.source_range.end_pos)
corrector.remove(range)
end
end

View File

@ -0,0 +1,45 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Prefer `match_array` when matching array values.
#
# @example
# # bad
# it { is_expected.to contain_exactly(*array1, *array2) }
#
# # good
# it { is_expected.to match_array(array1 + array2) }
#
# # good
# it { is_expected.to contain_exactly(content, *array) }
class ContainExactly < Base
extend AutoCorrector
MSG = 'Prefer `match_array` when matching array values.'
RESTRICT_ON_SEND = %i[contain_exactly].freeze
def on_send(node)
return unless node.each_child_node.all?(&:splat_type?)
add_offense(node) do |corrector|
autocorrect(node, corrector)
end
end
private
def autocorrect(node, corrector)
arrays = node.arguments.map do |splat_node|
splat_node.children.first
end
corrector.replace(
node.source_range,
"match_array(#{arrays.map(&:source).join(' + ')})"
)
end
end
end
end
end

View File

@ -62,12 +62,12 @@ module RuboCop
# @!method context_wording(node)
def_node_matcher :context_wording, <<-PATTERN
(block (send #rspec? { :context :shared_context } $(str $_) ...) ...)
(block (send #rspec? { :context :shared_context } $({str dstr xstr} ...) ...) ...)
PATTERN
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
context_wording(node) do |context, description|
if bad_pattern?(description)
context_wording(node) do |context|
if bad_pattern?(context)
message = format(MSG, patterns: expect_patterns)
add_offense(context, message: message)
end
@ -84,10 +84,18 @@ module RuboCop
@prefix_regexes ||= prefixes.map { |pre| /^#{Regexp.escape(pre)}\b/ }
end
def bad_pattern?(description)
def bad_pattern?(node)
return false if allowed_patterns.empty?
!matches_allowed_pattern?(description)
!matches_allowed_pattern?(description(node))
end
def description(context)
if context.xstr_type?
context.value.value
else
context.value
end
end
def expect_patterns

View File

@ -23,20 +23,28 @@ module RuboCop
MSG = 'The second argument to describe should be the method ' \
"being tested. '#instance' or '.class'."
# @!method second_argument(node)
def_node_matcher :second_argument, <<~PATTERN
# @!method second_string_literal_argument(node)
def_node_matcher :second_string_literal_argument, <<~PATTERN
(block
(send #rspec? :describe _first_argument $(str _) ...) ...
)
(send #rspec? :describe _first_argument ${str dstr} ...)
...)
PATTERN
# @!method method_name?(node)
def_node_matcher :method_name?, <<~PATTERN
{(str #method_name_prefix?) (dstr (str #method_name_prefix?) ...)}
PATTERN
def on_top_level_group(node)
second_argument = second_argument(node)
second_string_literal_argument(node) do |argument|
add_offense(argument) unless method_name?(argument)
end
end
return unless second_argument
return if second_argument.str_content.start_with?('#', '.')
private
add_offense(second_argument)
def method_name_prefix?(description)
description.start_with?('.', '#')
end
end
end

View File

@ -68,7 +68,8 @@ module RuboCop
PATTERN
# @!method rspec_block?(node)
def_node_matcher :rspec_block?, block_pattern('#ALL.all')
def_node_matcher :rspec_block?,
'({block numblock} (send #rspec? #ALL.all ...) ...)'
# @!method scope_changing_syntax?(node)
def_node_matcher :scope_changing_syntax?, '{def class module}'

View File

@ -23,7 +23,9 @@ module RuboCop
MSG = 'Avoid opening modules and defining specs within them.'
# @!method find_rspec_blocks(node)
def_node_search :find_rspec_blocks, block_pattern('#ExampleGroups.all')
def_node_search :find_rspec_blocks, <<~PATTERN
(block (send #explicit_rspec? #ExampleGroups.all ...) ...)
PATTERN
def on_module(node)
find_rspec_blocks(node) do

View File

@ -49,7 +49,7 @@ module RuboCop
MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
# @!method rspec_method?(node)
def_node_matcher :rspec_method?, send_pattern('#ALL.all')
def_node_matcher :rspec_method?, '(send #rspec? #ALL.all ...)'
def on_send(node)
return unless rspec_method?(node)

View File

@ -39,7 +39,7 @@ module RuboCop
corrector.remove(
range_with_surrounding_comma(
range_with_surrounding_space(
node.location.expression,
node.source_range,
side: :left
),
:left

View File

@ -53,7 +53,7 @@ module RuboCop
# @param node [RuboCop::AST::Node]
# @yield [RuboCop::AST::Node] example group body
def_node_matcher :example_group_body, <<~PATTERN
(block #{send_pattern('#ExampleGroups.all')} args $_)
(block (send #rspec? #ExampleGroups.all ...) args $_)
PATTERN
# @!method example_or_group_or_include?(node)
@ -72,10 +72,10 @@ module RuboCop
# @return [Array<RuboCop::AST::Node>] matching nodes
def_node_matcher :example_or_group_or_include?, <<~PATTERN
{
#{block_pattern(
'{#Examples.all #ExampleGroups.all #Includes.all}'
)}
#{send_pattern('{#Examples.all #Includes.all}')}
(block
(send #rspec? {#Examples.all #ExampleGroups.all #Includes.all} ...)
...)
(send nil? {#Examples.all #Includes.all} ...)
}
PATTERN
@ -95,7 +95,7 @@ module RuboCop
# @param node [RuboCop::AST::Node]
# @return [Array<RuboCop::AST::Node>] matching nodes
def_node_matcher :examples_inside_block?, <<~PATTERN
(block !#{send_pattern('#Hooks.all')} _ #examples?)
(block !(send nil? #Hooks.all ...) _ #examples?)
PATTERN
# @!method examples_directly_or_in_block?(node)
@ -174,7 +174,7 @@ module RuboCop
def removed_range(node)
range_by_whole_lines(
node.location.expression,
node.source_range,
include_final_newline: true
)
end

View File

@ -31,14 +31,14 @@ module RuboCop
# @!method empty_hook?(node)
def_node_matcher :empty_hook?, <<~PATTERN
(block $#{send_pattern('#Hooks.all')} _ nil?)
(block $(send nil? #Hooks.all ...) _ nil?)
PATTERN
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
empty_hook?(node) do |hook|
add_offense(hook) do |corrector|
corrector.remove(
range_with_surrounding_space(node.loc.expression, side: :left)
range_with_surrounding_space(node.source_range, side: :left)
)
end
end

View File

@ -88,7 +88,7 @@ module RuboCop
end
def docstring(node)
expr = node.loc.expression
expr = node.source_range
Parser::Source::Range.new(
expr.source_buffer,

View File

@ -74,7 +74,7 @@ module RuboCop
end
def docstring(node)
expr = node.loc.expression
expr = node.source_range
Parser::Source::Range.new(
expr.source_buffer,

View File

@ -25,7 +25,7 @@ module RuboCop
MSG = 'Do not use `%<expect>s` in `%<hook>s` hook'
# @!method expectation(node)
def_node_search :expectation, send_pattern('#Expectations.all')
def_node_search :expectation, '(send nil? #Expectations.all ...)'
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
return unless hook?(node)

View File

@ -96,7 +96,7 @@ module RuboCop
left_braces, right_braces = braces(node)
argument = node.first_argument
expression = argument.location.expression
expression = argument.source_range
corrector.insert_before(expression, left_braces)
corrector.insert_after(expression, right_braces)
end

View File

@ -71,14 +71,14 @@ module RuboCop
def crime_scene(node)
range_between(
node.loc.expression.begin_pos,
node.source_range.begin_pos,
node.loc.selector.end_pos
)
end
def offense(node)
range_between(
node.loc.expression.begin_pos,
node.source_range.begin_pos,
node.loc.selector.begin_pos
)
end

View File

@ -165,7 +165,7 @@ module RuboCop
end
def expanded_file_path
File.expand_path(processed_source.buffer.name)
File.expand_path(processed_source.file_path)
end
end
end

View File

@ -61,10 +61,9 @@ module RuboCop
PATTERN
# @!method focused_block?(node)
def_node_matcher :focused_block?,
send_pattern(<<~PATTERN)
{#ExampleGroups.focused #Examples.focused}
PATTERN
def_node_matcher :focused_block?, <<~PATTERN
(send #rspec? {#ExampleGroups.focused #Examples.focused} ...)
PATTERN
def on_send(node)
focus_metadata(node) do |focus|
@ -88,7 +87,7 @@ module RuboCop
def with_surrounding(focus)
range_with_space =
range_with_surrounding_space(focus.loc.expression, side: :left)
range_with_surrounding_space(focus.source_range, side: :left)
range_with_surrounding_comma(range_with_space, :left)
end

View File

@ -83,8 +83,7 @@ module RuboCop
style_detected(scope_name)
msg = explicit_message(scope_name)
add_offense(method_send, message: msg) do |corrector|
scope = implicit_style? ? '' : "(#{style.inspect})"
corrector.replace(argument_range(method_send), scope)
autocorrect(corrector, node, method_send)
end
end
end
@ -93,6 +92,13 @@ module RuboCop
private
def autocorrect(corrector, _node, method_send)
scope = implicit_style? ? '' : "(#{style.inspect})"
corrector.replace(
LocationHelp.arguments_with_whitespace(method_send), scope
)
end
def check_implicit(method_send)
style_detected(:implicit)
return if implicit_style?
@ -100,7 +106,10 @@ module RuboCop
msg = explicit_message(nil)
add_offense(method_send.loc.selector, message: msg) do |corrector|
scope = "(#{style.inspect})"
corrector.replace(argument_range(method_send), scope)
corrector.replace(
LocationHelp.arguments_with_whitespace(method_send),
scope
)
end
end
@ -119,12 +128,6 @@ module RuboCop
def hook(node, &block)
scoped_hook(node, &block) || unscoped_hook(node, &block)
end
def argument_range(send_node)
send_node.loc.selector.end.with(
end_pos: send_node.loc.expression.end_pos
)
end
end
end
end

View File

@ -30,9 +30,11 @@ module RuboCop
# @!method example_or_group?(node)
def_node_matcher :example_or_group?, <<-PATTERN
{
#{block_pattern('{#ExampleGroups.all #Examples.all}')}
#{numblock_pattern('{#ExampleGroups.all #Examples.all}')}
#{send_pattern('#Includes.examples')}
({block numblock} {
(send #rspec? #ExampleGroups.all ...)
(send nil? #Examples.all ...)
} ...)
(send nil? #Includes.examples ...)
}
PATTERN

View File

@ -38,16 +38,16 @@ module RuboCop
# @!method example_or_group?(node)
def_node_matcher :example_or_group?, <<-PATTERN
{
#{block_pattern('{#ExampleGroups.all #Examples.all}')}
#{send_pattern('#Includes.examples')}
(block (send nil? {#ExampleGroups.all #Examples.all} ...) ...)
(send nil? #Includes.examples ...)
}
PATTERN
# @!method include_examples?(node)
def_node_matcher :include_examples?, <<~PATTERN
{
#{block_pattern(':include_examples')}
#{send_pattern(':include_examples')}
(block (send nil? :include_examples ...) ...)
(send nil? :include_examples ...)
}
PATTERN

View File

@ -29,14 +29,12 @@ module RuboCop
MSG = 'Do not use `let!` to setup objects not referenced in tests.'
# @!method example_or_shared_group_or_including?(node)
def_node_matcher :example_or_shared_group_or_including?,
block_pattern(<<~PATTERN)
{
#SharedGroups.all
#ExampleGroups.all
#Includes.all
}
PATTERN
def_node_matcher :example_or_shared_group_or_including?, <<~PATTERN
(block {
(send #rspec? {#SharedGroups.all #ExampleGroups.all} ...)
(send nil? #Includes.all ...)
} ...)
PATTERN
# @!method let_bang(node)
def_node_matcher :let_bang, <<-PATTERN

View File

@ -0,0 +1,41 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Prefer `contain_exactly` when matching an array literal.
#
# @example
# # bad
# it { is_expected.to match_array([content1, content2]) }
#
# # good
# it { is_expected.to contain_exactly(content1, content2) }
#
# # good
# it { is_expected.to match_array([content] + array) }
#
# # good
# it { is_expected.to match_array(%w(tremble in fear foolish mortals)) }
class MatchArray < Base
extend AutoCorrector
MSG = 'Prefer `contain_exactly` when matching an array literal.'
RESTRICT_ON_SEND = %i[match_array].freeze
def on_send(node)
return unless node.first_argument.array_type?
return if node.first_argument.percent_literal?
add_offense(node) do |corrector|
array_contents = node.arguments.flat_map(&:to_a)
corrector.replace(
node.source_range,
"contain_exactly(#{array_contents.map(&:source).join(', ')})"
)
end
end
end
end
end
end

View File

@ -25,8 +25,7 @@ module RuboCop
def missing_separating_line(node)
line = final_end_line = final_end_location(node).line
while comment_line?(processed_source[line])
while processed_source.line_with_comment?(line + 1)
line += 1
comment = processed_source.comment_at_line(line)
if DirectiveComment.new(comment).enabled?

View File

@ -0,0 +1,37 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Helper methods to location.
module LocationHelp
module_function
# @param node [RuboCop::AST::SendNode]
# @return [Parser::Source::Range]
# @example
# foo 1, 2
# ^^^^^
def arguments_with_whitespace(node)
node.loc.selector.end.with(
end_pos: node.source_range.end_pos
)
end
# @param node [RuboCop::AST::SendNode]
# @return [Parser::Source::Range]
# @example
# foo { bar }
# ^^^^^^^^
def block_with_whitespace(node)
return unless (parent = node.parent)
return unless parent.block_type?
node.source_range.end.with(
end_pos: parent.source_range.end_pos
)
end
end
end
end
end

View File

@ -0,0 +1,39 @@
# frozen_string_literal: true
module RuboCop
module Cop
module RSpec
# Helps check offenses with variable definitions
module SkipOrPending
extend RuboCop::NodePattern::Macros
# @!method skipped_in_metadata?(node)
def_node_matcher :skipped_in_metadata?, <<-PATTERN
{
(send _ _ <(sym {:skip :pending}) ...>)
(send _ _ ... (hash <(pair (sym {:skip :pending}) { true str dstr }) ...>))
}
PATTERN
# @!method skip_or_pending_inside_block?(node)
# Match skip/pending statements inside a block (e.g. `context`)
#
# @example source that matches
# context 'when color is blue' do
# skip 'not implemented yet'
# pending 'not implemented yet'
# end
#
# @example source that does not match
# skip 'not implemented yet'
# pending 'not implemented yet'
#
# @param node [RuboCop::AST::Node]
# @return [Array<RuboCop::AST::Node>] matching nodes
def_node_matcher :skip_or_pending_inside_block?, <<-PATTERN
(block <(send nil? {:skip :pending} ...) ...>)
PATTERN
end
end
end
end

View File

@ -78,7 +78,8 @@ module RuboCop
PATTERN
# @!method expect?(node)
def_node_matcher :expect?, send_pattern('#Expectations.all')
def_node_matcher :expect?, '(send nil? #Expectations.all ...)'
# @!method aggregate_failures_block?(node)
def_node_matcher :aggregate_failures_block?, <<-PATTERN
(block (send nil? :aggregate_failures ...) ...)

View File

@ -82,12 +82,14 @@ module RuboCop
MSG = 'Name your test subject if you need to reference it explicitly.'
# @!method example_or_hook_block?(node)
def_node_matcher :example_or_hook_block?,
block_pattern('{#Examples.all #Hooks.all}')
def_node_matcher :example_or_hook_block?, <<~PATTERN
(block (send nil? {#Examples.all #Hooks.all} ...) ...)
PATTERN
# @!method shared_example?(node)
def_node_matcher :shared_example?,
block_pattern('#SharedGroups.examples')
def_node_matcher :shared_example?, <<~PATTERN
(block (send #rspec? #SharedGroups.examples ...) ...)
PATTERN
# @!method subject_usage(node)
def_node_search :subject_usage, '$(send nil? :subject)'

View File

@ -65,10 +65,7 @@ module RuboCop
# @param [RuboCop::AST::Node] node
# @return [Boolean]
def_node_matcher :regular_or_focused_example?, <<~PATTERN
{
#{block_pattern('{#Examples.regular | #Examples.focused}')}
#{numblock_pattern('{#Examples.regular | #Examples.focused}')}
}
({block numblock} (send nil? {#Examples.regular #Examples.focused} ...) ...)
PATTERN
# @!method includes_expectation?(node)
@ -76,7 +73,7 @@ module RuboCop
# @return [Boolean]
def_node_search :includes_expectation?, <<~PATTERN
{
#{send_pattern('#Expectations.all')}
(send nil? #Expectations.all ...)
(send nil? `#matches_allowed_pattern? ...)
}
PATTERN

Some files were not shown because too many files have changed in this diff Show More