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