Merge pull request #5635 from Homebrew/dependabot/bundler/Library/Homebrew/vendor/rubocop-rspec-1.32.0
Bump rubocop-rspec from 1.31.0 to 1.32.0 in /Library/Homebrew/vendor
This commit is contained in:
		
						commit
						5866c2b00a
					
				
							
								
								
									
										2
									
								
								Library/Homebrew/vendor/Gemfile.lock
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								Library/Homebrew/vendor/Gemfile.lock
									
									
									
									
										vendored
									
									
								
							@ -27,7 +27,7 @@ GEM
 | 
				
			|||||||
      rainbow (>= 2.2.2, < 4.0)
 | 
					      rainbow (>= 2.2.2, < 4.0)
 | 
				
			||||||
      ruby-progressbar (~> 1.7)
 | 
					      ruby-progressbar (~> 1.7)
 | 
				
			||||||
      unicode-display_width (~> 1.4.0)
 | 
					      unicode-display_width (~> 1.4.0)
 | 
				
			||||||
    rubocop-rspec (1.31.0)
 | 
					    rubocop-rspec (1.32.0)
 | 
				
			||||||
      rubocop (>= 0.60.0)
 | 
					      rubocop (>= 0.60.0)
 | 
				
			||||||
    ruby-macho (2.1.0)
 | 
					    ruby-macho (2.1.0)
 | 
				
			||||||
    ruby-progressbar (1.10.0)
 | 
					    ruby-progressbar (1.10.0)
 | 
				
			||||||
 | 
				
			|||||||
@ -22,5 +22,5 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rainbow-3.0.0/lib"
 | 
				
			|||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.10.0/lib"
 | 
					$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.10.0/lib"
 | 
				
			||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-1.4.1/lib"
 | 
					$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-1.4.1/lib"
 | 
				
			||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.63.1/lib"
 | 
					$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.63.1/lib"
 | 
				
			||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.31.0/lib"
 | 
					$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.32.0/lib"
 | 
				
			||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.1.0/lib"
 | 
					$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.1.0/lib"
 | 
				
			||||||
 | 
				
			|||||||
@ -1,150 +0,0 @@
 | 
				
			|||||||
