Class: RuboCop::Cop::RSpec::SharedContext

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Defined in:
lib/rubocop/cop/rspec/shared_context.rb

Overview

Checks for proper shared_context and shared_examples usage.

If there are no examples defined, use shared_context. If there is no setup defined, use shared_examples.

With ‘Strict: true`, `shared_context` is flagged whenever it contains any examples, even if it also contains setup code.

Examples:

# bad
RSpec.shared_context 'only examples here' do
  it 'does x' do
  end

  it 'does y' do
  end
end

# good
RSpec.shared_examples 'only examples here' do
  it 'does x' do
  end

  it 'does y' do
  end
end
# bad
RSpec.shared_examples 'only setup here' do
  subject(:foo) { :bar }

  let(:baz) { :bazz }

  before do
    something
  end
end

# good
RSpec.shared_context 'only setup here' do
  subject(:foo) { :bar }

  let(:baz) { :bazz }

  before do
    something
  end
end

Strict: true

# bad - shared_context with examples is flagged
RSpec.shared_context 'setup and examples' do
  let(:foo) { :bar }

  it 'does x' do
  end
end

# good - split into separate shared_context and shared_examples
RSpec.shared_context 'setup' do
  let(:foo) { :bar }
end

RSpec.shared_examples 'examples' do
  it 'does x' do
  end
end

Constant Summary collapse

MSG_EXAMPLES =
"Use `shared_examples` when you don't define context."
MSG_EXAMPLES_STRICT =
'Use `shared_examples` when you define examples.'
MSG_CONTEXT =
"Use `shared_context` when you don't define examples."

Instance Method Summary collapse

Methods inherited from Base

inherited, #on_new_investigation

Methods included from RSpec::Language

#example?, #example_group?, #example_group_with_body?, #explicit_rspec?, #hook?, #include?, #let?, #rspec?, #shared_group?, #spec_group?, #subject?

Instance Method Details

#context?(node) ⇒ Object



88
89
90
91
92
# File 'lib/rubocop/cop/rspec/shared_context.rb', line 88

def_node_search :context?, <<~PATTERN
  (send nil?
    {#Subjects.all #Helpers.all #Includes.context #Hooks.all} ...
  )
PATTERN

#examples?(node) ⇒ Object



83
84
85
# File 'lib/rubocop/cop/rspec/shared_context.rb', line 83

def_node_search :examples?, <<~PATTERN
  (send nil? {#Includes.examples #Examples.all} ...)
PATTERN

#on_block(node) ⇒ Object

rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/rubocop/cop/rspec/shared_context.rb', line 104

def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
  offending_node(node) do
    add_offense(node.send_node, message: message) do |corrector|
      if can_correct?(node)
        corrector.replace(node.send_node.loc.selector,
                          'shared_examples')
      end
    end
  end

  examples_with_only_context(node) do
    add_offense(node.send_node, message: MSG_CONTEXT) do |corrector|
      corrector.replace(node.send_node.loc.selector, 'shared_context')
    end
  end
end

#shared_context(node) ⇒ Object



95
96
97
# File 'lib/rubocop/cop/rspec/shared_context.rb', line 95

def_node_matcher :shared_context, <<~PATTERN
  (block (send #rspec? #SharedGroups.context ...) ...)
PATTERN

#shared_example(node) ⇒ Object



100
101
102
# File 'lib/rubocop/cop/rspec/shared_context.rb', line 100

def_node_matcher :shared_example, <<~PATTERN
  (block (send #rspec? #SharedGroups.examples ...) ...)
PATTERN