Merge pull request #8963 from Homebrew/dependabot/bundler/Library/Homebrew/rubocop-rspec-1.44.1
build(deps): bump rubocop-rspec from 1.43.2 to 1.44.1 in /Library/Homebrew
This commit is contained in:
commit
fcda3d1cfa
@ -23,6 +23,8 @@ RSpec/RepeatedDescription:
|
|||||||
Enabled: false
|
Enabled: false
|
||||||
RSpec/RepeatedExampleGroupDescription:
|
RSpec/RepeatedExampleGroupDescription:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
RSpec/StubbedMock:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# TODO: try to reduce these
|
# TODO: try to reduce these
|
||||||
RSpec/ExampleLength:
|
RSpec/ExampleLength:
|
||||||
|
|||||||
@ -112,8 +112,9 @@ GEM
|
|||||||
rubocop-performance (1.8.1)
|
rubocop-performance (1.8.1)
|
||||||
rubocop (>= 0.87.0)
|
rubocop (>= 0.87.0)
|
||||||
rubocop-ast (>= 0.4.0)
|
rubocop-ast (>= 0.4.0)
|
||||||
rubocop-rspec (1.43.2)
|
rubocop-rspec (1.44.1)
|
||||||
rubocop (~> 0.87)
|
rubocop (~> 0.87)
|
||||||
|
rubocop-ast (>= 0.7.1)
|
||||||
rubocop-sorbet (0.5.1)
|
rubocop-sorbet (0.5.1)
|
||||||
rubocop
|
rubocop
|
||||||
ruby-macho (2.2.0)
|
ruby-macho (2.2.0)
|
||||||
|
|||||||
16
Library/Homebrew/vendor/bundle/bundler/setup.rb
vendored
16
Library/Homebrew/vendor/bundle/bundler/setup.rb
vendored
@ -20,7 +20,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/json-2.3.1/lib"
|
|||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/docile-1.3.2/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/docile-1.3.2/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-html-0.12.3/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-html-0.12.3/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-0.19.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/simplecov-0.19.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/codecov-0.2.11/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/codecov-0.2.12/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/coderay-1.1.3/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/coderay-1.1.3/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/colorize-0.8.1/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/colorize-0.8.1/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/highline-2.0.3/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/highline-2.0.3/lib"
|
||||||
@ -51,14 +51,14 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel-1.19.2/lib"
|
|||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel_tests-3.3.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parallel_tests-3.3.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parser-2.7.2.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parser-2.7.2.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rainbow-3.0.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rainbow-3.0.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-0.5.5942/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-0.5.5973/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parlour-4.0.1/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/parlour-4.0.1/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/patchelf-1.3.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/patchelf-1.3.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/plist-3.5.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/plist-3.5.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/pry-0.13.1/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/pry-0.13.1/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-19/2.6.0/rdiscount-2.2.0.2"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/universal-darwin-19/2.6.0/rdiscount-2.2.0.2"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rdiscount-2.2.0.2/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rdiscount-2.2.0.2/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/regexp_parser-1.8.1/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/regexp_parser-1.8.2/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rexml-3.2.4/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rexml-3.2.4/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ronn-0.7.3/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ronn-0.7.3/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-support-3.9.3/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-support-3.9.3/lib"
|
||||||
@ -69,16 +69,16 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-3.9.0/lib"
|
|||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-its-1.3.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-its-1.3.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-retry-0.6.2/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-retry-0.6.2/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-wait-0.0.9/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec-wait-0.0.9/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-0.7.1/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-0.8.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.10.1/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.10.1/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-1.7.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-1.7.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.92.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.93.1/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1.8.1/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1.8.1/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.43.2/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.44.1/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-sorbet-0.5.1/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-sorbet-0.5.1/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.2.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.2.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-static-0.5.5942-universal-darwin-19/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-static-0.5.5949-universal-darwin-19/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-0.5.5942/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-0.5.5949/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-stub-0.2.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/sorbet-runtime-stub-0.2.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thor-1.0.1/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thor-1.0.1/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/spoom-1.0.4/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/spoom-1.0.4/lib"
|
||||||
|
|||||||
@ -76,7 +76,23 @@ RSpec/ContextWording:
|
|||||||
RSpec/DescribeClass:
|
RSpec/DescribeClass:
|
||||||
Description: Check that the first argument to the top-level describe is a constant.
|
Description: Check that the first argument to the top-level describe is a constant.
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
IgnoredMetadata:
|
||||||
|
type:
|
||||||
|
- channel
|
||||||
|
- controller
|
||||||
|
- helper
|
||||||
|
- job
|
||||||
|
- mailer
|
||||||
|
- model
|
||||||
|
- request
|
||||||
|
- routing
|
||||||
|
- view
|
||||||
|
- feature
|
||||||
|
- system
|
||||||
|
- mailbox
|
||||||
|
- aruba
|
||||||
VersionAdded: '1.0'
|
VersionAdded: '1.0'
|
||||||
|
VersionChanged: '1.44'
|
||||||
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeClass
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeClass
|
||||||
|
|
||||||
RSpec/DescribeMethod:
|
RSpec/DescribeMethod:
|
||||||
@ -494,6 +510,12 @@ RSpec/RepeatedExampleGroupDescription:
|
|||||||
VersionAdded: '1.38'
|
VersionAdded: '1.38'
|
||||||
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedExampleGroupDescription
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedExampleGroupDescription
|
||||||
|
|
||||||
|
RSpec/RepeatedIncludeExample:
|
||||||
|
Description: Check for repeated include of shared examples.
|
||||||
|
Enabled: true
|
||||||
|
VersionAdded: '1.44'
|
||||||
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/RepeatedIncludeExample
|
||||||
|
|
||||||
RSpec/ReturnFromStub:
|
RSpec/ReturnFromStub:
|
||||||
Description: Checks for consistent style of stub's return setting.
|
Description: Checks for consistent style of stub's return setting.
|
||||||
Enabled: true
|
Enabled: true
|
||||||
@ -537,6 +559,12 @@ RSpec/SingleArgumentMessageChain:
|
|||||||
VersionChanged: '1.10'
|
VersionChanged: '1.10'
|
||||||
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SingleArgumentMessageChain
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/SingleArgumentMessageChain
|
||||||
|
|
||||||
|
RSpec/StubbedMock:
|
||||||
|
Description: Checks that message expectations do not have a configured response.
|
||||||
|
Enabled: pending
|
||||||
|
VersionAdded: '1.44'
|
||||||
|
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/StubbedMock
|
||||||
|
|
||||||
RSpec/SubjectStub:
|
RSpec/SubjectStub:
|
||||||
Description: Checks for stubbed test subjects.
|
Description: Checks for stubbed test subjects.
|
||||||
Enabled: true
|
Enabled: true
|
||||||
@ -31,7 +31,7 @@ module RuboCop
|
|||||||
'or `%<arg>s.run`.'
|
'or `%<arg>s.run`.'
|
||||||
|
|
||||||
def_node_matcher :hook, <<-PATTERN
|
def_node_matcher :hook, <<-PATTERN
|
||||||
(block {(send nil? :around) (send nil? :around sym)} (args $...) ...)
|
(block (send nil? :around sym ?) (args $...) ...)
|
||||||
PATTERN
|
PATTERN
|
||||||
|
|
||||||
def_node_search :find_arg_usage, <<-PATTERN
|
def_node_search :find_arg_usage, <<-PATTERN
|
||||||
@ -29,6 +29,8 @@ module RuboCop
|
|||||||
.map(&Regexp.public_method(:new))
|
.map(&Regexp.public_method(:new))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
exclude_from_registry
|
||||||
|
|
||||||
# Invoke the original inherited hook so our cops are recognized
|
# Invoke the original inherited hook so our cops are recognized
|
||||||
def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
|
def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
|
||||||
RuboCop::Cop::Base.inherited(subclass)
|
RuboCop::Cop::Base.inherited(subclass)
|
||||||
@ -5,6 +5,19 @@ module RuboCop
|
|||||||
module RSpec
|
module RSpec
|
||||||
# Check that the first argument to the top-level describe is a constant.
|
# Check that the first argument to the top-level describe is a constant.
|
||||||
#
|
#
|
||||||
|
# It can be configured to ignore strings when certain metadata is passed.
|
||||||
|
#
|
||||||
|
# Ignores Rails and Aruba `type` metadata by default.
|
||||||
|
#
|
||||||
|
# @example `IgnoredMetadata` configuration
|
||||||
|
#
|
||||||
|
# # .rubocop.yml
|
||||||
|
# # RSpec/DescribeClass:
|
||||||
|
# # IgnoredMetadata:
|
||||||
|
# # type:
|
||||||
|
# # - request
|
||||||
|
# # - controller
|
||||||
|
#
|
||||||
# @example
|
# @example
|
||||||
# # bad
|
# # bad
|
||||||
# describe 'Do something' do
|
# describe 'Do something' do
|
||||||
@ -27,36 +40,42 @@ module RuboCop
|
|||||||
MSG = 'The first argument to describe should be '\
|
MSG = 'The first argument to describe should be '\
|
||||||
'the class or module being tested.'
|
'the class or module being tested.'
|
||||||
|
|
||||||
def_node_matcher :rails_metadata?, <<-PATTERN
|
def_node_matcher :example_group_with_ignored_metadata?, <<~PATTERN
|
||||||
(pair
|
(send #rspec? :describe ... (hash <#ignored_metadata? ...>))
|
||||||
(sym :type)
|
|
||||||
(sym { :channel :controller :helper :job :mailer :model :request
|
|
||||||
:routing :view :feature :system :mailbox })
|
|
||||||
)
|
|
||||||
PATTERN
|
|
||||||
|
|
||||||
def_node_matcher :example_group_with_rails_metadata?, <<~PATTERN
|
|
||||||
(send #rspec? :describe ... (hash <#rails_metadata? ...>))
|
|
||||||
PATTERN
|
PATTERN
|
||||||
|
|
||||||
def_node_matcher :not_a_const_described, <<~PATTERN
|
def_node_matcher :not_a_const_described, <<~PATTERN
|
||||||
(send #rspec? :describe $[!const !#string_constant?] ...)
|
(send #rspec? :describe $[!const !#string_constant?] ...)
|
||||||
PATTERN
|
PATTERN
|
||||||
|
|
||||||
def on_top_level_group(top_level_node)
|
def_node_matcher :sym_pair, <<~PATTERN
|
||||||
return if example_group_with_rails_metadata?(top_level_node.send_node)
|
(pair $sym $sym)
|
||||||
|
PATTERN
|
||||||
|
|
||||||
not_a_const_described(top_level_node.send_node) do |described|
|
def on_top_level_group(node)
|
||||||
|
return if example_group_with_ignored_metadata?(node.send_node)
|
||||||
|
|
||||||
|
not_a_const_described(node.send_node) do |described|
|
||||||
add_offense(described)
|
add_offense(described)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def ignored_metadata?(node)
|
||||||
|
sym_pair(node) do |key, value|
|
||||||
|
ignored_metadata[key.value.to_s].to_a.include?(value.value.to_s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def string_constant?(described)
|
def string_constant?(described)
|
||||||
described.str_type? &&
|
described.str_type? &&
|
||||||
described.value.match?(/^(?:(?:::)?[A-Z]\w*)+$/)
|
described.value.match?(/^(?:(?:::)?[A-Z]\w*)+$/)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ignored_metadata
|
||||||
|
cop_config['IgnoredMetadata'] || {}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -33,6 +33,11 @@ module RuboCop
|
|||||||
# end
|
# end
|
||||||
# end
|
# end
|
||||||
#
|
#
|
||||||
|
# # good
|
||||||
|
# describe Bacon do
|
||||||
|
# pending 'will add tests later'
|
||||||
|
# end
|
||||||
|
#
|
||||||
# @example configuration
|
# @example configuration
|
||||||
#
|
#
|
||||||
# # .rubocop.yml
|
# # .rubocop.yml
|
||||||
@ -83,11 +88,14 @@ module RuboCop
|
|||||||
# it_behaves_like 'an animal'
|
# it_behaves_like 'an animal'
|
||||||
# it_behaves_like('a cat') { let(:food) { 'milk' } }
|
# it_behaves_like('a cat') { let(:food) { 'milk' } }
|
||||||
# it_has_root_access
|
# it_has_root_access
|
||||||
|
# skip
|
||||||
|
# it 'will be implemented later'
|
||||||
#
|
#
|
||||||
# @param node [RuboCop::AST::Node]
|
# @param node [RuboCop::AST::Node]
|
||||||
# @return [Array<RuboCop::AST::Node>] matching nodes
|
# @return [Array<RuboCop::AST::Node>] matching nodes
|
||||||
def_node_matcher :example_or_group_or_include?, <<~PATTERN
|
def_node_matcher :example_or_group_or_include?, <<~PATTERN
|
||||||
{
|
{
|
||||||
|
#{Examples::ALL.send_pattern}
|
||||||
#{Examples::ALL.block_pattern}
|
#{Examples::ALL.block_pattern}
|
||||||
#{ExampleGroups::ALL.block_pattern}
|
#{ExampleGroups::ALL.block_pattern}
|
||||||
#{Includes::ALL.send_pattern}
|
#{Includes::ALL.send_pattern}
|
||||||
@ -152,13 +160,39 @@ module RuboCop
|
|||||||
PATTERN
|
PATTERN
|
||||||
|
|
||||||
def on_block(node)
|
def on_block(node)
|
||||||
|
return if node.each_ancestor(:def, :defs).any?
|
||||||
|
return if node.each_ancestor(:block).any? { |block| example?(block) }
|
||||||
|
|
||||||
example_group_body(node) do |body|
|
example_group_body(node) do |body|
|
||||||
add_offense(node.send_node) unless examples?(body)
|
add_offense(node.send_node) if offensive?(body)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def offensive?(body)
|
||||||
|
return true unless body
|
||||||
|
return false if conditionals_with_examples?(body)
|
||||||
|
|
||||||
|
if body.if_type?
|
||||||
|
!examples_in_branches?(body)
|
||||||
|
else
|
||||||
|
!examples?(body)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def conditionals_with_examples?(body)
|
||||||
|
return unless body.begin_type?
|
||||||
|
|
||||||
|
body.each_descendant(:if).any? do |if_node|
|
||||||
|
examples_in_branches?(if_node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def examples_in_branches?(if_node)
|
||||||
|
if_node.branches.any? { |branch| examples?(branch) }
|
||||||
|
end
|
||||||
|
|
||||||
def custom_include?(method_name)
|
def custom_include?(method_name)
|
||||||
custom_include_methods.include?(method_name)
|
custom_include_methods.include?(method_name)
|
||||||
end
|
end
|
||||||
@ -22,8 +22,7 @@ module RuboCop
|
|||||||
def_node_matcher :lambda?, <<-PATTERN
|
def_node_matcher :lambda?, <<-PATTERN
|
||||||
{
|
{
|
||||||
(send (const nil? :Proc) :new)
|
(send (const nil? :Proc) :new)
|
||||||
(send nil? :proc)
|
(send nil? {:proc :lambda})
|
||||||
(send nil? :lambda)
|
|
||||||
}
|
}
|
||||||
PATTERN
|
PATTERN
|
||||||
|
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module RuboCop
|
||||||
|
module Cop
|
||||||
|
module RSpec
|
||||||
|
# Check for repeated include of shared examples.
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
#
|
||||||
|
# # bad
|
||||||
|
# describe 'foo' do
|
||||||
|
# include_examples 'cool stuff'
|
||||||
|
# include_examples 'cool stuff'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# # bad
|
||||||
|
# describe 'foo' do
|
||||||
|
# it_behaves_like 'a cool', 'thing'
|
||||||
|
# it_behaves_like 'a cool', 'thing'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# # bad
|
||||||
|
# context 'foo' do
|
||||||
|
# it_should_behave_like 'a duck'
|
||||||
|
# it_should_behave_like 'a duck'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# # good
|
||||||
|
# describe 'foo' do
|
||||||
|
# include_examples 'cool stuff'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# describe 'bar' do
|
||||||
|
# include_examples 'cool stuff'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# # good
|
||||||
|
# describe 'foo' do
|
||||||
|
# it_behaves_like 'a cool', 'thing'
|
||||||
|
# it_behaves_like 'a cool', 'person'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# # good
|
||||||
|
# context 'foo' do
|
||||||
|
# it_should_behave_like 'a duck'
|
||||||
|
# it_should_behave_like 'a goose'
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
class RepeatedIncludeExample < Base
|
||||||
|
MSG = 'Repeated include of shared_examples %<name>s ' \
|
||||||
|
'on line(s) %<repeat>s'
|
||||||
|
|
||||||
|
def_node_matcher :several_include_examples?, <<-PATTERN
|
||||||
|
(begin <#include_examples? #include_examples? ...>)
|
||||||
|
PATTERN
|
||||||
|
|
||||||
|
def_node_matcher :include_examples?, Includes::EXAMPLES.send_pattern
|
||||||
|
|
||||||
|
def_node_matcher :shared_examples_name, <<-PATTERN
|
||||||
|
(send _ #{Includes::EXAMPLES.node_pattern_union} $_ ...)
|
||||||
|
PATTERN
|
||||||
|
|
||||||
|
def on_begin(node)
|
||||||
|
return unless several_include_examples?(node)
|
||||||
|
|
||||||
|
repeated_include_examples(node).each do |item, repeats|
|
||||||
|
add_offense(item, message: message(item, repeats))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def repeated_include_examples(node)
|
||||||
|
node
|
||||||
|
.children
|
||||||
|
.select { |child| literal_include_examples?(child) }
|
||||||
|
.group_by { |child| signature_keys(child) }
|
||||||
|
.values
|
||||||
|
.reject(&:one?)
|
||||||
|
.flat_map { |items| add_repeated_lines(items) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def literal_include_examples?(node)
|
||||||
|
include_examples?(node) &&
|
||||||
|
node.arguments.all?(&:recursive_literal_or_const?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_repeated_lines(items)
|
||||||
|
repeated_lines = items.map(&:first_line)
|
||||||
|
items.map { |item| [item, repeated_lines - [item.first_line]] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def signature_keys(item)
|
||||||
|
item.arguments
|
||||||
|
end
|
||||||
|
|
||||||
|
def message(item, repeats)
|
||||||
|
format(MSG, name: shared_examples_name(item).source, repeat: repeats)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,172 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module RuboCop
|
||||||
|
module Cop
|
||||||
|
module RSpec
|
||||||
|
# Checks that message expectations do not have a configured response.
|
||||||
|
#
|
||||||
|
# @example
|
||||||
|
#
|
||||||
|
# # bad
|
||||||
|
# expect(foo).to receive(:bar).with(42).and_return("hello world")
|
||||||
|
#
|
||||||
|
# # good (without spies)
|
||||||
|
# allow(foo).to receive(:bar).with(42).and_return("hello world")
|
||||||
|
# expect(foo).to receive(:bar).with(42)
|
||||||
|
#
|
||||||
|
class StubbedMock < Base
|
||||||
|
MSG = 'Prefer `%<replacement>s` over `%<method_name>s` when ' \
|
||||||
|
'configuring a response.'
|
||||||
|
|
||||||
|
# @!method message_expectation?(node)
|
||||||
|
# Match message expectation matcher
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive(:foo)
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive_message_chain(:foo, :bar)
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive(:foo).with('bar')
|
||||||
|
#
|
||||||
|
# @param node [RuboCop::AST::Node]
|
||||||
|
# @return [Array<RuboCop::AST::Node>] matching nodes
|
||||||
|
def_node_matcher :message_expectation?, <<-PATTERN
|
||||||
|
{
|
||||||
|
(send nil? { :receive :receive_message_chain } ...) # receive(:foo)
|
||||||
|
(send (send nil? :receive ...) :with ...) # receive(:foo).with('bar')
|
||||||
|
}
|
||||||
|
PATTERN
|
||||||
|
|
||||||
|
def_node_matcher :configured_response?, <<~PATTERN
|
||||||
|
{ :and_return :and_raise :and_throw :and_yield
|
||||||
|
:and_call_original :and_wrap_original }
|
||||||
|
PATTERN
|
||||||
|
|
||||||
|
# @!method expectation(node)
|
||||||
|
# Match expectation
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# is_expected.to be_in_the_bar
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# expect(cocktail).to contain_exactly(:fresh_orange_juice, :campari)
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# expect_any_instance_of(Officer).to be_alert
|
||||||
|
#
|
||||||
|
# @param node [RuboCop::AST::Node]
|
||||||
|
# @yield [RuboCop::AST::Node] expectation, method name, matcher
|
||||||
|
def_node_matcher :expectation, <<~PATTERN
|
||||||
|
(send
|
||||||
|
$(send nil? $#{Expectations::ALL.node_pattern_union} ...)
|
||||||
|
:to $_)
|
||||||
|
PATTERN
|
||||||
|
|
||||||
|
# @!method matcher_with_configured_response(node)
|
||||||
|
# Match matcher with a configured response
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive(:foo).and_return('bar')
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive(:lower).and_raise(SomeError)
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive(:redirect).and_call_original
|
||||||
|
#
|
||||||
|
# @param node [RuboCop::AST::Node]
|
||||||
|
# @yield [RuboCop::AST::Node] matcher
|
||||||
|
def_node_matcher :matcher_with_configured_response, <<~PATTERN
|
||||||
|
(send #message_expectation? #configured_response? _)
|
||||||
|
PATTERN
|
||||||
|
|
||||||
|
# @!method matcher_with_return_block(node)
|
||||||
|
# Match matcher with a return block
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive(:foo) { 'bar' }
|
||||||
|
#
|
||||||
|
# @param node [RuboCop::AST::Node]
|
||||||
|
# @yield [RuboCop::AST::Node] matcher
|
||||||
|
def_node_matcher :matcher_with_return_block, <<~PATTERN
|
||||||
|
(block #message_expectation? args _) # receive(:foo) { 'bar' }
|
||||||
|
PATTERN
|
||||||
|
|
||||||
|
# @!method matcher_with_hash(node)
|
||||||
|
# Match matcher with a configured response defined as a hash
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive_messages(foo: 'bar', baz: 'qux')
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive_message_chain(:foo, bar: 'baz')
|
||||||
|
#
|
||||||
|
# @param node [RuboCop::AST::Node]
|
||||||
|
# @yield [RuboCop::AST::Node] matcher
|
||||||
|
def_node_matcher :matcher_with_hash, <<~PATTERN
|
||||||
|
{
|
||||||
|
(send nil? :receive_messages hash) # receive_messages(foo: 'bar', baz: 'qux')
|
||||||
|
(send nil? :receive_message_chain ... hash) # receive_message_chain(:foo, bar: 'baz')
|
||||||
|
}
|
||||||
|
PATTERN
|
||||||
|
|
||||||
|
# @!method matcher_with_blockpass(node)
|
||||||
|
# Match matcher with a configured response in block-pass
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive(:foo, &canned)
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive_message_chain(:foo, :bar, &canned)
|
||||||
|
#
|
||||||
|
# @example source that matches
|
||||||
|
# receive(:foo).with('bar', &canned)
|
||||||
|
#
|
||||||
|
# @param node [RuboCop::AST::Node]
|
||||||
|
# @yield [RuboCop::AST::Node] matcher
|
||||||
|
def_node_matcher :matcher_with_blockpass, <<~PATTERN
|
||||||
|
{
|
||||||
|
(send nil? { :receive :receive_message_chain } ... block_pass) # receive(:foo, &canned)
|
||||||
|
(send (send nil? :receive ...) :with ... block_pass) # receive(:foo).with('foo', &canned)
|
||||||
|
}
|
||||||
|
PATTERN
|
||||||
|
|
||||||
|
def on_send(node)
|
||||||
|
expectation(node, &method(:on_expectation))
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def on_expectation(expectation, method_name, matcher)
|
||||||
|
flag_expectation = lambda do
|
||||||
|
add_offense(expectation, message: msg(method_name))
|
||||||
|
end
|
||||||
|
|
||||||
|
matcher_with_configured_response(matcher, &flag_expectation)
|
||||||
|
matcher_with_return_block(matcher, &flag_expectation)
|
||||||
|
matcher_with_hash(matcher, &flag_expectation)
|
||||||
|
matcher_with_blockpass(matcher, &flag_expectation)
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -43,10 +43,10 @@ module RuboCop
|
|||||||
#
|
#
|
||||||
# @yield [Symbol] subject name
|
# @yield [Symbol] subject name
|
||||||
def_node_matcher :subject, <<-PATTERN
|
def_node_matcher :subject, <<-PATTERN
|
||||||
{
|
(block
|
||||||
(block (send nil? :subject (sym $_)) args ...)
|
(send nil?
|
||||||
(block (send nil? $:subject) args ...)
|
{:subject (sym $_) | $:subject}
|
||||||
}
|
) args ...)
|
||||||
PATTERN
|
PATTERN
|
||||||
|
|
||||||
# @!method message_expectation?(node, method_name)
|
# @!method message_expectation?(node, method_name)
|
||||||
@ -79,12 +79,14 @@ require_relative 'rspec/repeated_description'
|
|||||||
require_relative 'rspec/repeated_example'
|
require_relative 'rspec/repeated_example'
|
||||||
require_relative 'rspec/repeated_example_group_body'
|
require_relative 'rspec/repeated_example_group_body'
|
||||||
require_relative 'rspec/repeated_example_group_description'
|
require_relative 'rspec/repeated_example_group_description'
|
||||||
|
require_relative 'rspec/repeated_include_example'
|
||||||
require_relative 'rspec/return_from_stub'
|
require_relative 'rspec/return_from_stub'
|
||||||
require_relative 'rspec/scattered_let'
|
require_relative 'rspec/scattered_let'
|
||||||
require_relative 'rspec/scattered_setup'
|
require_relative 'rspec/scattered_setup'
|
||||||
require_relative 'rspec/shared_context'
|
require_relative 'rspec/shared_context'
|
||||||
require_relative 'rspec/shared_examples'
|
require_relative 'rspec/shared_examples'
|
||||||
require_relative 'rspec/single_argument_message_chain'
|
require_relative 'rspec/single_argument_message_chain'
|
||||||
|
require_relative 'rspec/stubbed_mock'
|
||||||
require_relative 'rspec/subject_stub'
|
require_relative 'rspec/subject_stub'
|
||||||
require_relative 'rspec/unspecified_exception'
|
require_relative 'rspec/unspecified_exception'
|
||||||
require_relative 'rspec/variable_definition'
|
require_relative 'rspec/variable_definition'
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user