brew vendor-gems: commit updates.
This commit is contained in:
		
							parent
							
								
									4a02728c3a
								
							
						
					
					
						commit
						9bfc745940
					
				
							
								
								
									
										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/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/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/colorize-0.8.1/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/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/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/patchelf-1.3.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}/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/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/ronn-0.7.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-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/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/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-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/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-0.5.5942/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.5949/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/spoom-1.0.4/lib"
 | 
			
		||||
 | 
			
		||||
@ -76,7 +76,23 @@ RSpec/ContextWording:
 | 
			
		||||
RSpec/DescribeClass:
 | 
			
		||||
  Description: Check that the first argument to the top-level describe is a constant.
 | 
			
		||||
  Enabled: true
 | 
			
		||||
  IgnoredMetadata:
 | 
			
		||||
    type:
 | 
			
		||||
    - channel
 | 
			
		||||
    - controller
 | 
			
		||||
    - helper
 | 
			
		||||
    - job
 | 
			
		||||
    - mailer
 | 
			
		||||
    - model
 | 
			
		||||
    - request
 | 
			
		||||
    - routing
 | 
			
		||||
    - view
 | 
			
		||||
    - feature
 | 
			
		||||
    - system
 | 
			
		||||
    - mailbox
 | 
			
		||||
    - aruba
 | 
			
		||||
  VersionAdded: '1.0'
 | 
			
		||||
  VersionChanged: '1.44'
 | 
			
		||||
  StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/DescribeClass
 | 
			
		||||
 | 
			
		||||
RSpec/DescribeMethod:
 | 
			
		||||
@ -494,6 +510,12 @@ RSpec/RepeatedExampleGroupDescription:
 | 
			
		||||
  VersionAdded: '1.38'
 | 
			
		||||
  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:
 | 
			
		||||
  Description: Checks for consistent style of stub's return setting.
 | 
			
		||||
  Enabled: true
 | 
			
		||||
@ -537,6 +559,12 @@ RSpec/SingleArgumentMessageChain:
 | 
			
		||||
  VersionChanged: '1.10'
 | 
			
		||||
  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:
 | 
			
		||||
  Description: Checks for stubbed test subjects.
 | 
			
		||||
  Enabled: true
 | 
			
		||||
@ -31,7 +31,7 @@ module RuboCop
 | 
			
		||||
                         'or `%<arg>s.run`.'
 | 
			
		||||
 | 
			
		||||
        def_node_matcher :hook, <<-PATTERN
 | 
			
		||||
          (block {(send nil? :around) (send nil? :around sym)} (args $...) ...)
 | 
			
		||||
          (block (send nil? :around sym ?) (args $...) ...)
 | 
			
		||||
        PATTERN
 | 
			
		||||
 | 
			
		||||
        def_node_search :find_arg_usage, <<-PATTERN
 | 
			
		||||
@ -29,6 +29,8 @@ module RuboCop
 | 
			
		||||
                               .map(&Regexp.public_method(:new))
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        exclude_from_registry
 | 
			
		||||
 | 
			
		||||
        # Invoke the original inherited hook so our cops are recognized
 | 
			
		||||
        def self.inherited(subclass) # rubocop:disable Lint/MissingSuper
 | 
			
		||||
          RuboCop::Cop::Base.inherited(subclass)
 | 
			
		||||
@ -5,6 +5,19 @@ module RuboCop
 | 
			
		||||
    module RSpec
 | 
			
		||||
      # 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
 | 
			
		||||
      #   # bad
 | 
			
		||||
      #   describe 'Do something' do
 | 
			
		||||