# frozen_string_literal: true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module RuboCop
 | 
					 | 
				
			||||||
  module Cop
 | 
					 | 
				
			||||||
    module RSpec
 | 
					 | 
				
			||||||
      module FactoryBot
 | 
					 | 
				
			||||||
        # Checks for create_list usage.
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
        # This cop can be configured using the `EnforcedStyle` option
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
        # @example `EnforcedStyle: create_list`
 | 
					 | 
				
			||||||
        #   # bad
 | 
					 | 
				
			||||||
        #   3.times { create :user }
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
        #   # good
 | 
					 | 
				
			||||||
        #   create_list :user, 3
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
        #   # good
 | 
					 | 
				
			||||||
        #   3.times { |n| create :user, created_at: n.months.ago }
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
        # @example `EnforcedStyle: n_times`
 | 
					 | 
				
			||||||
        #   # bad
 | 
					 | 
				
			||||||
        #   create_list :user, 3
 | 
					 | 
				
			||||||
        #
 | 
					 | 
				
			||||||
        #   # good
 | 
					 | 
				
			||||||
        #   3.times { create :user }
 | 
					 | 
				
			||||||
        class CreateList < Cop
 | 
					 | 
				
			||||||
          include ConfigurableEnforcedStyle
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          MSG_CREATE_LIST = 'Prefer create_list.'.freeze
 | 
					 | 
				
			||||||
          MSG_N_TIMES = 'Prefer %<number>s.times.'.freeze
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def_node_matcher :n_times_block_without_arg?, <<-PATTERN
 | 
					 | 
				
			||||||
            (block
 | 
					 | 
				
			||||||
              (send (int _) :times)
 | 
					 | 
				
			||||||
              (args)
 | 
					 | 
				
			||||||
              ...
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
          PATTERN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def_node_matcher :factory_call, <<-PATTERN
 | 
					 | 
				
			||||||
            (send ${(const nil? {:FactoryGirl :FactoryBot}) nil?} :create (sym $_) $...)
 | 
					 | 
				
			||||||
          PATTERN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def_node_matcher :factory_list_call, <<-PATTERN
 | 
					 | 
				
			||||||
            (send ${(const nil? {:FactoryGirl :FactoryBot}) nil?} :create_list (sym $_) (int $_) $...)
 | 
					 | 
				
			||||||
          PATTERN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def on_block(node)
 | 
					 | 
				
			||||||
            return unless style == :create_list
 | 
					 | 
				
			||||||
            return unless n_times_block_without_arg?(node)
 | 
					 | 
				
			||||||
            return unless contains_only_factory?(node.body)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            add_offense(node.send_node,
 | 
					 | 
				
			||||||
                        location: :expression, message: MSG_CREATE_LIST)
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def on_send(node)
 | 
					 | 
				
			||||||
            return unless style == :n_times
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            factory_list_call(node) do |_receiver, _factory, count, _|
 | 
					 | 
				
			||||||
              add_offense(
 | 
					 | 
				
			||||||
                node,
 | 
					 | 
				
			||||||
                location: :selector,
 | 
					 | 
				
			||||||
                message: format(MSG_N_TIMES, number: count)
 | 
					 | 
				
			||||||
              )
 | 
					 | 
				
			||||||
            end
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def autocorrect(node)
 | 
					 | 
				
			||||||
            if style == :create_list
 | 
					 | 
				
			||||||
              autocorrect_n_times_to_create_list(node)
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
              autocorrect_create_list_to_n_times(node)
 | 
					 | 
				
			||||||
            end
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          private
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def contains_only_factory?(node)
 | 
					 | 
				
			||||||
            if node.block_type?
 | 
					 | 
				
			||||||
              factory_call(node.send_node)
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
              factory_call(node)
 | 
					 | 
				
			||||||
            end
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def autocorrect_n_times_to_create_list(node)
 | 
					 | 
				
			||||||
            block = node.parent
 | 
					 | 
				
			||||||
            count = block.receiver.source
 | 
					 | 
				
			||||||
            replacement = factory_call_replacement(block.body, count)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            lambda do |corrector|
 | 
					 | 
				
			||||||
              corrector.replace(block.loc.expression, replacement)
 | 
					 | 
				
			||||||
            end
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def autocorrect_create_list_to_n_times(node)
 | 
					 | 
				
			||||||
            replacement = generate_n_times_block(node)
 | 
					 | 
				
			||||||
            lambda do |corrector|
 | 
					 | 
				
			||||||
              corrector.replace(node.loc.expression, replacement)
 | 
					 | 
				
			||||||
            end
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def generate_n_times_block(node)
 | 
					 | 
				
			||||||
            receiver, factory, count, options = *factory_list_call(node)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            arguments = ":#{factory}"
 | 
					 | 
				
			||||||
            options = build_options_string(options)
 | 
					 | 
				
			||||||
            arguments += ", #{options}" unless options.empty?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            replacement = format_receiver(receiver)
 | 
					 | 
				
			||||||
            replacement += format_method_call(node, 'create', arguments)
 | 
					 | 
				
			||||||
            "#{count}.times { #{replacement} }"
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def factory_call_replacement(body, count)
 | 
					 | 
				
			||||||
            receiver, factory, options = *factory_call(body)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            arguments = ":#{factory}, #{count}"
 | 
					 | 
				
			||||||
            options = build_options_string(options)
 | 
					 | 
				
			||||||
            arguments += ", #{options}" unless options.empty?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            replacement = format_receiver(receiver)
 | 
					 | 
				
			||||||
            replacement += format_method_call(body, 'create_list', arguments)
 | 
					 | 
				
			||||||
            replacement
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def build_options_string(options)
 | 
					 | 
				
			||||||
            options.map(&:source).join(', ')
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def format_method_call(node, method, arguments)
 | 
					 | 
				
			||||||
            if node.parenthesized?
 | 
					 | 
				
			||||||
              "#{method}(#{arguments})"
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
              "#{method} #{arguments}"
 | 
					 | 
				
			||||||
            end
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          def format_receiver(receiver)
 | 
					 | 
				
			||||||
            return '' unless receiver
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            "#{receiver.source}."
 | 
					 | 
				
			||||||
          end
 | 
					 | 
				
			||||||
        end
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
    end
 | 
					 | 
				
			||||||
  end
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
@ -417,6 +417,11 @@ RSpec/VoidExpect:
 | 
				
			|||||||
  Enabled: true
 | 
					  Enabled: true
 | 
				
			||||||
  StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VoidExpect
 | 
					  StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/VoidExpect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RSpec/Yield:
 | 
				
			||||||
 | 
					  Description: This cop checks for calling a block within a stub.
 | 
				
			||||||
 | 
					  Enabled: true
 | 
				
			||||||
 | 
					  StyleGuide: http://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/Yield
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Capybara/CurrentPathExpectation:
 | 
					Capybara/CurrentPathExpectation:
 | 
				
			||||||
  Description: Checks that no expectations are set on Capybara's `current_path`.
 | 
					  Description: Checks that no expectations are set on Capybara's `current_path`.
 | 
				
			||||||
  Enabled: true
 | 
					  Enabled: true
 | 
				
			||||||
@ -0,0 +1,214 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module RuboCop
 | 
				
			||||||
 | 
					  module Cop
 | 
				
			||||||
 | 
					    module RSpec
 | 
				
			||||||
 | 
					      module FactoryBot
 | 
				
			||||||
 | 
					        # Checks for create_list usage.
 | 
				
			||||||
 | 
					        #
 | 
				
			||||||
 | 
					        # This cop can be configured using the `EnforcedStyle` option
 | 
				
			||||||
 | 
					        #
 | 
				
			||||||
 | 
					        # @example `EnforcedStyle: create_list`
 | 
				
			||||||
 | 
					        #   # bad
 | 
				
			||||||
 | 
					        #   3.times { create :user }
 | 
				
			||||||
 | 
					        #
 | 
				
			||||||
 | 
					        #   # good
 | 
				
			||||||
 | 
					        #   create_list :user, 3
 | 
				
			||||||
 | 
					        #
 | 
				
			||||||
 | 
					        #   # good
 | 
				
			||||||
 | 
					        #   3.times { |n| create :user, created_at: n.months.ago }
 | 
				
			||||||
 | 
					        #
 | 
				
			||||||
 | 
					        # @example `EnforcedStyle: n_times`
 | 
				
			||||||
 | 
					        #   # bad
 | 
				
			||||||
 | 
					        #   create_list :user, 3
 | 
				
			||||||
 | 
					        #
 | 
				
			||||||
 | 
					        #   # good
 | 
				
			||||||
 | 
					        #   3.times { create :user }
 | 
				
			||||||
 | 
					        class CreateList < Cop
 | 
				
			||||||
 | 
					          include ConfigurableEnforcedStyle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          MSG_CREATE_LIST = 'Prefer create_list.'.freeze
 | 
				
			||||||
 | 
					          MSG_N_TIMES = 'Prefer %<number>s.times.'.freeze
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          def_node_matcher :n_times_block_without_arg?, <<-PATTERN
 | 
				
			||||||
 | 
					            (block
 | 
				
			||||||
 | 
					              (send (int _) :times)
 | 
				
			||||||
 | 
					              (args)
 | 
				
			||||||
 | 
					              ...
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					          PATTERN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          def_node_matcher :factory_call, <<-PATTERN
 | 
				
			||||||
 | 
					            (send ${(const nil? {:FactoryGirl :FactoryBot}) nil?} :create (sym $_) $...)
 | 
				
			||||||
 | 
					          PATTERN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          def_node_matcher :factory_list_call, <<-PATTERN
 | 
				
			||||||
 | 
					            (send ${(const nil? {:FactoryGirl :FactoryBot}) nil?} :create_list (sym $_) (int $_) $...)
 | 
				
			||||||
 | 
					          PATTERN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          def on_block(node)
 | 
				
			||||||
 | 
					            return unless style == :create_list
 | 
				
			||||||
 | 
					            return unless n_times_block_without_arg?(node)
 | 
				
			||||||
 | 
					            return unless contains_only_factory?(node.body)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            add_offense(node.send_node,
 | 
				
			||||||
 | 
					                        location: :expression, message: MSG_CREATE_LIST)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          def on_send(node)
 | 
				
			||||||
 | 
					            return unless style == :n_times
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            factory_list_call(node) do |_receiver, _factory, count, _|
 | 
				
			||||||
 | 
					              add_offense(
 | 
				
			||||||
 | 
					                node,
 | 
				
			||||||
 | 
					                location: :selector,
 | 
				
			||||||
 | 
					                message: format(MSG_N_TIMES, number: count)
 | 
				
			||||||
 | 
					              )
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          def autocorrect(node)
 | 
				
			||||||
 | 
					            if style == :create_list
 | 
				
			||||||
 | 
					              CreateListCorrector.new(node)
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              TimesCorrector.new(node)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          def contains_only_factory?(node)
 | 
				
			||||||
 | 
					            if node.block_type?
 | 
				
			||||||
 | 
					              factory_call(node.send_node)
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              factory_call(node)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          # :nodoc
 | 
				
			||||||
 | 
					          class Corrector
 | 
				
			||||||
 | 
					            private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def build_options_string(options)
 | 
				
			||||||
 | 
					              options.map(&:source).join(', ')
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def format_method_call(node, method, arguments)
 | 
				
			||||||
 | 
					              if node.block_type? || node.parenthesized?
 | 
				
			||||||
 | 
					                "#{method}(#{arguments})"
 | 
				
			||||||
 | 
					              else
 | 
				
			||||||
 | 
					                "#{method} #{arguments}"
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def format_receiver(receiver)
 | 
				
			||||||
 | 
					              return '' unless receiver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              "#{receiver.source}."
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          # :nodoc
 | 
				
			||||||
 | 
					          class TimesCorrector < Corrector
 | 
				
			||||||
 | 
					            def initialize(node)
 | 
				
			||||||
 | 
					              @node = node
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def call(corrector)
 | 
				
			||||||
 | 
					              replacement = generate_n_times_block(node)
 | 
				
			||||||
 | 
					              corrector.replace(node.loc.expression, replacement)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            attr_reader :node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def generate_n_times_block(node)
 | 
				
			||||||
 | 
					              factory, count, *options = node.arguments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              arguments = factory.source
 | 
				
			||||||
 | 
					              options = build_options_string(options)
 | 
				
			||||||
 | 
					              arguments += ", #{options}" unless options.empty?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              replacement = format_receiver(node.receiver)
 | 
				
			||||||
 | 
					              replacement += format_method_call(node, 'create', arguments)
 | 
				
			||||||
 | 
					              "#{count.source}.times { #{replacement} }"
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          # :nodoc:
 | 
				
			||||||
 | 
					          class CreateListCorrector < Corrector
 | 
				
			||||||
 | 
					            def initialize(node)
 | 
				
			||||||
 | 
					              @node = node.parent
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def call(corrector)
 | 
				
			||||||
 | 
					              replacement = if node.body.block_type?
 | 
				
			||||||
 | 
					                              call_with_block_replacement(node)
 | 
				
			||||||
 | 
					                            else
 | 
				
			||||||
 | 
					                              call_replacement(node)
 | 
				
			||||||
 | 
					                            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              corrector.replace(node.loc.expression, replacement)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            attr_reader :node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def call_with_block_replacement(node)
 | 
				
			||||||
 | 
					              block = node.body
 | 
				
			||||||
 | 
					              arguments = build_arguments(block, node.receiver.source)
 | 
				
			||||||
 | 
					              replacement = format_receiver(block.send_node.receiver)
 | 
				
			||||||
 | 
					              replacement += format_method_call(block, 'create_list', arguments)
 | 
				
			||||||
 | 
					              replacement += format_block(block)
 | 
				
			||||||
 | 
					              replacement
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def build_arguments(node, count)
 | 
				
			||||||
 | 
					              factory, *options = *node.send_node.arguments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              arguments = ":#{factory.value}, #{count}"
 | 
				
			||||||
 | 
					              options = build_options_string(options)
 | 
				
			||||||
 | 
					              arguments += ", #{options}" unless options.empty?
 | 
				
			||||||
 | 
					              arguments
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def call_replacement(node)
 | 
				
			||||||
 | 
					              block = node.body
 | 
				
			||||||
 | 
					              factory, *options = *block.arguments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              arguments = "#{factory.source}, #{node.receiver.source}"
 | 
				
			||||||
 | 
					              options = build_options_string(options)
 | 
				
			||||||
 | 
					              arguments += ", #{options}" unless options.empty?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              replacement = format_receiver(block.receiver)
 | 
				
			||||||
 | 
					              replacement += format_method_call(block, 'create_list', arguments)
 | 
				
			||||||
 | 
					              replacement
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def format_block(node)
 | 
				
			||||||
 | 
					              if node.body.begin_type?
 | 
				
			||||||
 | 
					                format_multiline_block(node)
 | 
				
			||||||
 | 
					              else
 | 
				
			||||||
 | 
					                format_singeline_block(node)
 | 
				
			||||||
 | 
					              end
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def format_multiline_block(node)
 | 
				
			||||||
 | 
					              indent = ' ' * node.body.loc.column
 | 
				
			||||||
 | 
					              indent_end = ' ' * node.parent.loc.column
 | 
				
			||||||
 | 
					              " do #{node.arguments.source}\n" \
 | 
				
			||||||
 | 
					              "#{indent}#{node.body.source}\n" \
 | 
				
			||||||
 | 
					              "#{indent_end}end"
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            def format_singeline_block(node)
 | 
				
			||||||
 | 
					              " { #{node.arguments.source} #{node.body.source} }"
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@ -36,8 +36,8 @@ module RuboCop
 | 
				
			|||||||
        FOCUS_TRUE   = s(:pair, FOCUS_SYMBOL, s(:true))
 | 
					        FOCUS_TRUE   = s(:pair, FOCUS_SYMBOL, s(:true))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def_node_matcher :metadata, <<-PATTERN
 | 
					        def_node_matcher :metadata, <<-PATTERN
 | 
				
			||||||
          {(send nil? #{FOCUSABLE_SELECTORS} ... (hash $...))
 | 
					          {(send {(const nil? :RSpec) nil?} #{FOCUSABLE_SELECTORS} ... (hash $...))
 | 
				
			||||||
           (send nil? #{FOCUSABLE_SELECTORS} $...)}
 | 
					           (send {(const nil? :RSpec) nil?} #{FOCUSABLE_SELECTORS} $...)}
 | 
				
			||||||
        PATTERN
 | 
					        PATTERN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def_node_matcher :focused_block?, focused.send_pattern
 | 
					        def_node_matcher :focused_block?, focused.send_pattern
 | 
				
			||||||
@ -37,8 +37,8 @@ module RuboCop
 | 
				
			|||||||
        PENDING_SYMBOL = s(:sym, :pending)
 | 
					        PENDING_SYMBOL = s(:sym, :pending)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def_node_matcher :metadata, <<-PATTERN
 | 
					        def_node_matcher :metadata, <<-PATTERN
 | 
				
			||||||
          {(send nil? #{SKIPPABLE_SELECTORS} ... (hash $...))
 | 
					          {(send {(const nil? :RSpec) nil?} #{SKIPPABLE_SELECTORS} ... (hash $...))
 | 
				
			||||||
           (send nil? #{SKIPPABLE_SELECTORS} $...)}
 | 
					           (send {(const nil? :RSpec) nil?} #{SKIPPABLE_SELECTORS} $...)}
 | 
				
			||||||
        PATTERN
 | 
					        PATTERN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def_node_matcher :pending_block?, PENDING_EXAMPLES.send_pattern
 | 
					        def_node_matcher :pending_block?, PENDING_EXAMPLES.send_pattern
 | 
				
			||||||
@ -30,8 +30,12 @@ module RuboCop
 | 
				
			|||||||
          (send $(send _ {:exactly :at_least :at_most} (int {1 2})) :times)
 | 
					          (send $(send _ {:exactly :at_least :at_most} (int {1 2})) :times)
 | 
				
			||||||
        PATTERN
 | 
					        PATTERN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def_node_search :stub?, '(send nil? :receive ...)'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def on_send(node)
 | 
					        def on_send(node)
 | 
				
			||||||
          receive_counts(node) do |offending_node|
 | 
					          receive_counts(node) do |offending_node|
 | 
				
			||||||
 | 
					            return unless stub?(offending_node.receiver)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            offending_range = range(node, offending_node)
 | 
					            offending_range = range(node, offending_node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            add_offense(
 | 
					            add_offense(
 | 
				
			||||||
@ -48,10 +52,9 @@ module RuboCop
 | 
				
			|||||||
              node.method_name,
 | 
					              node.method_name,
 | 
				
			||||||
              node.first_argument.source.to_i
 | 
					              node.first_argument.source.to_i
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            corrector.replace(
 | 
					
 | 
				
			||||||
              range(node.parent, node),
 | 
					            original = range(node.parent, node)
 | 
				
			||||||
              replacement
 | 
					            corrector.replace(original, replacement)
 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
          end
 | 
					          end
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -0,0 +1,77 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module RuboCop
 | 
				
			||||||
 | 
					  module Cop
 | 
				
			||||||
 | 
					    module RSpec
 | 
				
			||||||
 | 
					      # This cop checks for calling a block within a stub.
 | 
				
			||||||
 | 
					      #
 | 
				
			||||||
 | 
					      # @example
 | 
				
			||||||
 | 
					      #   # bad
 | 
				
			||||||
 | 
					      #   allow(foo).to receive(:bar) { |&block| block.call(1) }
 | 
				
			||||||
 | 
					      #
 | 
				
			||||||
 | 
					      #   # good
 | 
				
			||||||
 | 
					      #   expect(foo).to be(:bar).and_yield(1)
 | 
				
			||||||
 | 
					      class Yield < Cop
 | 
				
			||||||
 | 
					        include RangeHelp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        MSG = 'Use `.and_yield`.'.freeze
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def_node_search :method_on_stub?, '(send nil? :receive ...)'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def_node_matcher :block_arg, '(args (blockarg $_))'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def_node_matcher :block_call?, '(send (lvar %) :call ...)'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def on_block(node)
 | 
				
			||||||
 | 
					          return unless method_on_stub?(node.send_node)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          block_arg(node.arguments) do |block|
 | 
				
			||||||
 | 
					            if calling_block?(node.body, block)
 | 
				
			||||||
 | 
					              add_offense(node, location: block_range(node))
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def autocorrect(node)
 | 
				
			||||||
 | 
					          lambda do |corrector|
 | 
				
			||||||
 | 
					            node_range = range_with_surrounding_space(
 | 
				
			||||||
 | 
					              range: block_range(node), side: :left
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            corrector.replace(node_range, generate_replacement(node.body))
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def calling_block?(node, block)
 | 
				
			||||||
 | 
					          if node.begin_type?
 | 
				
			||||||
 | 
					            node.each_child_node.all? { |child| block_call?(child, block) }
 | 
				
			||||||
 | 
					          else
 | 
				
			||||||
 | 
					            block_call?(node, block)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def block_range(node)
 | 
				
			||||||
 | 
					          block_start = node.loc.begin.begin_pos
 | 
				
			||||||
 | 
					          block_end = node.loc.end.end_pos
 | 
				
			||||||
 | 
					          range_between(block_start, block_end)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def generate_replacement(node)
 | 
				
			||||||
 | 
					          if node.begin_type?
 | 
				
			||||||
 | 
					            node.children.map { |child| convert_block_to_yield(child) }.join
 | 
				
			||||||
 | 
					          else
 | 
				
			||||||
 | 
					            convert_block_to_yield(node)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def convert_block_to_yield(node)
 | 
				
			||||||
 | 
					          args = node.arguments
 | 
				
			||||||
 | 
					          replacement = '.and_yield'
 | 
				
			||||||
 | 
					          replacement += "(#{args.map(&:source).join(', ')})" if args.any?
 | 
				
			||||||
 | 
					          replacement
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@ -75,3 +75,4 @@ require_relative 'rspec/subject_stub'
 | 
				
			|||||||
require_relative 'rspec/unspecified_exception'
 | 
					require_relative 'rspec/unspecified_exception'
 | 
				
			||||||
require_relative 'rspec/verified_doubles'
 | 
					require_relative 'rspec/verified_doubles'
 | 
				
			||||||
require_relative 'rspec/void_expect'
 | 
					require_relative 'rspec/void_expect'
 | 
				
			||||||
 | 
					require_relative 'rspec/yield'
 | 
				
			||||||
@ -4,7 +4,7 @@ module RuboCop
 | 
				
			|||||||
  module RSpec
 | 
					  module RSpec
 | 
				
			||||||
    # Version information for the RSpec RuboCop plugin.
 | 
					    # Version information for the RSpec RuboCop plugin.
 | 
				
			||||||
    module Version
 | 
					    module Version
 | 
				
			||||||
      STRING = '1.31.0'.freeze
 | 
					      STRING = '1.32.0'.freeze
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user