Class: RuboCop::Cop::RSpec::Capybara::FeatureMethods

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
InsideExampleGroup
Defined in:
lib/rubocop/cop/rspec/capybara/feature_methods.rb

Overview

Checks for consistent method usage in feature specs.

By default, the cop disables all Capybara-specific methods that have the same native RSpec method (e.g. are just aliases). Some teams however may prefer using some of the Capybara methods (like ‘feature`) to make it obvious that the test uses Capybara, while still disable the rest of the methods, like `given` (alias for `let`), `background` (alias for `before`), etc. You can configure which of the methods to be enabled by using the EnabledMethods configuration option.

Examples:

# bad
feature 'User logs in' do
  given(:user) { User.new }

  background do
    visit new_session_path
  end

  scenario 'with OAuth' do
    # ...
  end
end

# good
describe 'User logs in' do
  let(:user) { User.new }

  before do
    visit new_session_path
  end

  it 'with OAuth' do
    # ...
  end
end

Constant Summary collapse

MSG =
'Use `%<replacement>s` instead of `%<method>s`.'
MAP =
{
  background: :before,
  scenario:   :it,
  xscenario:  :xit,
  given:      :let,
  given!:     :let!,
  feature:    :describe
}.freeze

Instance Method Summary collapse

Methods inherited from Base

inherited, #on_new_investigation

Methods included from RSpec::Language::NodePattern

#block_or_numblock_pattern, #block_pattern, #numblock_pattern, #send_pattern

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

#capybara_speak(node) ⇒ Object



61
62
63
# File 'lib/rubocop/cop/rspec/capybara/feature_methods.rb', line 61

def_node_matcher :capybara_speak, <<~PATTERN
  {#{MAP.keys.map(&:inspect).join(' ')}}
PATTERN

#feature_method(node) ⇒ Object



66
67
68
69
70
# File 'lib/rubocop/cop/rspec/capybara/feature_methods.rb', line 66

def_node_matcher :feature_method, <<~PATTERN
  (block
    $(send #rspec? $#capybara_speak ...)
  ...)
PATTERN

#message(range) ⇒ Object



84
85
86
87
# File 'lib/rubocop/cop/rspec/capybara/feature_methods.rb', line 84

def message(range)
  name = range.source.to_sym
  format(MSG, method: name, replacement: MAP[name])
end

#on_block(node) ⇒ Object

rubocop:disable InternalAffairs/NumblockHandler



72
73
74
75
76
77
78
79
80
81
82
# File 'lib/rubocop/cop/rspec/capybara/feature_methods.rb', line 72

def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
  return unless inside_example_group?(node)

  feature_method(node) do |send_node, match|
    next if enabled?(match)

    add_offense(send_node.loc.selector) do |corrector|
      corrector.replace(send_node.loc.selector, MAP[match].to_s)
    end
  end
end