@ -27,36 +40,42 @@ module RuboCop
 | 
			
		||||
        MSG = 'The first argument to describe should be '\
 | 
			
		||||
              'the class or module being tested.'
 | 
			
		||||
 | 
			
		||||
        def_node_matcher :rails_metadata?, <<-PATTERN
 | 
			
		||||
          (pair
 | 
			
		||||
            (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? ...>))
 | 
			
		||||
        def_node_matcher :example_group_with_ignored_metadata?, <<~PATTERN
 | 
			
		||||
          (send #rspec? :describe ... (hash <#ignored_metadata? ...>))
 | 
			
		||||
        PATTERN
 | 
			
		||||
 | 
			
		||||
        def_node_matcher :not_a_const_described, <<~PATTERN
 | 
			
		||||
          (send #rspec? :describe $[!const !#string_constant?] ...)
 | 
			
		||||
        PATTERN
 | 
			
		||||
 | 
			
		||||
        def on_top_level_group(top_level_node)
 | 
			
		||||
          return if example_group_with_rails_metadata?(top_level_node.send_node)
 | 
			
		||||
        def_node_matcher :sym_pair, <<~PATTERN
 | 
			
		||||
          (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)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
          described.str_type? &&
 | 
			
		||||
            described.value.match?(/^(?:(?:::)?[A-Z]\w*)+$/)
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def ignored_metadata
 | 
			
		||||
          cop_config['IgnoredMetadata'] || {}
 | 
			
		||||
        end
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
@ -33,6 +33,11 @@ module RuboCop
 | 
			
		||||
      #     end
 | 
			
		||||
      #   end
 | 
			
		||||
      #
 | 
			
		||||
      #   # good
 | 
			
		||||
      #   describe Bacon do
 | 
			
		||||
      #     pending 'will add tests later'
 | 
			
		||||
      #   end
 | 
			
		||||
      #
 | 
			
		||||
      # @example configuration
 | 
			
		||||
      #
 | 
			
		||||
      #   # .rubocop.yml
 | 
			
		||||
@ -83,11 +88,14 @@ module RuboCop
 | 
			
		||||
        #     it_behaves_like 'an animal'
 | 
			
		||||
        #     it_behaves_like('a cat') { let(:food) { 'milk' } }
 | 
			
		||||
        #     it_has_root_access
 | 
			
		||||
        #     skip
 | 
			
		||||
        #     it 'will be implemented later'
 | 
			
		||||
        #
 | 
			
		||||
        #   @param node [RuboCop::AST::Node]
 | 
			
		||||
        #   @return [Array<RuboCop::AST::Node>] matching nodes
 | 
			
		||||
        def_node_matcher :example_or_group_or_include?, <<~PATTERN
 | 
			
		||||
          {
 | 
			
		||||
            #{Examples::ALL.send_pattern}
 | 
			
		||||
            #{Examples::ALL.block_pattern}
 | 
			
		||||
            #{ExampleGroups::ALL.block_pattern}
 | 
			
		||||
            #{Includes::ALL.send_pattern}
 | 
			
		||||
@ -152,13 +160,39 @@ module RuboCop
 | 
			
		||||
        PATTERN
 | 
			
		||||
 | 
			
		||||
        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|
 | 
			
		||||
            add_offense(node.send_node) unless examples?(body)
 | 
			
		||||
            add_offense(node.send_node) if offensive?(body)
 | 
			
		||||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        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)
 | 
			
		||||
          custom_include_methods.include?(method_name)
 | 
			
		||||
        end
 | 
			
		||||
@ -22,8 +22,7 @@ module RuboCop
 | 
			
		||||
        def_node_matcher :lambda?, <<-PATTERN
 | 
			
		||||
          {
 | 
			
		||||
            (send (const nil? :Proc) :new)
 | 
			
		||||
            (send nil? :proc)
 | 
			
		||||
            (send nil? :lambda)
 | 
			
		||||
            (send nil? {:proc :lambda})
 | 
			
		||||
          }
 | 
			
		||||
        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
 | 
			
		||||
        def_node_matcher :subject, <<-PATTERN
 | 
			
		||||
          {
 | 
			
		||||
            (block (send nil? :subject (sym $_)) args ...)
 | 
			
		||||
            (block (send nil? $:subject) args ...)
 | 
			
		||||
          }
 | 
			
		||||
            (block
 | 
			
		||||
              (send nil?
 | 
			
		||||
                {:subject (sym $_) | $:subject}
 | 
			
		||||
              ) args ...)
 | 
			
		||||
        PATTERN
 | 
			
		||||
 | 
			
		||||
        # @!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_group_body'
 | 
			
		||||
require_relative 'rspec/repeated_example_group_description'
 | 
			
		||||
require_relative 'rspec/repeated_include_example'
 | 
			
		||||
require_relative 'rspec/return_from_stub'
 | 
			
		||||
require_relative 'rspec/scattered_let'
 | 
			
		||||
require_relative 'rspec/scattered_setup'
 | 
			
		||||
require_relative 'rspec/shared_context'
 | 
			
		||||
require_relative 'rspec/shared_examples'
 | 
			
		||||
require_relative 'rspec/single_argument_message_chain'
 | 
			
		||||
require_relative 'rspec/stubbed_mock'
 | 
			
		||||
require_relative 'rspec/subject_stub'
 | 
			
		||||
require_relative 'rspec/unspecified_exception'
 | 
			
		||||
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